Imported Upstream version 3.5.2 00/155900/1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 16 Oct 2017 10:59:49 +0000 (19:59 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 16 Oct 2017 11:00:39 +0000 (20:00 +0900)
Change-Id: I1c5cb913449d614075dfedca59fc712947af0359
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
979 files changed:
Doc/README.txt
Doc/bugs.rst
Doc/c-api/arg.rst
Doc/c-api/code.rst
Doc/c-api/exceptions.rst
Doc/c-api/function.rst
Doc/c-api/gcsupport.rst
Doc/c-api/import.rst
Doc/c-api/init.rst
Doc/c-api/mapping.rst
Doc/c-api/memory.rst
Doc/c-api/method.rst
Doc/c-api/module.rst
Doc/c-api/object.rst
Doc/c-api/sequence.rst
Doc/c-api/set.rst
Doc/c-api/stable.rst
Doc/c-api/typeobj.rst
Doc/c-api/unicode.rst
Doc/c-api/veryhigh.rst
Doc/conf.py
Doc/copyright.rst
Doc/distributing/index.rst
Doc/distutils/apiref.rst
Doc/distutils/configfile.rst
Doc/distutils/index.rst
Doc/extending/building.rst
Doc/extending/extending.rst
Doc/extending/index.rst
Doc/faq/design.rst
Doc/faq/extending.rst
Doc/faq/general.rst
Doc/faq/gui.rst
Doc/faq/library.rst
Doc/faq/programming.rst
Doc/faq/windows.rst
Doc/glossary.rst
Doc/howto/argparse.rst
Doc/howto/cporting.rst
Doc/howto/curses.rst
Doc/howto/descriptor.rst
Doc/howto/functional.rst
Doc/howto/index.rst
Doc/howto/logging-cookbook.rst
Doc/howto/logging.rst
Doc/howto/pyporting.rst
Doc/howto/regex.rst
Doc/howto/sorting.rst
Doc/howto/unicode.rst
Doc/howto/urllib2.rst
Doc/howto/webservers.rst [deleted file]
Doc/install/index.rst
Doc/installing/index.rst
Doc/library/2to3.rst
Doc/library/__main__.rst
Doc/library/_thread.rst
Doc/library/abc.rst
Doc/library/aifc.rst
Doc/library/argparse.rst
Doc/library/array.rst
Doc/library/ast.rst
Doc/library/asynchat.rst
Doc/library/asyncio-eventloop.rst
Doc/library/asyncio-eventloops.rst
Doc/library/asyncio-protocol.rst
Doc/library/asyncio-stream.rst
Doc/library/asyncio-subprocess.rst
Doc/library/asyncio-sync.rst
Doc/library/asyncio-task.rst
Doc/library/asyncio.rst
Doc/library/asyncore.rst
Doc/library/atexit.rst
Doc/library/audioop.rst
Doc/library/base64.rst
Doc/library/binascii.rst
Doc/library/binhex.rst
Doc/library/bisect.rst
Doc/library/builtins.rst
Doc/library/bz2.rst
Doc/library/calendar.rst
Doc/library/cgi.rst
Doc/library/cgitb.rst
Doc/library/chunk.rst
Doc/library/cmath.rst
Doc/library/cmd.rst
Doc/library/code.rst
Doc/library/codecs.rst
Doc/library/codeop.rst
Doc/library/collections.abc.rst
Doc/library/collections.rst
Doc/library/colorsys.rst
Doc/library/compileall.rst
Doc/library/concurrent.futures.rst
Doc/library/configparser.rst
Doc/library/contextlib.rst
Doc/library/copy.rst
Doc/library/copyreg.rst
Doc/library/crypt.rst
Doc/library/crypto.rst
Doc/library/csv.rst
Doc/library/ctypes.rst
Doc/library/curses.ascii.rst
Doc/library/curses.panel.rst
Doc/library/curses.rst
Doc/library/datetime.rst
Doc/library/dbm.rst
Doc/library/decimal.rst
Doc/library/difflib.rst
Doc/library/dis.rst
Doc/library/distutils.rst
Doc/library/doctest.rst
Doc/library/email.charset.rst
Doc/library/email.contentmanager.rst
Doc/library/email.encoders.rst
Doc/library/email.errors.rst
Doc/library/email.generator.rst
Doc/library/email.header.rst
Doc/library/email.headerregistry.rst
Doc/library/email.iterators.rst
Doc/library/email.message.rst
Doc/library/email.mime.rst
Doc/library/email.parser.rst
Doc/library/email.policy.rst
Doc/library/email.rst
Doc/library/email.util.rst
Doc/library/ensurepip.rst
Doc/library/enum.rst
Doc/library/errno.rst
Doc/library/exceptions.rst
Doc/library/faulthandler.rst
Doc/library/fcntl.rst
Doc/library/filecmp.rst
Doc/library/fileinput.rst
Doc/library/fnmatch.rst
Doc/library/formatter.rst
Doc/library/fpectl.rst
Doc/library/fractions.rst
Doc/library/ftplib.rst
Doc/library/functions.rst
Doc/library/functools.rst
Doc/library/gc.rst
Doc/library/getopt.rst
Doc/library/getpass.rst
Doc/library/gettext.rst
Doc/library/glob.rst
Doc/library/grp.rst
Doc/library/hashlib.rst
Doc/library/heapq.rst
Doc/library/hmac.rst
Doc/library/html.entities.rst
Doc/library/html.parser.rst
Doc/library/http.client.rst
Doc/library/http.cookiejar.rst
Doc/library/http.cookies.rst
Doc/library/http.rst
Doc/library/http.server.rst
Doc/library/idle.rst
Doc/library/imaplib.rst
Doc/library/imp.rst
Doc/library/importlib.rst
Doc/library/inspect.rst
Doc/library/io.rst
Doc/library/ipaddress.rst
Doc/library/itertools.rst
Doc/library/json.rst
Doc/library/linecache.rst
Doc/library/locale.rst
Doc/library/logging.config.rst
Doc/library/logging.handlers.rst
Doc/library/logging.rst
Doc/library/lzma.rst
Doc/library/macpath.rst
Doc/library/mailbox.rst
Doc/library/mailcap.rst
Doc/library/marshal.rst
Doc/library/math.rst
Doc/library/mimetypes.rst
Doc/library/mmap.rst
Doc/library/modulefinder.rst
Doc/library/msilib.rst
Doc/library/msvcrt.rst
Doc/library/multiprocessing.rst
Doc/library/netrc.rst
Doc/library/nis.rst
Doc/library/nntplib.rst
Doc/library/numbers.rst
Doc/library/operator.rst
Doc/library/optparse.rst
Doc/library/os.path.rst
Doc/library/os.rst
Doc/library/ossaudiodev.rst
Doc/library/othergui.rst
Doc/library/parser.rst
Doc/library/pathlib.rst
Doc/library/pdb.rst
Doc/library/pickle.rst
Doc/library/pipes.rst
Doc/library/pkgutil.rst
Doc/library/platform.rst
Doc/library/plistlib.rst
Doc/library/poplib.rst
Doc/library/posix.rst
Doc/library/pprint.rst
Doc/library/pty.rst
Doc/library/pwd.rst
Doc/library/py_compile.rst
Doc/library/pyclbr.rst
Doc/library/pydoc.rst
Doc/library/pyexpat.rst
Doc/library/quopri.rst
Doc/library/random.rst
Doc/library/re.rst
Doc/library/readline.rst
Doc/library/reprlib.rst
Doc/library/resource.rst
Doc/library/rlcompleter.rst
Doc/library/runpy.rst
Doc/library/sched.rst
Doc/library/select.rst
Doc/library/selectors.rst
Doc/library/shelve.rst
Doc/library/shlex.rst
Doc/library/shutil.rst
Doc/library/signal.rst
Doc/library/site.rst
Doc/library/smtplib.rst
Doc/library/sndhdr.rst
Doc/library/socket.rst
Doc/library/socketserver.rst
Doc/library/spwd.rst
Doc/library/sqlite3.rst
Doc/library/ssl.rst
Doc/library/stat.rst
Doc/library/statistics.rst
Doc/library/stdtypes.rst
Doc/library/string.rst
Doc/library/stringprep.rst
Doc/library/struct.rst
Doc/library/subprocess.rst
Doc/library/sunau.rst
Doc/library/symbol.rst
Doc/library/sys.rst
Doc/library/sysconfig.rst
Doc/library/syslog.rst
Doc/library/tabnanny.rst
Doc/library/tarfile.rst
Doc/library/telnetlib.rst
Doc/library/tempfile.rst
Doc/library/termios.rst
Doc/library/test.rst
Doc/library/textwrap.rst
Doc/library/threading.rst
Doc/library/time.rst
Doc/library/timeit.rst
Doc/library/tkinter.rst
Doc/library/tkinter.scrolledtext.rst
Doc/library/tkinter.tix.rst
Doc/library/tkinter.ttk.rst
Doc/library/token.rst
Doc/library/tokenize.rst
Doc/library/traceback.rst
Doc/library/tracemalloc.rst
Doc/library/tty.rst
Doc/library/turtle.rst
Doc/library/types.rst
Doc/library/typing.rst
Doc/library/unicodedata.rst
Doc/library/unittest.mock-examples.rst
Doc/library/unittest.mock.rst
Doc/library/unittest.rst
Doc/library/urllib.error.rst
Doc/library/urllib.parse.rst
Doc/library/urllib.request.rst
Doc/library/urllib.robotparser.rst
Doc/library/urllib.rst
Doc/library/uu.rst
Doc/library/uuid.rst
Doc/library/venv.rst
Doc/library/warnings.rst
Doc/library/wave.rst
Doc/library/weakref.rst
Doc/library/webbrowser.rst
Doc/library/winreg.rst
Doc/library/winsound.rst
Doc/library/wsgiref.rst
Doc/library/xdrlib.rst
Doc/library/xml.dom.minidom.rst
Doc/library/xml.dom.pulldom.rst
Doc/library/xml.dom.rst
Doc/library/xml.etree.elementtree.rst
Doc/library/xml.rst
Doc/library/xml.sax.handler.rst
Doc/library/xml.sax.reader.rst
Doc/library/xml.sax.rst
Doc/library/xml.sax.utils.rst
Doc/library/xmlrpc.client.rst
Doc/library/xmlrpc.server.rst
Doc/library/zipapp.rst
Doc/library/zipfile.rst
Doc/library/zipimport.rst
Doc/library/zlib.rst
Doc/license.rst
Doc/reference/compound_stmts.rst
Doc/reference/datamodel.rst
Doc/reference/expressions.rst
Doc/reference/import.rst
Doc/reference/introduction.rst
Doc/reference/lexical_analysis.rst
Doc/reference/simple_stmts.rst
Doc/tools/extensions/pyspecific.py
Doc/tools/pydoctheme/static/pydoctheme.css
Doc/tools/rstlint.py
Doc/tools/static/copybutton.js
Doc/tools/susp-ignored.csv
Doc/tools/templates/indexcontent.html
Doc/tools/templates/indexsidebar.html
Doc/tools/templates/layout.html
Doc/tutorial/appendix.rst
Doc/tutorial/classes.rst
Doc/tutorial/controlflow.rst
Doc/tutorial/datastructures.rst
Doc/tutorial/errors.rst
Doc/tutorial/floatingpoint.rst
Doc/tutorial/inputoutput.rst
Doc/tutorial/interactive.rst
Doc/tutorial/introduction.rst
Doc/tutorial/modules.rst
Doc/tutorial/stdlib.rst
Doc/tutorial/stdlib2.rst
Doc/tutorial/whatnow.rst
Doc/using/cmdline.rst
Doc/using/mac.rst
Doc/using/unix.rst
Doc/using/venv-create.inc
Doc/using/windows.rst
Doc/whatsnew/2.0.rst
Doc/whatsnew/2.1.rst
Doc/whatsnew/2.2.rst
Doc/whatsnew/2.3.rst
Doc/whatsnew/2.4.rst
Doc/whatsnew/2.5.rst
Doc/whatsnew/2.6.rst
Doc/whatsnew/2.7.rst
Doc/whatsnew/3.0.rst
Doc/whatsnew/3.2.rst
Doc/whatsnew/3.3.rst
Doc/whatsnew/3.4.rst
Doc/whatsnew/3.5.rst
Include/abstract.h
Include/bytesobject.h
Include/code.h
Include/dictobject.h
Include/frameobject.h
Include/genobject.h
Include/listobject.h
Include/object.h
Include/patchlevel.h
Include/pyatomic.h
Include/pymacconfig.h
Include/pystate.h
Include/pythonrun.h
Include/traceback.h
Include/unicodeobject.h
LICENSE
Lib/_collections_abc.py
Lib/_compat_pickle.py
Lib/_osx_support.py
Lib/_pydecimal.py
Lib/_pyio.py
Lib/_strptime.py
Lib/asyncio/base_events.py
Lib/asyncio/base_subprocess.py
Lib/asyncio/compat.py
Lib/asyncio/coroutines.py
Lib/asyncio/events.py
Lib/asyncio/futures.py
Lib/asyncio/locks.py
Lib/asyncio/proactor_events.py
Lib/asyncio/queues.py
Lib/asyncio/selector_events.py
Lib/asyncio/sslproto.py
Lib/asyncio/streams.py
Lib/asyncio/subprocess.py
Lib/asyncio/tasks.py
Lib/asyncio/test_utils.py
Lib/asyncio/unix_events.py
Lib/asyncio/windows_events.py
Lib/base64.py
Lib/cgi.py
Lib/collections/__init__.py
Lib/compileall.py
Lib/copy.py
Lib/ctypes/__init__.py
Lib/ctypes/macholib/README.ctypes
Lib/ctypes/test/test_arrays.py
Lib/ctypes/test/test_pointers.py
Lib/ctypes/test/test_values.py
Lib/ctypes/util.py
Lib/datetime.py
Lib/dis.py
Lib/distutils/_msvccompiler.py
Lib/distutils/ccompiler.py
Lib/distutils/command/build_ext.py
Lib/distutils/command/register.py
Lib/distutils/command/upload.py
Lib/distutils/command/wininst-14.0-amd64.exe
Lib/distutils/command/wininst-14.0.exe
Lib/distutils/config.py
Lib/distutils/msvc9compiler.py
Lib/distutils/tests/test_build_ext.py
Lib/distutils/tests/test_register.py
Lib/distutils/tests/test_unixccompiler.py
Lib/distutils/tests/test_upload.py
Lib/distutils/unixccompiler.py
Lib/doctest.py
Lib/email/_header_value_parser.py
Lib/email/headerregistry.py
Lib/email/message.py
Lib/email/parser.py
Lib/email/utils.py
Lib/encodings/hp_roman8.py
Lib/encodings/utf_16.py
Lib/encodings/utf_32.py
Lib/ensurepip/__init__.py
Lib/ensurepip/_bundled/pip-7.1.2-py2.py3-none-any.whl [deleted file]
Lib/ensurepip/_bundled/pip-8.1.1-py2.py3-none-any.whl [new file with mode: 0644]
Lib/ensurepip/_bundled/setuptools-20.10.1-py2.py3-none-any.whl [moved from Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl with 60% similarity]
Lib/enum.py
Lib/fileinput.py
Lib/gzip.py
Lib/heapq.py
Lib/html/parser.py
Lib/http/client.py
Lib/http/cookiejar.py
Lib/http/cookies.py
Lib/http/server.py
Lib/idlelib/AutoComplete.py
Lib/idlelib/CREDITS.txt
Lib/idlelib/ChangeLog
Lib/idlelib/ColorDelegator.py
Lib/idlelib/Debugger.py
Lib/idlelib/Delegator.py
Lib/idlelib/EditorWindow.py
Lib/idlelib/IOBinding.py
Lib/idlelib/MultiCall.py
Lib/idlelib/NEWS.txt
Lib/idlelib/Percolator.py
Lib/idlelib/PyShell.py
Lib/idlelib/README.txt
Lib/idlelib/ReplaceDialog.py
Lib/idlelib/SearchDialog.py
Lib/idlelib/UndoDelegator.py
Lib/idlelib/WidgetRedirector.py
Lib/idlelib/aboutDialog.py
Lib/idlelib/configDialog.py
Lib/idlelib/configHandler.py
Lib/idlelib/configHelpSourceEdit.py
Lib/idlelib/help.html
Lib/idlelib/help.py
Lib/idlelib/idle_test/README.txt
Lib/idlelib/idle_test/__init__.py
Lib/idlelib/idle_test/htest.py
Lib/idlelib/idle_test/mock_tk.py
Lib/idlelib/idle_test/test_autocomplete.py
Lib/idlelib/idle_test/test_autoexpand.py
Lib/idlelib/idle_test/test_config_help.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_configdialog.py
Lib/idlelib/idle_test/test_delegator.py
Lib/idlelib/idle_test/test_editmenu.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_formatparagraph.py
Lib/idlelib/idle_test/test_parenmatch.py
Lib/idlelib/idle_test/test_percolator.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_replacedialog.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_searchdialog.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_textview.py
Lib/idlelib/idle_test/test_undodelegator.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_warning.py
Lib/idlelib/idle_test/test_widgetredir.py
Lib/idlelib/rpc.py
Lib/importlib/_bootstrap.py
Lib/importlib/_bootstrap_external.py
Lib/importlib/abc.py
Lib/importlib/util.py
Lib/inspect.py
Lib/ipaddress.py
Lib/json/encoder.py
Lib/lib2to3/btm_utils.py
Lib/lib2to3/fixer_base.py
Lib/lib2to3/fixes/fix_metaclass.py
Lib/lib2to3/patcomp.py
Lib/lib2to3/pgen2/tokenize.py
Lib/lib2to3/refactor.py
Lib/lib2to3/tests/pytree_idempotency.py
Lib/locale.py
Lib/logging/__init__.py
Lib/logging/handlers.py
Lib/lzma.py
Lib/mailbox.py
Lib/mimetypes.py
Lib/modulefinder.py
Lib/msilib/__init__.py
Lib/msilib/schema.py
Lib/multiprocessing/connection.py
Lib/multiprocessing/forkserver.py
Lib/multiprocessing/managers.py
Lib/multiprocessing/process.py
Lib/multiprocessing/spawn.py
Lib/multiprocessing/util.py
Lib/nntplib.py
Lib/ntpath.py
Lib/optparse.py
Lib/os.py
Lib/pathlib.py
Lib/pdb.py
Lib/pickle.py
Lib/pickletools.py
Lib/pkgutil.py
Lib/platform.py
Lib/plistlib.py
Lib/posixpath.py
Lib/pprint.py
Lib/pyclbr.py
Lib/pydoc.py
Lib/pydoc_data/topics.py
Lib/random.py
Lib/reprlib.py
Lib/rlcompleter.py
Lib/runpy.py
Lib/selectors.py
Lib/shutil.py
Lib/site.py
Lib/smtplib.py
Lib/socket.py
Lib/socketserver.py
Lib/sqlite3/test/regression.py
Lib/sqlite3/test/userfunctions.py
Lib/sre_parse.py
Lib/ssl.py
Lib/statistics.py
Lib/string.py
Lib/subprocess.py
Lib/sysconfig.py
Lib/tarfile.py
Lib/tempfile.py
Lib/test/_test_multiprocessing.py
Lib/test/buffer_tests.py [deleted file]
Lib/test/bytecode_helper.py
Lib/test/capath/0e4015b9.0 [new file with mode: 0644]
Lib/test/capath/ce7b8643.0 [new file with mode: 0644]
Lib/test/cfgparser.2
Lib/test/datetimetester.py
Lib/test/eintrdata/eintr_tester.py
Lib/test/https_svn_python_org_root.pem [deleted file]
Lib/test/list_tests.py
Lib/test/lock_tests.py
Lib/test/pickletester.py
Lib/test/regrtest.py
Lib/test/selfsigned_pythontestdotnet.pem
Lib/test/seq_tests.py
Lib/test/string_tests.py
Lib/test/support/__init__.py
Lib/test/support/script_helper.py
Lib/test/test__locale.py
Lib/test/test_argparse.py
Lib/test/test_array.py
Lib/test/test_asyncio/test_base_events.py
Lib/test/test_asyncio/test_events.py
Lib/test/test_asyncio/test_futures.py
Lib/test/test_asyncio/test_locks.py
Lib/test/test_asyncio/test_pep492.py
Lib/test/test_asyncio/test_proactor_events.py
Lib/test/test_asyncio/test_selector_events.py
Lib/test/test_asyncio/test_sslproto.py
Lib/test/test_asyncio/test_streams.py
Lib/test/test_asyncio/test_subprocess.py
Lib/test/test_asyncio/test_tasks.py
Lib/test/test_base64.py
Lib/test/test_bigmem.py
Lib/test/test_binop.py
Lib/test/test_bool.py
Lib/test/test_builtin.py
Lib/test/test_bytes.py
Lib/test/test_capi.py
Lib/test/test_cmd_line.py
Lib/test/test_cmd_line_script.py
Lib/test/test_codecs.py
Lib/test/test_collections.py
Lib/test/test_compile.py
Lib/test/test_compileall.py
Lib/test/test_concurrent_futures.py
Lib/test/test_copy.py
Lib/test/test_coroutines.py
Lib/test/test_crypt.py
Lib/test/test_csv.py
Lib/test/test_curses.py
Lib/test/test_decimal.py
Lib/test/test_deque.py
Lib/test/test_descr.py
Lib/test/test_dict.py
Lib/test/test_dictviews.py
Lib/test/test_dis.py
Lib/test/test_doctest.py
Lib/test/test_dummy_thread.py
Lib/test/test_email/test__header_value_parser.py
Lib/test/test_email/test_asian_codecs.py
Lib/test/test_email/test_contentmanager.py
Lib/test/test_email/test_policy.py
Lib/test/test_email/torture_test.py
Lib/test/test_enum.py
Lib/test/test_exceptions.py
Lib/test/test_extcall.py
Lib/test/test_faulthandler.py
Lib/test/test_fileinput.py
Lib/test/test_float.py
Lib/test/test_fork1.py
Lib/test/test_functools.py
Lib/test/test_gdb.py
Lib/test/test_generators.py
Lib/test/test_genericpath.py
Lib/test/test_getargs2.py
Lib/test/test_grammar.py
Lib/test/test_hashlib.py
Lib/test/test_http_cookiejar.py
Lib/test/test_http_cookies.py
Lib/test/test_httplib.py
Lib/test/test_httpservers.py
Lib/test/test_import/__init__.py
Lib/test/test_importlib/import_/test_relative_imports.py
Lib/test/test_importlib/source/test_source_encoding.py
Lib/test/test_importlib/test_lazy.py
Lib/test/test_inspect.py
Lib/test/test_int.py
Lib/test/test_io.py
Lib/test/test_ipaddress.py
Lib/test/test_iter.py
Lib/test/test_itertools.py
Lib/test/test_linecache.py
Lib/test/test_list.py
Lib/test/test_logging.py
Lib/test/test_long.py
Lib/test/test_lzma.py
Lib/test/test_memoryio.py
Lib/test/test_memoryview.py
Lib/test/test_minidom.py
Lib/test/test_mmap.py
Lib/test/test_module.py
Lib/test/test_modulefinder.py
Lib/test/test_multibytecodec.py
Lib/test/test_nntplib.py
Lib/test/test_operator.py
Lib/test/test_ordered_dict.py [new file with mode: 0644]
Lib/test/test_os.py
Lib/test/test_pathlib.py
Lib/test/test_pdb.py
Lib/test/test_pep292.py [deleted file]
Lib/test/test_pep3151.py
Lib/test/test_pickle.py
Lib/test/test_pkgutil.py
Lib/test/test_platform.py
Lib/test/test_plistlib.py
Lib/test/test_posixpath.py
Lib/test/test_property.py
Lib/test/test_pyclbr.py
Lib/test/test_pydoc.py
Lib/test/test_pyexpat.py
Lib/test/test_random.py
Lib/test/test_reprlib.py
Lib/test/test_rlcompleter.py
Lib/test/test_runpy.py
Lib/test/test_set.py
Lib/test/test_shutil.py
Lib/test/test_site.py
Lib/test/test_slice.py
Lib/test/test_socket.py
Lib/test/test_socketserver.py
Lib/test/test_source_encoding.py
Lib/test/test_ssl.py
Lib/test/test_statistics.py
Lib/test/test_string.py
Lib/test/test_strptime.py
Lib/test/test_subprocess.py
Lib/test/test_super.py
Lib/test/test_syntax.py
Lib/test/test_sys.py
Lib/test/test_sys_setprofile.py
Lib/test/test_sys_settrace.py
Lib/test/test_sysconfig.py
Lib/test/test_tarfile.py
Lib/test/test_tcl.py
Lib/test/test_telnetlib.py
Lib/test/test_tempfile.py
Lib/test/test_threading.py
Lib/test/test_threading_local.py
Lib/test/test_tools/test_gprof2html.py
Lib/test/test_tools/test_unparse.py
Lib/test/test_tracemalloc.py
Lib/test/test_tuple.py
Lib/test/test_turtle.py [new file with mode: 0644]
Lib/test/test_typing.py
Lib/test/test_unicode.py
Lib/test/test_urllib.py
Lib/test/test_urllib2.py
Lib/test/test_urllib2_localnet.py
Lib/test/test_urllibnet.py
Lib/test/test_urlparse.py
Lib/test/test_userdict.py
Lib/test/test_userlist.py
Lib/test/test_uuid.py
Lib/test/test_venv.py
Lib/test/test_wait4.py
Lib/test/test_warnings/__init__.py
Lib/test/test_warnings/data/import_warning.py
Lib/test/test_weakref.py
Lib/test/test_winsound.py
Lib/test/test_wsgiref.py
Lib/test/test_xml_dom_minicompat.py
Lib/test/test_xml_etree.py
Lib/test/test_xml_etree_c.py
Lib/test/test_xmlrpc.py
Lib/test/test_zipapp.py
Lib/test/test_zipfile.py
Lib/test/test_zipfile64.py
Lib/test/test_zipimport.py
Lib/test/test_zlib.py
Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt
Lib/test/wrongcert.pem [new file with mode: 0644]
Lib/threading.py
Lib/tkinter/__init__.py
Lib/tkinter/dnd.py
Lib/tkinter/test/test_tkinter/test_geometry_managers.py
Lib/tkinter/test/test_tkinter/test_widgets.py
Lib/tkinter/test/test_ttk/test_functions.py
Lib/tkinter/test/test_ttk/test_widgets.py
Lib/tkinter/test/widget_tests.py
Lib/tkinter/tix.py
Lib/tkinter/ttk.py
Lib/tokenize.py
Lib/traceback.py
Lib/turtledemo/__main__.py
Lib/typing.py
Lib/unittest/__init__.py
Lib/unittest/case.py
Lib/unittest/loader.py
Lib/unittest/mock.py
Lib/unittest/result.py
Lib/unittest/suite.py
Lib/unittest/test/test_case.py
Lib/unittest/test/test_discovery.py
Lib/unittest/test/test_loader.py
Lib/unittest/test/test_runner.py
Lib/unittest/test/testmock/testmock.py
Lib/unittest/test/testmock/testpatch.py
Lib/urllib/parse.py
Lib/urllib/request.py
Lib/urllib/robotparser.py
Lib/uuid.py
Lib/venv/__init__.py
Lib/venv/scripts/posix/activate.fish
Lib/warnings.py
Lib/wsgiref/handlers.py
Lib/wsgiref/headers.py
Lib/wsgiref/simple_server.py
Lib/xml/dom/minicompat.py
Lib/xml/etree/ElementTree.py
Lib/xmlrpc/client.py
Lib/xmlrpc/server.py
Lib/zipapp.py
Lib/zipfile.py
Mac/BuildScript/build-installer.py
Mac/BuildScript/openssl_sdk_makedepend.patch
Mac/BuildScript/resources/License.rtf
Mac/BuildScript/scripts/postflight.patch-profile
Mac/IDLE/IDLE.app/Contents/Info.plist
Mac/PythonLauncher/Info.plist.in
Mac/README
Mac/Resources/app/Info.plist.in
Mac/Resources/framework/Info.plist.in
Makefile.pre.in
Misc/ACKS
Misc/HISTORY
Misc/NEWS
Misc/python.man
Modules/_bz2module.c
Modules/_collectionsmodule.c
Modules/_csv.c
Modules/_ctypes/_ctypes.c
Modules/_ctypes/cfield.c
Modules/_ctypes/ctypes_dlfcn.h
Modules/_ctypes/libffi/m4/libtool.m4
Modules/_curses_panel.c
Modules/_datetimemodule.c
Modules/_decimal/_decimal.c
Modules/_elementtree.c
Modules/_functoolsmodule.c
Modules/_heapqmodule.c
Modules/_io/bufferedio.c
Modules/_io/bytesio.c
Modules/_io/clinic/bytesio.c.h
Modules/_io/clinic/fileio.c.h
Modules/_io/clinic/iobase.c.h
Modules/_io/fileio.c
Modules/_io/iobase.c
Modules/_io/stringio.c
Modules/_io/textio.c
Modules/_json.c
Modules/_lzmamodule.c
Modules/_operator.c
Modules/_pickle.c
Modules/_posixsubprocess.c
Modules/_sqlite/connection.c
Modules/_sqlite/cursor.c
Modules/_sre.c
Modules/_ssl.c
Modules/_struct.c
Modules/_testcapimodule.c
Modules/_threadmodule.c
Modules/_tkinter.c
Modules/_tracemalloc.c
Modules/arraymodule.c
Modules/audioop.c
Modules/cjkcodecs/cjkcodecs.h
Modules/cjkcodecs/multibytecodec.c
Modules/clinic/_pickle.c.h
Modules/clinic/fcntlmodule.c.h
Modules/clinic/zlibmodule.c.h
Modules/cmathmodule.c
Modules/expat/expat.h
Modules/expat/xmlparse.c
Modules/expat/xmltok.c
Modules/faulthandler.c
Modules/fcntlmodule.c
Modules/getaddrinfo.c
Modules/getpath.c
Modules/itertoolsmodule.c
Modules/ld_so_aix.in
Modules/main.c
Modules/mathmodule.c
Modules/mmapmodule.c
Modules/overlapped.c
Modules/parsermodule.c
Modules/posixmodule.c
Modules/readline.c
Modules/selectmodule.c
Modules/sha256module.c
Modules/sha512module.c
Modules/signalmodule.c
Modules/socketmodule.c
Modules/zipimport.c
Modules/zlibmodule.c
Objects/bytearrayobject.c
Objects/bytesobject.c
Objects/cellobject.c
Objects/codeobject.c
Objects/descrobject.c
Objects/dictobject.c
Objects/exceptions.c
Objects/floatobject.c
Objects/frameobject.c
Objects/funcobject.c
Objects/genobject.c
Objects/iterobject.c
Objects/listobject.c
Objects/longobject.c
Objects/moduleobject.c
Objects/object.c
Objects/odictobject.c
Objects/rangeobject.c
Objects/setobject.c
Objects/sliceobject.c
Objects/stringlib/unicode_format.h
Objects/tupleobject.c
Objects/typeobject.c
Objects/unicodeobject.c
Objects/weakrefobject.c
PC/bdist_wininst/bdist_wininst.vcxproj
PC/bdist_wininst/install.c
PC/clinic/winreg.c.h
PC/getpathp.c
PC/icons/baselogo.svg [deleted file]
PC/icons/source.xar [deleted file]
PC/launcher.c
PC/pyconfig.h
PC/python_ver_rc.h
PC/sqlite3.rc [new file with mode: 0644]
PC/validate_ucrtbase.py [new file with mode: 0644]
PC/winreg.c
PCbuild/_bz2.vcxproj
PCbuild/_ctypes.vcxproj
PCbuild/_ctypes_test.vcxproj
PCbuild/_decimal.vcxproj
PCbuild/_elementtree.vcxproj
PCbuild/_hashlib.vcxproj
PCbuild/_lzma.vcxproj
PCbuild/_msi.vcxproj
PCbuild/_multiprocessing.vcxproj
PCbuild/_overlapped.vcxproj
PCbuild/_socket.vcxproj
PCbuild/_sqlite3.vcxproj
PCbuild/_ssl.vcxproj
PCbuild/_testbuffer.vcxproj
PCbuild/_testcapi.vcxproj
PCbuild/_testembed.vcxproj
PCbuild/_testimportmultiple.vcxproj
PCbuild/_testmultiphase.vcxproj
PCbuild/_tkinter.vcxproj
PCbuild/build.bat
PCbuild/build_pgo.bat
PCbuild/get_externals.bat
PCbuild/openssl.props
PCbuild/prepare_ssl.bat
PCbuild/prepare_ssl.py
PCbuild/pyexpat.vcxproj
PCbuild/pylauncher.vcxproj
PCbuild/pyproject.props
PCbuild/python.props
PCbuild/python.vcxproj
PCbuild/python3dll.vcxproj
PCbuild/pythoncore.vcxproj
PCbuild/pythonw.vcxproj
PCbuild/pywlauncher.vcxproj
PCbuild/readme.txt
PCbuild/select.vcxproj
PCbuild/sqlite3.vcxproj
PCbuild/tcltk.props
PCbuild/unicodedata.vcxproj
PCbuild/winsound.vcxproj
Parser/tokenizer.c
Programs/_testembed.c
Programs/python.c
Python/_warnings.c
Python/bltinmodule.c
Python/ceval.c
Python/ceval_gil.h
Python/clinic/bltinmodule.c.h
Python/codecs.c
Python/compile.c
Python/errors.c
Python/fileutils.c
Python/formatter_unicode.c
Python/getargs.c
Python/getcopyright.c
Python/import.c
Python/importlib.h
Python/importlib_external.h
Python/marshal.c
Python/modsupport.c
Python/peephole.c
Python/pylifecycle.c
Python/pystate.c
Python/pythonrun.c
Python/random.c
Python/symtable.c
Python/sysmodule.c
Python/thread_nt.h
README
Tools/clinic/clinic.py
Tools/clinic/clinic_test.py
Tools/freeze/makemakefile.py
Tools/gdb/libpython.py
Tools/msi/buildrelease.bat
Tools/msi/bundle/Default.thm
Tools/msi/bundle/Default.wxl
Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp
Tools/msi/bundle/bundle.wxs
Tools/msi/bundle/packagegroups/launcher.wxs
Tools/msi/common.wxs
Tools/msi/launcher/launcher.wixproj
Tools/msi/launcher/launcher.wxs
Tools/msi/launcher/launcher_en-US.wxl
Tools/msi/make_zip.py
Tools/msi/msi.props
Tools/msi/msi.targets
Tools/parser/unparse.py
Tools/scripts/findnocoding.py
aclocal.m4
configure
configure.ac
pyconfig.h.in
setup.py

index 580d102..4f8e9f8 100644 (file)
@@ -119,27 +119,3 @@ and we will process your request as soon as possible.
 
 If you want to help the Documentation Team, you are always welcome.  Just send
 a mail to docs@python.org.
-
-
-Copyright notice
-================
-
-The Python source is copyrighted, but you can freely use and copy it
-as long as you don't change or remove the copyright notice:
-
-----------------------------------------------------------------------
-Copyright (c) 2000-2015 Python Software Foundation.
-All rights reserved.
-
-Copyright (c) 2000 BeOpen.com.
-All rights reserved.
-
-Copyright (c) 1995-2000 Corporation for National Research Initiatives.
-All rights reserved.
-
-Copyright (c) 1991-1995 Stichting Mathematisch Centrum.
-All rights reserved.
-
-See the file "license.rst" for information on usage and redistribution
-of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-----------------------------------------------------------------------
index f01ae0e..1b0a5a9 100644 (file)
@@ -1,13 +1,16 @@
 .. _reporting-bugs:
 
-**************
-Reporting Bugs
-**************
+*****************
+Dealing with Bugs
+*****************
 
 Python is a mature programming language which has established a reputation for
 stability.  In order to maintain this reputation, the developers would like to
 know of any deficiencies you find in Python.
 
+It can be sometimes faster to fix bugs yourself and contribute patches to
+Python as it streamlines the process and involves less people. Learn how to
+:ref:`contribute <contributing-to-python>`.
 
 Documentation bugs
 ==================
@@ -16,7 +19,8 @@ If you find a bug in this documentation or would like to propose an improvement,
 please submit a bug report on the :ref:`tracker <using-the-tracker>`.  If you
 have a suggestion how to fix it, include that as well.
 
-If you're short on time, you can also email your bug report to docs@python.org.
+If you're short on time, you can also email documentation bug reports to
+docs@python.org (behavioral bugs can be sent to python-list@python.org).
 'docs@' is a mailing list run by volunteers; your request will be noticed,
 though it may take a while to be processed.
 
@@ -72,6 +76,7 @@ taken on the bug.
       Information about writing a good bug report.  Some of this is specific to the
       Mozilla project, but describes general good practices.
 
+.. _contributing-to-python:
 
 Getting started contributing to Python yourself
 ===============================================
index ed62dea..983d113 100644 (file)
@@ -30,7 +30,7 @@ variable(s) whose address should be passed.
 Strings and buffers
 -------------------
 
-These formats allow to access an object as a contiguous chunk of memory.
+These formats allow accessing an object as a contiguous chunk of memory.
 You don't have to provide raw storage for the returned unicode or bytes
 area.  Also, you won't have to release any memory yourself, except with the
 ``es``, ``es#``, ``et`` and ``et#`` formats.
@@ -206,7 +206,8 @@ Unless otherwise stated, buffers are not NUL-terminated.
    :c:func:`PyArg_ParseTuple` will use this location as the buffer and interpret the
    initial value of *\*buffer_length* as the buffer size.  It will then copy the
    encoded data into the buffer and NUL-terminate it.  If the buffer is not large
-   enough, a :exc:`ValueError` will be set.
+   enough, a :exc:`TypeError` will be set.
+   Note: starting from Python 3.6 a :exc:`ValueError` will be set.
 
    In both cases, *\*buffer_length* is set to the length of the encoded data
    without the trailing NUL byte.
@@ -322,7 +323,7 @@ Other objects
       ``Py_CLEANUP_SUPPORTED`` was added.
 
 ``p`` (:class:`bool`) [int]
-   Tests the value passed in for truth (a boolean **p**\redicate) and converts
+   Tests the value passed in for truth (a boolean **p**\ redicate) and converts
    the result to its equivalent C true/false integer value.
    Sets the int to 1 if the expression was true and 0 if it was false.
    This accepts any valid Python value.  See :ref:`truth` for more
index 9c93563..10d89f2 100644 (file)
@@ -2,15 +2,13 @@
 
 .. _codeobjects:
 
+.. index:: object; code, code object
+
 Code Objects
 ------------
 
 .. sectionauthor:: Jeffrey Yasskin <jyasskin@gmail.com>
 
-
-.. index::
-   object: code
-
 Code objects are a low-level detail of the CPython implementation.
 Each one represents a chunk of executable code that hasn't yet been
 bound into a function.
index 3fd69ba..19cbb3b 100644 (file)
@@ -74,8 +74,8 @@ Printing and clearing
    :meth:`__del__` method.
 
    The function is called with a single argument *obj* that identifies the context
-   in which the unraisable exception occurred. The repr of *obj* will be printed in
-   the warning message.
+   in which the unraisable exception occurred. If possible,
+   the repr of *obj* will be printed in the warning message.
 
 
 Raising exceptions
@@ -285,7 +285,7 @@ an error value).
 .. c:function:: int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)
 
    Issue a warning message.  The *category* argument is a warning category (see
-   below) or *NULL*; the *message* argument is an UTF-8 encoded string.  *stack_level* is a
+   below) or *NULL*; the *message* argument is a UTF-8 encoded string.  *stack_level* is a
    positive number giving a number of stack frames; the warning will be issued from
    the  currently executing line of code in that stack frame.  A *stack_level* of 1
    is the function calling :c:func:`PyErr_WarnEx`, 2 is  the function above that,
@@ -609,7 +609,7 @@ The following functions are used to create and modify Unicode exceptions from C.
 .. c:function:: PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
 
    Create a :class:`UnicodeTranslateError` object with the attributes *object*,
-   *length*, *start*, *end* and *reason*. *reason* is an UTF-8 encoded string.
+   *length*, *start*, *end* and *reason*. *reason* is a UTF-8 encoded string.
 
 .. c:function:: PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)
                 PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)
index ad98322..17279c7 100644 (file)
@@ -34,13 +34,14 @@ There are a few functions specific to Python functions.
    Return a new function object associated with the code object *code*. *globals*
    must be a dictionary with the global variables accessible to the function.
 
-   The function's docstring, name and *__module__* are retrieved from the code
-   object, the argument defaults and closure are set to *NULL*.
+   The function's docstring and name are retrieved from the code object. *__module__*
+   is retrieved from *globals*. The argument defaults, annotations and closure are
+   set to *NULL*. *__qualname__* is set to the same value as the function's name.
 
 
 .. c:function:: PyObject* PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
 
-   As :c:func:`PyFunction_New`, but also allows to set the function object's
+   As :c:func:`PyFunction_New`, but also allows setting the function object's
    ``__qualname__`` attribute.  *qualname* should be a unicode object or NULL;
    if NULL, the ``__qualname__`` attribute is set to the same value as its
    ``__name__`` attribute.
index 9f6ad85..f5e0d7e 100644 (file)
@@ -126,9 +126,10 @@ must name its arguments exactly *visit* and *arg*:
 
 .. c:function:: void Py_VISIT(PyObject *o)
 
-   Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns
-   a non-zero value, then return it.  Using this macro, :c:member:`~PyTypeObject.tp_traverse`
-   handlers look like::
+   If *o* is not *NULL*, call the *visit* callback, with arguments *o*
+   and *arg*.  If *visit* returns a non-zero value, then return it.
+   Using this macro, :c:member:`~PyTypeObject.tp_traverse` handlers
+   look like::
 
       static int
       my_traverse(Noddy *self, visitproc visit, void *arg)
index bf1b495..2936f4f 100644 (file)
@@ -72,7 +72,7 @@ Importing Modules
 
 .. c:function:: PyObject* PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)
 
-   Similar to :c:func:`PyImport_ImportModuleLevelObject`, but the name is an
+   Similar to :c:func:`PyImport_ImportModuleLevelObject`, but the name is a
    UTF-8 encoded string instead of a Unicode object.
 
    .. versionchanged:: 3.3
@@ -236,11 +236,6 @@ Importing Modules
    For internal use only.
 
 
-.. c:function:: PyObject* _PyImport_FixupExtension(char *, char *)
-
-   For internal use only.
-
-
 .. c:function:: int PyImport_ImportFrozenModuleObject(PyObject *name)
 
    Load a frozen module named *name*.  Return ``1`` for success, ``0`` if the
@@ -277,7 +272,7 @@ Importing Modules
       };
 
 
-.. c:var:: struct _frozen* PyImport_FrozenModules
+.. c:var:: const struct _frozen* PyImport_FrozenModules
 
    This pointer is initialized to point to an array of :c:type:`struct _frozen`
    records, terminated by one whose members are all *NULL* or zero.  When a frozen
index 81823bf..639819c 100644 (file)
@@ -357,7 +357,7 @@ Process-wide parameters
       It is recommended that applications embedding the Python interpreter
       for purposes other than executing a single script pass 0 as *updatepath*,
       and update :data:`sys.path` themselves if desired.
-      See `CVE-2008-5983 <http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983>`_.
+      See `CVE-2008-5983 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983>`_.
 
       On versions before 3.1.3, you can achieve the same effect by manually
       popping the first :data:`sys.path` element after having called
index e341047..fe601b6 100644 (file)
@@ -50,21 +50,21 @@ Mapping Protocol
 
 .. c:function:: PyObject* PyMapping_Keys(PyObject *o)
 
-   On success, return a list of the keys in object *o*.  On failure, return *NULL*.
-   This is equivalent to the Python expression ``list(o.keys())``.
+   On success, return a list, a tuple or a dictionary view in case of a dict,
+   of the keys in object *o*. On failure, return *NULL*.
 
 
 .. c:function:: PyObject* PyMapping_Values(PyObject *o)
 
-   On success, return a list of the values in object *o*.  On failure, return
-   *NULL*. This is equivalent to the Python expression ``list(o.values())``.
+   On success, return a list, a tuple or a dictionary view in case of a dict, of
+   the values in object *o*. On failure, return *NULL*.
 
 
 .. c:function:: PyObject* PyMapping_Items(PyObject *o)
 
-   On success, return a list of the items in object *o*, where each item is a tuple
-   containing a key-value pair.  On failure, return *NULL*. This is equivalent to
-   the Python expression ``list(o.items())``.
+   On success, return a list, a tuple or a dictionary view in case of a dict, 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)
index 7339006..290ef09 100644 (file)
@@ -83,6 +83,12 @@ collection, memory compaction or other preventive procedures. Note that by using
 the C library allocator as shown in the previous example, the allocated memory
 for the I/O buffer escapes completely the Python memory manager.
 
+.. seealso::
+
+   The :envvar:`PYTHONMALLOCSTATS` environment variable can be used to print
+   memory allocation statistics every time a new object arena is created, and
+   on shutdown.
+
 
 Raw Memory Interface
 ====================
@@ -100,9 +106,10 @@ The default raw memory block allocator uses the following functions:
 .. c:function:: void* PyMem_RawMalloc(size_t n)
 
    Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
-   allocated memory, or *NULL* if the request fails. Requesting zero bytes
-   returns a distinct non-*NULL* pointer if possible, as if
-   ``PyMem_RawMalloc(1)`` had been called instead. The memory will not have
+   allocated memory, or *NULL* if the request fails.
+
+   Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as
+   if ``PyMem_RawMalloc(1)`` had been called instead. The memory will not have
    been initialized in any way.
 
 
@@ -110,9 +117,11 @@ The default raw memory block allocator uses the following functions:
 
    Allocates *nelem* elements each whose size in bytes is *elsize* and returns
    a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the
-   request fails. The memory is initialized to zeros. Requesting zero elements
-   or elements of size zero bytes returns a distinct non-*NULL* pointer if
-   possible, as if ``PyMem_RawCalloc(1, 1)`` had been called instead.
+   request fails. The memory is initialized to zeros.
+
+   Requesting zero elements or elements of size zero bytes returns a distinct
+   non-*NULL* pointer if possible, as if ``PyMem_RawCalloc(1, 1)`` had been
+   called instead.
 
    .. versionadded:: 3.5
 
@@ -120,21 +129,28 @@ The default raw memory block allocator uses the following functions:
 .. c:function:: void* PyMem_RawRealloc(void *p, size_t n)
 
    Resizes the memory block pointed to by *p* to *n* bytes. The contents will
-   be unchanged to the minimum of the old and the new sizes. If *p* is *NULL*,
-   the call is equivalent to ``PyMem_RawMalloc(n)``; else if *n* is equal to
-   zero, the memory block is resized but is not freed, and the returned pointer
-   is non-*NULL*. Unless *p* is *NULL*, it must have been returned by a
-   previous call to :c:func:`PyMem_RawMalloc` or :c:func:`PyMem_RawRealloc`. If
-   the request fails, :c:func:`PyMem_RawRealloc` returns *NULL* and *p* remains
-   a valid pointer to the previous memory area.
+   be unchanged to the minimum of the old and the new sizes.
+
+   If *p* is *NULL*, the call is equivalent to ``PyMem_RawMalloc(n)``; else if
+   *n* is equal to zero, the memory block is resized but is not freed, and the
+   returned pointer is non-*NULL*.
+
+   Unless *p* is *NULL*, it must have been returned by a previous call to
+   :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc` or
+   :c:func:`PyMem_RawCalloc`.
+
+   If the request fails, :c:func:`PyMem_RawRealloc` returns *NULL* and *p*
+   remains a valid pointer to the previous memory area.
 
 
 .. c:function:: void PyMem_RawFree(void *p)
 
    Frees the memory block pointed to by *p*, which must have been returned by a
-   previous call to :c:func:`PyMem_RawMalloc` or :c:func:`PyMem_RawRealloc`.
-   Otherwise, or if ``PyMem_Free(p)`` has been called before, undefined
-   behavior occurs. If *p* is *NULL*, no operation is performed.
+   previous call to :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc` or
+   :c:func:`PyMem_RawCalloc`.  Otherwise, or if ``PyMem_Free(p)`` has been
+   called before, undefined behavior occurs.
+
+   If *p* is *NULL*, no operation is performed.
 
 
 .. _memoryinterface:
@@ -158,18 +174,22 @@ The default memory block allocator uses the following functions:
 .. c:function:: void* PyMem_Malloc(size_t n)
 
    Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
-   allocated memory, or *NULL* if the request fails. Requesting zero bytes returns
-   a distinct non-*NULL* pointer if possible, as if ``PyMem_Malloc(1)`` had
-   been called instead. The memory will not have been initialized in any way.
+   allocated memory, or *NULL* if the request fails.
+
+   Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as
+   if ``PyMem_Malloc(1)`` had been called instead. The memory will not have
+   been initialized in any way.
 
 
 .. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize)
 
    Allocates *nelem* elements each whose size in bytes is *elsize* and returns
    a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the
-   request fails. The memory is initialized to zeros. Requesting zero elements
-   or elements of size zero bytes returns a distinct non-*NULL* pointer if
-   possible, as if ``PyMem_Calloc(1, 1)`` had been called instead.
+   request fails. The memory is initialized to zeros.
+
+   Requesting zero elements or elements of size zero bytes returns a distinct
+   non-*NULL* pointer if possible, as if ``PyMem_Calloc(1, 1)`` had been called
+   instead.
 
    .. versionadded:: 3.5
 
@@ -177,21 +197,27 @@ The default memory block allocator uses the following functions:
 .. c:function:: void* PyMem_Realloc(void *p, size_t n)
 
    Resizes the memory block pointed to by *p* to *n* bytes. The contents will be
-   unchanged to the minimum of the old and the new sizes. If *p* is *NULL*, the
-   call is equivalent to ``PyMem_Malloc(n)``; else if *n* is equal to zero,
-   the memory block is resized but is not freed, and the returned pointer is
-   non-*NULL*.  Unless *p* is *NULL*, it must have been returned by a previous call
-   to :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`. If the request fails,
-   :c:func:`PyMem_Realloc` returns *NULL* and *p* remains a valid pointer to the
-   previous memory area.
+   unchanged to the minimum of the old and the new sizes.
+
+   If *p* is *NULL*, the call is equivalent to ``PyMem_Malloc(n)``; else if *n*
+   is equal to zero, the memory block is resized but is not freed, and the
+   returned pointer is non-*NULL*.
+
+   Unless *p* is *NULL*, it must have been returned by a previous call to
+   :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc` or :c:func:`PyMem_Calloc`.
+
+   If the request fails, :c:func:`PyMem_Realloc` returns *NULL* and *p* remains
+   a valid pointer to the previous memory area.
 
 
 .. c:function:: void PyMem_Free(void *p)
 
    Frees the memory block pointed to by *p*, which must have been returned by a
-   previous call to :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`.  Otherwise, or
-   if ``PyMem_Free(p)`` has been called before, undefined behavior occurs. If
-   *p* is *NULL*, no operation is performed.
+   previous call to :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc` or
+   :c:func:`PyMem_Calloc`.  Otherwise, or if ``PyMem_Free(p)`` has been called
+   before, undefined behavior occurs.
+
+   If *p* is *NULL*, no operation is performed.
 
 The following type-oriented macros are provided for convenience.  Note  that
 *TYPE* refers to any C type.
@@ -209,8 +235,10 @@ The following type-oriented macros are provided for convenience.  Note  that
    Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n *
    sizeof(TYPE))`` bytes.  Returns a pointer cast to :c:type:`TYPE\*`. On return,
    *p* will be a pointer to the new memory area, or *NULL* in the event of
-   failure.  This is a C preprocessor macro; p is always reassigned.  Save
-   the original value of p to avoid losing memory when handling errors.
+   failure.
+
+   This is a C preprocessor macro; *p* is always reassigned.  Save the original
+   value of *p* to avoid losing memory when handling errors.
 
 
 .. c:function:: void PyMem_Del(void *p)
@@ -222,9 +250,12 @@ allocator directly, without involving the C API functions listed above. However,
 note that their use does not preserve binary compatibility across Python
 versions and is therefore deprecated in extension modules.
 
-:c:func:`PyMem_MALLOC`, :c:func:`PyMem_REALLOC`, :c:func:`PyMem_FREE`.
-
-:c:func:`PyMem_NEW`, :c:func:`PyMem_RESIZE`, :c:func:`PyMem_DEL`.
+* ``PyMem_MALLOC(size)``
+* ``PyMem_NEW(type, size)``
+* ``PyMem_REALLOC(ptr, size)``
+* ``PyMem_RESIZE(ptr, type, size)``
+* ``PyMem_FREE(ptr)``
+* ``PyMem_DEL(ptr)``
 
 
 Customize Memory Allocators
@@ -262,11 +293,13 @@ Customize Memory Allocators
    Enum used to identify an allocator domain. Domains:
 
    * :c:data:`PYMEM_DOMAIN_RAW`: functions :c:func:`PyMem_RawMalloc`,
-     :c:func:`PyMem_RawRealloc` and :c:func:`PyMem_RawFree`
+     :c:func:`PyMem_RawRealloc`, :c:func:`PyMem_RawCalloc` and
+     :c:func:`PyMem_RawFree`
    * :c:data:`PYMEM_DOMAIN_MEM`: functions :c:func:`PyMem_Malloc`,
-     :c:func:`PyMem_Realloc` and :c:func:`PyMem_Free`
+     :c:func:`PyMem_Realloc`, :c:func:`PyMem_Calloc` and :c:func:`PyMem_Free`
    * :c:data:`PYMEM_DOMAIN_OBJ`: functions :c:func:`PyObject_Malloc`,
-     :c:func:`PyObject_Realloc` and :c:func:`PyObject_Free`
+     :c:func:`PyObject_Realloc`, :c:func:`PyObject_Calloc` and
+     :c:func:`PyObject_Free`
 
 
 .. c:function:: void PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
@@ -296,10 +329,11 @@ Customize Memory Allocators
    functions:
 
    - :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc`,
-     :c:func:`PyMem_RawFree`
-   - :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc`, :c:func:`PyMem_Free`
+     :c:func:`PyMem_RawCalloc`, :c:func:`PyMem_RawFree`
+   - :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc`, :c:func:`PyMem_Calloc`,
+     :c:func:`PyMem_Free`
    - :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc`,
-     :c:func:`PyObject_Free`
+     :c:func:`PyObject_Calloc`, :c:func:`PyObject_Free`
 
    Newly allocated memory is filled with the byte ``0xCB``, freed memory is
    filled with the byte ``0xDB``. Additional checks:
index acc81e4..7a2a84f 100644 (file)
@@ -49,7 +49,7 @@ Method Objects
 .. index:: object: method
 
 Methods are bound function objects. Methods are always bound to an instance of
-an user-defined class. Unbound methods (methods bound to a class object) are
+a user-defined class. Unbound methods (methods bound to a class object) are
 no longer available.
 
 
index ef778cc..904b4b1 100644 (file)
@@ -50,7 +50,7 @@ Module Objects
 
 .. c:function:: PyObject* PyModule_New(const char *name)
 
-   Similar to :c:func:`PyImport_NewObject`, but the name is an UTF-8 encoded
+   Similar to :c:func:`PyImport_NewObject`, but the name is a UTF-8 encoded
    string instead of a Unicode object.
 
 
@@ -129,7 +129,7 @@ which export an initialization function), or compiled-in modules
 (where the initialization function is added using :c:func:`PyImport_AppendInittab`).
 See :ref:`building` or :ref:`extending-with-embedding` for details.
 
-The initialization function can either pass pass a module definition instance
+The initialization function can either pass a module definition instance
 to :c:func:`PyModule_Create`, and return the resulting module object,
 or request "multi-phase initialization" by returning the definition struct itself.
 
index 97b45b1..b761c80 100644 (file)
@@ -68,25 +68,35 @@ Object Protocol
 .. c:function:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)
 
    Set the value of the attribute named *attr_name*, for object *o*, to the value
-   *v*. Returns ``-1`` on failure.  This is the equivalent of the Python statement
+   *v*. Raise an exception and return ``-1`` on failure;
+   return ``0`` on success.  This is the equivalent of the Python statement
    ``o.attr_name = v``.
 
+   If *v* is *NULL*, the attribute is deleted, however this feature is
+   deprecated in favour of using :c:func:`PyObject_DelAttr`.
+
 
 .. c:function:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
 
    Set the value of the attribute named *attr_name*, for object *o*, to the value
-   *v*. Returns ``-1`` on failure.  This is the equivalent of the Python statement
+   *v*. Raise an exception and return ``-1`` on failure;
+   return ``0`` on success.  This is the equivalent of the Python statement
    ``o.attr_name = v``.
 
+   If *v* is *NULL*, the attribute is deleted, however this feature is
+   deprecated in favour of using :c:func:`PyObject_DelAttrString`.
+
 
 .. c:function:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)
 
-   Generic attribute setter function that is meant to be put into a type
-   object's ``tp_setattro`` slot.  It looks for a data descriptor in the
+   Generic attribute setter and deleter function that is meant
+   to be put into a type object's :c:member:`~PyTypeObject.tp_setattro`
+   slot.  It looks for a data descriptor in the
    dictionary of classes in the object's MRO, and if found it takes preference
-   over setting the attribute in the instance dictionary. Otherwise, the
-   attribute is set in the object's :attr:`~object.__dict__` (if present).
-   Otherwise, an :exc:`AttributeError` is raised and ``-1`` is returned.
+   over setting or deleting the attribute in the instance dictionary. Otherwise, the
+   attribute is set or deleted in the object's :attr:`~object.__dict__` (if present).
+   On success, ``0`` is returned, otherwise an :exc:`AttributeError`
+   is raised and ``-1`` is returned.
 
 
 .. c:function:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name)
@@ -378,7 +388,8 @@ Object Protocol
 
 .. c:function:: int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)
 
-   Map the object *key* to the value *v*.  Returns ``-1`` on failure.  This is the
+   Map the object *key* to the value *v*.  Raise an exception and
+   return ``-1`` on failure; return ``0`` on success.  This is the
    equivalent of the Python statement ``o[key] = v``.
 
 
index 5960db9..f1825f0 100644 (file)
@@ -62,10 +62,14 @@ Sequence Protocol
 
 .. c:function:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v)
 
-   Assign object *v* to the *i*\ th element of *o*.  Returns ``-1`` on failure.  This
+   Assign object *v* to the *i*\ th element of *o*.  Raise an exception
+   and return ``-1`` on failure; return ``0`` on success.  This
    is the equivalent of the Python statement ``o[i] = v``.  This function *does
    not* steal a reference to *v*.
 
+   If *v* is *NULL*, the element is deleted, however this feature is
+   deprecated in favour of using :c:func:`PySequence_DelItem`.
+
 
 .. c:function:: int PySequence_DelItem(PyObject *o, Py_ssize_t i)
 
index 7f4d534..8de0394 100644 (file)
@@ -128,7 +128,7 @@ or :class:`frozenset` or instances of their subtypes.
    of brand new frozensets before they are exposed to other code).  Return 0 on
    success or -1 on failure. Raise a :exc:`TypeError` if the *key* is
    unhashable. Raise a :exc:`MemoryError` if there is no room to grow.  Raise a
-   :exc:`SystemError` if *set* is an not an instance of :class:`set` or its
+   :exc:`SystemError` if *set* is not an instance of :class:`set` or its
    subtype.
 
 
@@ -142,7 +142,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
    error is encountered.  Does not raise :exc:`KeyError` for missing keys.  Raise a
    :exc:`TypeError` if the *key* is unhashable.  Unlike the Python :meth:`~set.discard`
    method, this function does not automatically convert unhashable sets into
-   temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is an not an
+   temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is not an
    instance of :class:`set` or its subtype.
 
 
@@ -150,7 +150,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
 
    Return a new reference to an arbitrary object in the *set*, and removes the
    object from the *set*.  Return *NULL* on failure.  Raise :exc:`KeyError` if the
-   set is empty. Raise a :exc:`SystemError` if *set* is an not an instance of
+   set is empty. Raise a :exc:`SystemError` if *set* is not an instance of
    :class:`set` or its subtype.
 
 
index 063f856..5b771dd 100644 (file)
@@ -34,5 +34,5 @@ will work on all subsequent Python releases, but fail to load (because of
 missing symbols) on the older releases.
 
 As of Python 3.2, the set of functions available to the limited API is
-documented in PEP 384.  In the C API documentation, API elements that are not
+documented in :pep:`384`.  In the C API documentation, API elements that are not
 part of the limited API are marked as "Not part of the limited API."
index b5113aa..ac589b8 100644 (file)
@@ -208,12 +208,13 @@ type objects) *must* have the :attr:`ob_size` field.
 
 .. c:member:: setattrfunc PyTypeObject.tp_setattr
 
-   An optional pointer to the set-attribute-string function.
+   An optional pointer to the function for setting and deleting attributes.
 
    This field is deprecated.  When it is defined, it should point to a function
    that acts the same as the :c:member:`~PyTypeObject.tp_setattro` function, but taking a C string
    instead of a Python string object to give the attribute name.  The signature is
-   the same as for :c:func:`PyObject_SetAttrString`.
+   the same as for :c:func:`PyObject_SetAttrString`, but setting
+   *v* to *NULL* to delete an attribute must be supported.
 
    This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype
    inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when
@@ -351,9 +352,10 @@ type objects) *must* have the :attr:`ob_size` field.
 
 .. c:member:: setattrofunc PyTypeObject.tp_setattro
 
-   An optional pointer to the set-attribute function.
+   An optional pointer to the function for setting and deleting attributes.
 
-   The signature is the same as for :c:func:`PyObject_SetAttr`.  It is usually
+   The signature is the same as for :c:func:`PyObject_SetAttr`, but setting
+   *v* to *NULL* to delete an attribute must be supported.  It is usually
    convenient to set this field to :c:func:`PyObject_GenericSetAttr`, which
    implements the normal way of setting object attributes.
 
@@ -724,7 +726,7 @@ type objects) *must* have the :attr:`ob_size` field.
       typedef struct PyGetSetDef {
           char *name;    /* attribute name */
           getter get;    /* C function to get the attribute */
-          setter set;    /* C function to set the attribute */
+          setter set;    /* C function to set or delete the attribute */
           char *doc;     /* optional doc string */
           void *closure; /* optional additional data for getter and setter */
       } PyGetSetDef;
@@ -775,12 +777,14 @@ type objects) *must* have the :attr:`ob_size` field.
 
 .. c:member:: descrsetfunc PyTypeObject.tp_descr_set
 
-   An optional pointer to a "descriptor set" function.
+   An optional pointer to a function for setting and deleting
+   a descriptor's value.
 
    The function signature is ::
 
       int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
 
+   The *value* argument is set to *NULL* to delete the value.
    This field is inherited by subtypes.
 
    .. XXX explain.
@@ -1171,9 +1175,11 @@ Mapping Object Structures
 
 .. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript
 
-   This function is used by :c:func:`PyObject_SetItem` and has the same
-   signature.  If this slot is *NULL*, the object does not support item
-   assignment.
+   This function is used by :c:func:`PyObject_SetItem` and
+   :c:func:`PyObject_DelItem`.  It has the same signature as
+   :c:func:`PyObject_SetItem`, but *v* can also be set to *NULL* to delete
+   an item.  If this slot is *NULL*, the object does not support item
+   assignment and deletion.
 
 
 .. _sequence-structs:
@@ -1222,7 +1228,7 @@ Sequence Object Structures
 
    This function is used by :c:func:`PySequence_SetItem` and has the same
    signature.  This slot may be left to *NULL* if the object does not support
-   item assignment.
+   item assignment and deletion.
 
 .. c:member:: objobjproc PySequenceMethods.sq_contains
 
index 2eeadb5..a0672ca 100644 (file)
@@ -367,7 +367,7 @@ These APIs can be used to work with surrogates:
 
 .. c:macro:: Py_UNICODE_IS_HIGH_SURROGATE(ch)
 
-   Check if *ch* is an high surrogate (``0xD800 <= ch <= 0xDBFF``).
+   Check if *ch* is a high surrogate (``0xD800 <= ch <= 0xDBFF``).
 
 .. c:macro:: Py_UNICODE_IS_LOW_SURROGATE(ch)
 
@@ -423,7 +423,7 @@ APIs:
 
 .. c:function:: PyObject *PyUnicode_FromString(const char *u)
 
-   Create a Unicode object from an UTF-8 encoded null-terminated char buffer
+   Create a Unicode object from a UTF-8 encoded null-terminated char buffer
    *u*.
 
 
@@ -450,7 +450,7 @@ APIs:
    | :attr:`%%`        | *n/a*               | The literal % character.       |
    +-------------------+---------------------+--------------------------------+
    | :attr:`%c`        | int                 | A single character,            |
-   |                   |                     | represented as an C int.       |
+   |                   |                     | represented as a C int.        |
    +-------------------+---------------------+--------------------------------+
    | :attr:`%d`        | int                 | Exactly equivalent to          |
    |                   |                     | ``printf("%d")``.              |
@@ -556,14 +556,13 @@ APIs:
 .. c:function:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, \
                                const char *encoding, const char *errors)
 
-   Coerce an encoded object *obj* to an Unicode object and return a reference with
-   incremented refcount.
+   Decode an encoded object *obj* to a Unicode object.
 
    :class:`bytes`, :class:`bytearray` and other
    :term:`bytes-like objects <bytes-like object>`
    are decoded according to the given *encoding* and using the error handling
    defined by *errors*. Both can be *NULL* to have the interface use the default
-   values (see the next section for details).
+   values (see :ref:`builtincodecs` for details).
 
    All other objects, including Unicode objects, cause a :exc:`TypeError` to be
    set.
@@ -614,8 +613,7 @@ APIs:
 
    This function checks that *unicode* is a Unicode object, that the index is
    not out of bounds, and that the object can be modified safely (i.e. that it
-   its reference count is one), in contrast to the macro version
-   :c:func:`PyUnicode_WRITE_CHAR`.
+   its reference count is one).
 
    .. versionadded:: 3.3
 
@@ -745,8 +743,11 @@ Extension modules can continue using them, as they will not be removed in Python
 
 .. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj)
 
-   Shortcut for ``PyUnicode_FromEncodedObject(obj, NULL, "strict")`` which is used
-   throughout the interpreter whenever coercion to Unicode is needed.
+   Copy an instance of a Unicode subtype to a new true Unicode object if
+   necessary. If *obj* is already a true Unicode object (not a subtype),
+   return the reference with incremented refcount.
+
+   Objects other than Unicode or its subtypes will cause a :exc:`TypeError`.
 
 
 Locale Encoding
@@ -1224,7 +1225,7 @@ These are the UTF-16 codec APIs:
 
    If *Py_UNICODE_WIDE* is defined, a single :c:type:`Py_UNICODE` value may get
    represented as a surrogate pair. If it is not defined, each :c:type:`Py_UNICODE`
-   values is interpreted as an UCS-2 character.
+   values is interpreted as a UCS-2 character.
 
    Return *NULL* if an exception was raised by the codec.
 
index f8aaf0f..706efdf 100644 (file)
@@ -307,10 +307,16 @@ the same library that the Python runtime is using.
    cells.
 
 
+.. c:type:: PyFrameObject
+
+   The C structure of the objects used to describe frame objects. The
+   fields of this type are subject to change at any time.
+
+
 .. c:function:: PyObject* PyEval_EvalFrame(PyFrameObject *f)
 
    Evaluate an execution frame.  This is a simplified interface to
-   PyEval_EvalFrameEx, for backward compatibility.
+   :c:func:`PyEval_EvalFrameEx`, for backward compatibility.
 
 
 .. c:function:: PyObject* PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
index 28dd80f..d6f20ba 100644 (file)
@@ -17,7 +17,7 @@ extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest',
 
 # General substitutions.
 project = 'Python'
-copyright = '1990-%s, Python Software Foundation' % time.strftime('%Y')
+copyright = '2001-%s, Python Software Foundation' % time.strftime('%Y')
 
 # We look for the Include/patchlevel.h file in the current Python source tree
 # and replace the values accordingly.
@@ -138,6 +138,11 @@ latex_appendices = ['glossary', 'about', 'license', 'copyright']
 # Get LaTeX to handle Unicode correctly
 latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''}
 
+# Options for Epub output
+# -----------------------
+
+epub_author = 'Python Documentation Authors'
+epub_publisher = 'Python Software Foundation'
 
 # Options for the coverage checker
 # --------------------------------
index 2b2f887..22d7705 100644 (file)
@@ -4,7 +4,7 @@ Copyright
 
 Python and this documentation is:
 
-Copyright © 2001-2015 Python Software Foundation. All rights reserved.
+Copyright © 2001-2016 Python Software Foundation. All rights reserved.
 
 Copyright © 2000 BeOpen.com. All rights reserved.
 
index 1774d23..82ecd2c 100644 (file)
@@ -35,7 +35,7 @@ Key terms
   repository of open source licensed packages made available for use by
   other Python users
 * the `Python Packaging Authority
-  <https://packaging.python.org/en/latest/future.html>`__ are the group of
+  <https://www.pypa.io/>`__ are the group of
   developers and documentation authors responsible for the maintenance and
   evolution of the standard packaging tools and the associated metadata and
   file format standards. They maintain a variety of tools, documentation
@@ -61,8 +61,8 @@ Key terms
   extensions, to be installed on a system without needing to be built
   locally.
 
-.. _setuptools: https://setuptools.pypa.io/en/latest/setuptools.html
-.. _wheel: http://wheel.readthedocs.org
+.. _setuptools: https://setuptools.readthedocs.io/en/latest/
+.. _wheel: https://wheel.readthedocs.org
 
 Open source licensing and collaboration
 =======================================
@@ -111,7 +111,7 @@ by invoking the ``pip`` module at the command line::
 The Python Packaging User Guide includes more details on the `currently
 recommended tools`_.
 
-.. _currently recommended tools: https://packaging.python.org/en/latest/current.html#packaging-tool-recommendations
+.. _currently recommended tools: https://packaging.python.org/en/latest/current/#packaging-tool-recommendations
 
 Reading the guide
 =================
@@ -124,11 +124,11 @@ involved in creating a project:
 * `Uploading the project to the Python Packaging Index`_
 
 .. _Project structure: \
-   https://packaging.python.org/en/latest/distributing.html#creating-your-own-project
+   https://packaging.python.org/en/latest/distributing/
 .. _Building and packaging the project: \
-   https://packaging.python.org/en/latest/distributing.html#packaging-your-project
+   https://packaging.python.org/en/latest/distributing/#packaging-your-project
 .. _Uploading the project to the Python Packaging Index: \
-   https://packaging.python.org/en/latest/distributing.html#uploading-your-project-to-pypi
+   https://packaging.python.org/en/latest/distributing/#uploading-your-project-to-pypi
 
 
 How do I...?
@@ -160,11 +160,11 @@ Python Packaging User Guide for more information and recommendations.
 .. seealso::
 
    `Python Packaging User Guide: Binary Extensions
-   <https://packaging.python.org/en/latest/extensions.html>`__
+   <https://packaging.python.org/en/latest/extensions>`__
 
 .. other topics:
 
    Once the Development & Deployment part of PPUG is fleshed out, some of
    those sections should be linked from new questions here (most notably,
    we should have a question about avoiding depending on PyPI that links to
-   https://packaging.python.org/en/latest/deployment.html#pypi-mirrors-and-caches)
+   https://packaging.python.org/en/latest/mirrors/)
index 554d2c8..0672253 100644 (file)
@@ -319,12 +319,12 @@ This module provides the following functions.
 
 .. function:: gen_preprocess_options(macros, include_dirs)
 
-   Generate C pre-processor options (:option:`-D`, :option:`-U`, :option:`-I`) as
+   Generate C pre-processor options (:option:`-D`, :option:`!-U`, :option:`!-I`) as
    used by at least two types of compilers: the typical Unix compiler and Visual
    C++. *macros* is the usual thing, a list of 1- or 2-tuples, where ``(name,)``
-   means undefine (:option:`-U`) macro *name*, and ``(name, value)`` means define
+   means undefine (:option:`!-U`) macro *name*, and ``(name, value)`` means define
    (:option:`-D`) macro *name* to *value*.  *include_dirs* is just a list of
-   directory names to be added to the header file search path (:option:`-I`).
+   directory names to be added to the header file search path (:option:`!-I`).
    Returns a list of command-line options suitable for either Unix compilers or
    Visual C++.
 
@@ -799,7 +799,7 @@ This module provides the :class:`UnixCCompiler` class, a subclass of
 
 * library search directories specified with :option:`-Ldir`
 
-* compile handled by :program:`cc` (or similar) executable with :option:`-c`
+* compile handled by :program:`cc` (or similar) executable with :option:`!-c`
   option: compiles :file:`.c` to :file:`.o`
 
 * link static library handled by :program:`ar` command (possibly with
@@ -837,7 +837,7 @@ selection by :class:`MSVCCompiler`.
 .. module:: distutils.bcppcompiler
 
 
-This module provides :class:`BorlandCCompiler`, an subclass of the abstract
+This module provides :class:`BorlandCCompiler`, a subclass of the abstract
 :class:`CCompiler` class for the Borland C++ compiler.
 
 
@@ -876,7 +876,7 @@ tarballs or zipfiles.
    archive.  *root_dir* and *base_dir* both default to the current directory.
    Returns the name of the archive file.
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Added support for the ``xztar`` format.
 
 
@@ -891,7 +891,7 @@ tarballs or zipfiles.
    compression extension (``.gz``, ``.bz2``, ``.xz`` or ``.Z``).  Return the
    output filename.
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Added support for the ``xz`` compression.
 
 
@@ -1234,7 +1234,7 @@ other utility module.
       <imp.get_tag>` in their name, in a :file:`__pycache__` subdirectory
       instead of files without tag in the current directory.
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Create ``.pyc`` files according to :pep:`488`.
 
 
@@ -1822,7 +1822,7 @@ Subclasses of :class:`Command` must define the following methods.
 
    Builds a `Windows Installer`_ (.msi) binary package.
 
-   .. _Windows Installer: http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx
+   .. _Windows Installer: https://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx
 
    In most cases, the ``bdist_msi`` installer is a better choice than the
    ``bdist_wininst`` installer, because it provides better support for
@@ -1907,9 +1907,9 @@ Subclasses of :class:`Command` must define the following methods.
    that is designed to run with both Python 2.x and 3.x, add::
 
      try:
-        from distutils.command.build_py import build_py_2to3 as build_py
+         from distutils.command.build_py import build_py_2to3 as build_py
      except ImportError:
-        from distutils.command.build_py import build_py
+         from distutils.command.build_py import build_py
 
    to your setup.py, and later::
 
index 8faffe6..51d8897 100644 (file)
@@ -51,7 +51,7 @@ option values can be split across multiple lines simply by indenting the
 continuation lines.
 
 You can find out the list of options supported by a particular command with the
-universal :option:`--help` option, e.g. ::
+universal :option:`!--help` option, e.g. ::
 
    > python setup.py --help build_ext
    [...]
index 335f804..c565bcc 100644 (file)
@@ -7,6 +7,11 @@
 :Authors: Greg Ward, Anthony Baxter
 :Email: distutils-sig@python.org
 
+.. seealso::
+
+   :ref:`distributing-index`
+      The up to date module distribution documentations
+
 This document describes the Python Distribution Utilities ("Distutils") from
 the module developer's point of view, describing how to use the Distutils to
 make Python modules and extensions easily available to a wider audience with
@@ -20,7 +25,6 @@ very little overhead for build/release/install mechanics.
    recommendations section <https://packaging.python.org/en/latest/current/>`__
    in the Python Packaging User Guide for more information.
 
-
 .. toctree::
    :maxdepth: 2
    :numbered:
index 163179d..b5ccee7 100644 (file)
@@ -40,7 +40,7 @@ It is possible to export multiple modules from a single shared library by
 defining multiple initialization functions. However, importing them requires
 using symbolic links or a custom importer, because by default only the
 function corresponding to the filename is found.
-See :PEP:`489#multiple-modules-in-one-library` for details.
+See the *"Multiple modules in one library"* section in :pep:`489` for details.
 
 
 .. highlightlang:: c
@@ -81,14 +81,15 @@ In the :file:`setup.py`, all execution is performed by calling the ``setup``
 function. This takes a variable number of keyword arguments, of which the
 example above uses only a subset. Specifically, the example specifies
 meta-information to build packages, and it specifies the contents of the
-package.  Normally, a package will contain of addition modules, like Python
+package.  Normally, a package will contain additional modules, like Python
 source modules, documentation, subpackages, etc. Please refer to the distutils
 documentation in :ref:`distutils-index` to learn more about the features of
 distutils; this section explains building extension modules only.
 
 It is common to pre-compute arguments to :func:`setup`, to better structure the
 driver script. In the example above, the ``ext_modules`` argument to
-:func:`setup` is a list of extension modules, each of which is an instance of
+:func:`~distutils.core.setup` is a list of extension modules, each of which is
+an instance of
 the :class:`~distutils.extension.Extension`. In the example, the instance
 defines an extension named ``demo`` which is build by compiling a single source
 file, :file:`demo.c`.
@@ -119,7 +120,8 @@ example below. ::
           ext_modules = [module1])
 
 
-In this example, :func:`setup` is called with additional meta-information, which
+In this example, :func:`~distutils.core.setup` is called with additional
+meta-information, which
 is recommended when distribution packages have to be built. For the extension
 itself, it specifies preprocessor defines, include directories, library
 directories, and libraries. Depending on the compiler, distutils passes this
@@ -150,8 +152,7 @@ Module maintainers should produce source packages; to do so, they run ::
    python setup.py sdist
 
 In some cases, additional files need to be included in a source distribution;
-this is done through a :file:`MANIFEST.in` file; see the distutils documentation
-for details.
+this is done through a :file:`MANIFEST.in` file; see :ref:`manifest` for details.
 
 If the source distribution has been build successfully, maintainers can also
 create binary distributions. Depending on the platform, one of the following
index 8cc4184..523dfab 100644 (file)
@@ -27,7 +27,7 @@ your system setup; details are given in later chapters.
    avoid writing C extensions and preserve portability to other implementations.
    For example, if your use case is calling C library functions or system calls,
    you should consider using the :mod:`ctypes` module or the `cffi
-   <http://cffi.readthedocs.org>`_ library rather than writing custom C code.
+   <https://cffi.readthedocs.org>`_ library rather than writing custom C code.
    These modules let you write Python code to interface with C code and are more
    portable between implementations of Python than writing and compiling a C
    extension module.
index dd43926..9eec8c2 100644 (file)
@@ -32,7 +32,7 @@ approaches to creating C and C++ extensions for Python.
 
 .. seealso::
 
-   `Python Packaging User Guide: Binary Extensions <https://packaging.python.org/en/latest/extensions.html>`_
+   `Python Packaging User Guide: Binary Extensions <https://packaging.python.org/en/latest/extensions/>`_
       The Python Packaging User Guide not only covers several available
       tools that simplify the creation of binary extensions, but also
       discusses the various reasons why creating an extension module may be
index 9fdf8cb..1b6cd7e 100644 (file)
@@ -158,7 +158,7 @@ where in Python you're forced to write this::
        line = f.readline()
        if not line:
            break
-       ... # do something with line
+       ...  # do something with line
 
 The reason for not allowing assignment in Python expressions is a common,
 hard-to-find bug in those other languages, caused by this construct:
@@ -190,7 +190,7 @@ generally less robust than the "while True" solution::
 
    line = f.readline()
    while line:
-       ... # do something with line...
+       ...  # do something with line...
        line = f.readline()
 
 The problem with this is that if you change your mind about exactly how you get
@@ -203,7 +203,7 @@ objects using the ``for`` statement.  For example, :term:`file objects
 <file object>` support the iterator protocol, so you can write simply::
 
    for line in f:
-       ... # do something with line...
+       ...  # do something with line...
 
 
 
@@ -368,9 +368,9 @@ Can Python be compiled to machine code, C or some other language?
 
 Practical answer:
 
-`Cython <http://cython.org/>`_ and `Pyrex <http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_
+`Cython <http://cython.org/>`_ and `Pyrex <https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_
 compile a modified version of Python with optional annotations into C
-extensions.  `Weave <http://docs.scipy.org/doc/scipy-dev/reference/tutorial/weave.html>`_ makes it easy to
+extensions.  `Weave <https://scipy.github.io/devdocs/tutorial/weave.html>`_ makes it easy to
 intermingle Python and C code in various ways to increase performance.
 `Nuitka <http://www.nuitka.net/>`_ is an up-and-coming compiler of Python
 into C++ code, aiming to support the full Python language.
@@ -577,8 +577,10 @@ other structure). ::
    class ListWrapper:
        def __init__(self, the_list):
            self.the_list = the_list
+
        def __eq__(self, other):
            return self.the_list == other.the_list
+
        def __hash__(self):
            l = self.the_list
            result = 98767 - len(l)*555
@@ -619,7 +621,7 @@ it and returns it.  For example, here's how to iterate over the keys of a
 dictionary in sorted order::
 
    for key in sorted(mydict):
-       ... # do whatever with mydict[key]...
+       ...  # do whatever with mydict[key]...
 
 
 How do you specify and enforce an interface spec in Python?
@@ -675,11 +677,11 @@ languages.  For example::
    class label(Exception): pass  # declare a label
 
    try:
-        ...
-        if condition: raise label()  # goto label
-        ...
+       ...
+       if condition: raise label()  # goto label
+       ...
    except label:  # where to goto
-        pass
+       pass
    ...
 
 This doesn't allow you to jump into the middle of a loop, but that's usually
index 7bb4dc2..852e35f 100644 (file)
@@ -42,7 +42,7 @@ on what you're trying to do.
 .. XXX make sure these all work
 
 `Cython <http://cython.org>`_ and its relative `Pyrex
-<http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers
+<https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers
 that accept a slightly modified form of Python and generate the corresponding
 C code.  Cython and Pyrex make it possible to write an extension without having
 to learn Python's C API.
@@ -50,10 +50,10 @@ to learn Python's C API.
 If you need to interface to some C or C++ library for which no Python extension
 currently exists, you can try wrapping the library's data types and functions
 with a tool such as `SWIG <http://www.swig.org>`_.  `SIP
-<http://www.riverbankcomputing.co.uk/software/sip/intro>`__, `CXX
+<https://riverbankcomputing.com/software/sip/intro>`__, `CXX
 <http://cxx.sourceforge.net/>`_ `Boost
 <http://www.boost.org/libs/python/doc/index.html>`_, or `Weave
-<http://docs.scipy.org/doc/scipy-dev/reference/tutorial/weave.html>`_ are also
+<https://scipy.github.io/devdocs/tutorial/weave.html>`_ are also
 alternatives for wrapping C++ libraries.
 
 
@@ -247,20 +247,6 @@ For Red Hat, install the python-devel RPM to get the necessary files.
 For Debian, run ``apt-get install python-dev``.
 
 
-What does "SystemError: _PyImport_FixupExtension: module yourmodule not loaded" mean?
--------------------------------------------------------------------------------------
-
-This means that you have created an extension module named "yourmodule", but
-your module init function does not initialize with that name.
-
-Every module init function will have a line similar to::
-
-   module = Py_InitModule("yourmodule", yourmodule_functions);
-
-If the string passed to this function is not the same name as your extension
-module, the :exc:`SystemError` exception will be raised.
-
-
 How do I tell "incomplete input" from "invalid input"?
 ------------------------------------------------------
 
index 2221f14..6b773dd 100644 (file)
@@ -146,10 +146,9 @@ labeled 2.0aN precede the versions labeled 2.0bN, which precede versions labeled
 2.0cN, and *those* precede 2.0.
 
 You may also find version numbers with a "+" suffix, e.g. "2.2+".  These are
-unreleased versions, built directly from the Subversion trunk.  In practice,
-after a final minor release is made, the Subversion trunk is incremented to the
-next minor version, which becomes the "a0" version,
-e.g. "2.4a0".
+unreleased versions, built directly from the CPython development repository.  In
+practice, after a final minor release is made, the version is incremented to the
+next minor version, which becomes the "a0" version, e.g. "2.4a0".
 
 See also the documentation for :data:`sys.version`, :data:`sys.hexversion`, and
 :data:`sys.version_info`.
@@ -159,7 +158,7 @@ How do I obtain a copy of the Python source?
 --------------------------------------------
 
 The latest Python source distribution is always available from python.org, at
-https://www.python.org/download/.  The latest development sources can be obtained
+https://www.python.org/downloads/.  The latest development sources can be obtained
 via anonymous Mercurial access at https://hg.python.org/cpython.
 
 The source distribution is a gzipped tar file containing the complete C source,
@@ -218,7 +217,7 @@ can be found at https://www.python.org/community/lists/.
 How do I get a beta test version of Python?
 -------------------------------------------
 
-Alpha and beta releases are available from https://www.python.org/download/.  All
+Alpha and beta releases are available from https://www.python.org/downloads/.  All
 releases are announced on the comp.lang.python and comp.lang.python.announce
 newsgroups and on the Python home page at https://www.python.org/; an RSS feed of
 news is available.
@@ -271,9 +270,9 @@ Where in the world is www.python.org located?
 
 The Python project's infrastructure is located all over the world.
 `www.python.org <https://www.python.org>`_ is graciously hosted by `Rackspace
-<http://www.rackspace.com>`_, with CDN caching provided by `Fastly
+<https://www.rackspace.com>`_, with CDN caching provided by `Fastly
 <https://www.fastly.com>`_.  `Upfront Systems
-<http://www.upfrontsystems.co.za>`_ hosts `bugs.python.org
+<http://www.upfrontsystems.co.za/>`_ hosts `bugs.python.org
 <https://bugs.python.org>`_.  Many other Python services like `the Wiki
 <https://wiki.python.org>`_ are hosted by `Oregon State
 University Open Source Lab <https://osuosl.org>`_.
@@ -284,7 +283,7 @@ Why is it called Python?
 
 When he began implementing Python, Guido van Rossum was also reading the
 published scripts from `"Monty Python's Flying Circus"
-<http://en.wikipedia.org/wiki/Monty_Python>`__, a BBC comedy series from the 1970s.  Van Rossum
+<https://en.wikipedia.org/wiki/Monty_Python>`__, a BBC comedy series from the 1970s.  Van Rossum
 thought he needed a name that was short, unique, and slightly mysterious, so he
 decided to call the language Python.
 
@@ -313,7 +312,7 @@ guaranteed that interfaces will remain the same throughout a series of bugfix
 releases.
 
 The latest stable releases can always be found on the `Python download page
-<https://www.python.org/download/>`_.  There are two recommended production-ready
+<https://www.python.org/downloads/>`_.  There are two recommended production-ready
 versions at this point in time, because at the moment there are two branches of
 stable releases: 2.x and 3.x.  Python 3.x may be less useful than 2.x, since
 currently there is more third party software available for Python 2 than for
@@ -345,7 +344,7 @@ different companies and organizations.
 High-profile Python projects include `the Mailman mailing list manager
 <http://www.list.org>`_ and `the Zope application server
 <http://www.zope.org>`_.  Several Linux distributions, most notably `Red Hat
-<http://www.redhat.com>`_, have written part or all of their installer and
+<https://www.redhat.com>`_, have written part or all of their installer and
 system administration software in Python.  Companies that use Python internally
 include Google, Yahoo, and Lucasfilm Ltd.
 
index 5122de1..98a28c3 100644 (file)
@@ -29,15 +29,15 @@ Tkinter
 Standard builds of Python include an object-oriented interface to the Tcl/Tk
 widget set, called :ref:`tkinter <Tkinter>`.  This is probably the easiest to
 install (since it comes included with most
-`binary distributions <https://www.python.org/download/>`_ of Python) and use.
+`binary distributions <https://www.python.org/downloads/>`_ of Python) and use.
 For more info about Tk, including pointers to the source, see the
-`Tcl/Tk home page <http://www.tcl.tk>`_.  Tcl/Tk is fully portable to the
+`Tcl/Tk home page <https://www.tcl.tk>`_.  Tcl/Tk is fully portable to the
 Mac OS X, Windows, and Unix platforms.
 
 wxWidgets
 ---------
 
-wxWidgets (http://www.wxwidgets.org) is a free, portable GUI class
+wxWidgets (https://www.wxwidgets.org) is a free, portable GUI class
 library written in C++ that provides a native look and feel on a
 number of platforms, with Windows, Mac OS X, GTK, X11, all listed as
 current stable targets.  Language bindings are available for a number
@@ -58,21 +58,21 @@ Qt
 ---
 
 There are bindings available for the Qt toolkit (using either `PyQt
-<http://www.riverbankcomputing.co.uk/software/pyqt/intro>`_ or `PySide
-<http://www.pyside.org/>`_) and for KDE (`PyKDE <https://techbase.kde.org/Development/Languages/Python>`__).
+<https://riverbankcomputing.com/software/pyqt/intro>`_ or `PySide
+<https://wiki.qt.io/PySide>`_) and for KDE (`PyKDE4 <https://techbase.kde.org/Languages/Python/Using_PyKDE_4>`__).
 PyQt is currently more mature than PySide, but you must buy a PyQt license from
-`Riverbank Computing <http://www.riverbankcomputing.co.uk/software/pyqt/license>`_
+`Riverbank Computing <https://www.riverbankcomputing.com/commercial/license-faq>`_
 if you want to write proprietary applications.  PySide is free for all applications.
 
 Qt 4.5 upwards is licensed under the LGPL license; also, commercial licenses
-are available from `The Qt Company <http://www.qt.io/licensing/>`_.
+are available from `The Qt Company <https://www.qt.io/licensing/>`_.
 
 Gtk+
 ----
 
-The `GObject introspection bindings <https://live.gnome.org/PyGObject>`_
+The `GObject introspection bindings <https://wiki.gnome.org/Projects/PyGObject>`_
 for Python allow you to write GTK+ 3 applications.  There is also a
-`Python GTK+ 3 Tutorial <http://python-gtk-3-tutorial.readthedocs.org/en/latest/>`_.
+`Python GTK+ 3 Tutorial <https://python-gtk-3-tutorial.readthedocs.org/en/latest/>`_.
 
 The older PyGtk bindings for the `Gtk+ 2 toolkit <http://www.gtk.org>`_ have
 been implemented by James Henstridge; see <http://www.pygtk.org>.
index 064728f..b5fdfa4 100644 (file)
@@ -257,7 +257,8 @@ all the threads to finish::
    import threading, time
 
    def thread_task(name, n):
-       for i in range(n): print(name, i)
+       for i in range(n):
+           print(name, i)
 
    for i in range(10):
        T = threading.Thread(target=thread_task, args=(str(i), i))
@@ -273,7 +274,8 @@ A simple fix is to add a tiny sleep to the start of the run function::
 
    def thread_task(name, n):
        time.sleep(0.001)  # <--------------------!
-       for i in range(n): print(name, i)
+       for i in range(n):
+           print(name, i)
 
    for i in range(10):
        T = threading.Thread(target=thread_task, args=(str(i), i))
@@ -502,8 +504,8 @@ in big-endian format from a file::
    import struct
 
    with open(filename, "rb") as f:
-      s = f.read(8)
-      x, y, z = struct.unpack(">hhl", s)
+       s = f.read(8)
+       x, y, z = struct.unpack(">hhl", s)
 
 The '>' in the format string forces big-endian data; the letter 'h' reads one
 "short integer" (2 bytes), and 'l' reads one "long integer" (4 bytes) from the
@@ -619,7 +621,7 @@ For Win32, POSIX (Linux, BSD, etc.), Jython:
 
 For Unix, see a Usenet post by Mitch Chapman:
 
-   http://groups.google.com/groups?selm=34A04430.CF9@ohioee.com
+   https://groups.google.com/groups?selm=34A04430.CF9@ohioee.com
 
 
 Why doesn't closing sys.stdout (stdin, stderr) really close it?
@@ -681,10 +683,10 @@ Yes. Here's a simple example that uses urllib.request::
 
    import urllib.request
 
-   ### build the query string
+   # build the query string
    qs = "First=Josephine&MI=Q&Last=Public"
 
-   ### connect and send the server a path
+   # connect and send the server a path
    req = urllib.request.urlopen('http://www.some-server.out-there'
                                 '/cgi-bin/some-cgi-script', data=qs)
    with req:
@@ -740,8 +742,9 @@ varies between systems; sometimes it is ``/usr/lib/sendmail``, sometimes
 ``/usr/sbin/sendmail``.  The sendmail manual page will help you out.  Here's
 some sample code::
 
-   SENDMAIL = "/usr/sbin/sendmail"  # sendmail location
    import os
+
+   SENDMAIL = "/usr/sbin/sendmail"  # sendmail location
    p = os.popen("%s -t -i" % SENDMAIL, "w")
    p.write("To: receiver@example.com\n")
    p.write("Subject: test\n")
index 295445e..694753e 100644 (file)
@@ -28,9 +28,9 @@ graphical debugger.
 PythonWin is a Python IDE that includes a GUI debugger based on pdb.  The
 Pythonwin debugger colors breakpoints and has quite a few cool features such as
 debugging non-Pythonwin programs.  Pythonwin is available as part of the `Python
-for Windows Extensions <http://sourceforge.net/projects/pywin32/>`__ project and
+for Windows Extensions <https://sourceforge.net/projects/pywin32/>`__ project and
 as a part of the ActivePython distribution (see
-http://www.activestate.com/activepython\ ).
+https://www.activestate.com/activepython\ ).
 
 `Boa Constructor <http://boa-constructor.sourceforge.net/>`_ is an IDE and GUI
 builder that uses wxWidgets.  It offers visual frame creation and manipulation,
@@ -44,13 +44,13 @@ and the Scintilla editing component.
 Pydb is a version of the standard Python debugger pdb, modified for use with DDD
 (Data Display Debugger), a popular graphical debugger front end.  Pydb can be
 found at http://bashdb.sourceforge.net/pydb/ and DDD can be found at
-http://www.gnu.org/software/ddd.
+https://www.gnu.org/software/ddd.
 
 There are a number of commercial Python IDEs that include graphical debuggers.
 They include:
 
-* Wing IDE (http://wingware.com/)
-* Komodo IDE (http://komodoide.com/)
+* Wing IDE (https://wingware.com/)
+* Komodo IDE (https://komodoide.com/)
 * PyCharm (https://www.jetbrains.com/pycharm/)
 
 
@@ -63,13 +63,13 @@ PyChecker is a static analysis tool that finds bugs in Python source code and
 warns about code complexity and style.  You can get PyChecker from
 http://pychecker.sourceforge.net/.
 
-`Pylint <http://www.logilab.org/projects/pylint>`_ is another tool that checks
+`Pylint <https://www.pylint.org/>`_ is another tool that checks
 if a module satisfies a coding standard, and also makes it possible to write
 plug-ins to add a custom feature.  In addition to the bug checking that
 PyChecker performs, Pylint offers some additional features such as checking line
 length, whether variable names are well-formed according to your coding
 standard, whether declared interfaces are fully implemented, and more.
-http://docs.pylint.org/ provides a full list of Pylint's features.
+https://docs.pylint.org/ provides a full list of Pylint's features.
 
 
 How can I create a stand-alone binary from a Python script?
@@ -207,7 +207,7 @@ functions), e.g.::
 
    >>> squares = []
    >>> for x in range(5):
-   ...    squares.append(lambda: x**2)
+   ...     squares.append(lambda: x**2)
 
 This gives you a list that contains 5 lambdas that calculate ``x**2``.  You
 might expect that, when called, they would return, respectively, ``0``, ``1``,
@@ -234,7 +234,7 @@ lambdas, so that they don't rely on the value of the global ``x``::
 
    >>> squares = []
    >>> for x in range(5):
-   ...    squares.append(lambda n=x: n**2)
+   ...     squares.append(lambda n=x: n**2)
 
 Here, ``n=x`` creates a new variable ``n`` local to the lambda and computed
 when the lambda is defined so that it has the same value that ``x`` had at
@@ -539,7 +539,7 @@ desired effect in a number of ways.
           args['a'] = 'new-value'     # args is a mutable dictionary
           args['b'] = args['b'] + 1   # change it in-place
 
-      args = {'a':old-value', 'b': 99}
+      args = {'a': 'old-value', 'b': 99}
       func3(args)
       print(args['a'], args['b'])
 
@@ -655,16 +655,15 @@ Essentially, assignment always binds a name to a value; The same is true of
 ``def`` and ``class`` statements, but in that case the value is a
 callable. Consider the following code::
 
-   class A:
-       pass
-
-   B = A
-
-   a = B()
-   b = a
-   print(b)
+   >>> class A:
+   ...     pass
+   ...
+   >>> B = A
+   >>> a = B()
+   >>> b = a
+   >>> print(b)
    <__main__.A object at 0x16D07CC>
-   print(a)
+   >>> print(a)
    <__main__.A object at 0x16D07CC>
 
 Arguably the class has a name: even though it is bound to two names and invoked
@@ -839,7 +838,7 @@ How do I convert a number to a string?
 To convert, e.g., the number 144 to the string '144', use the built-in type
 constructor :func:`str`.  If you want a hexadecimal or octal representation, use
 the built-in functions :func:`hex` or :func:`oct`.  For fancy formatting, see
-the :ref:`string-formatting` section, e.g. ``"{:04d}".format(144)`` yields
+the :ref:`formatstrings` section, e.g. ``"{:04d}".format(144)`` yields
 ``'0144'`` and ``"{:.3f}".format(1.0/3.0)`` yields ``'0.333'``.
 
 
@@ -1010,8 +1009,7 @@ performance levels:
   may come up with.  This is doubly true for primitives written in C, such
   as builtins and some extension types.  For example, be sure to use
   either the :meth:`list.sort` built-in method or the related :func:`sorted`
-  function to do sorting (and see the
-  `sorting mini-HOWTO <https://wiki.python.org/moin/HowTo/Sorting>`_ for examples
+  function to do sorting (and see the :ref:`sortinghowto` for examples
   of moderately advanced usage).
 
 * Abstractions tend to create indirections and force the interpreter to work
@@ -1100,7 +1098,7 @@ How do I iterate over a sequence in reverse order?
 Use the :func:`reversed` built-in function, which is new in Python 2.4::
 
    for x in reversed(sequence):
-       ... # do something with x...
+       ...  # do something with x ...
 
 This won't touch your original sequence, but build a new copy with reversed
 order to iterate over.
@@ -1108,7 +1106,7 @@ order to iterate over.
 With Python 2.3, you can use an extended slice syntax::
 
    for x in sequence[::-1]:
-       ... # do something with x...
+       ...  # do something with x ...
 
 
 How do you remove duplicates from a list?
@@ -1116,7 +1114,7 @@ How do you remove duplicates from a list?
 
 See the Python Cookbook for a long discussion of many ways to do this:
 
-   http://code.activestate.com/recipes/52560/
+   https://code.activestate.com/recipes/52560/
 
 If you don't mind reordering the list, sort it and then scan from the end of the
 list, deleting duplicates as you go::
@@ -1173,16 +1171,28 @@ You probably tried to make a multidimensional array like this::
 
    >>> A = [[None] * 2] * 3
 
-This looks correct if you print it::
+This looks correct if you print it:
+
+.. testsetup::
+
+   A = [[None] * 2] * 3
+
+.. doctest::
 
    >>> A
    [[None, None], [None, None], [None, None]]
 
 But when you assign a value, it shows up in multiple places:
 
-  >>> A[0][0] = 5
-  >>> A
-  [[5, None], [5, None], [5, None]]
+.. testsetup::
+
+   A = [[None] * 2] * 3
+
+.. doctest::
+
+   >>> A[0][0] = 5
+   >>> A
+   [[5, None], [5, None], [5, None]]
 
 The reason is that replicating a list with ``*`` doesn't create copies, it only
 creates references to the existing objects.  The ``*3`` creates a list
@@ -1202,7 +1212,7 @@ use a list comprehension::
    w, h = 2, 3
    A = [[None] * w for i in range(h)]
 
-Or, you can use an extension that provides a matrix datatype; `Numeric Python
+Or, you can use an extension that provides a matrix datatype; `NumPy
 <http://www.numpy.org/>`_ is the best known.
 
 
@@ -1314,40 +1324,11 @@ I want to do a complicated sort: can you do a Schwartzian Transform in Python?
 
 The technique, attributed to Randal Schwartz of the Perl community, sorts the
 elements of a list by a metric which maps each element to its "sort value". In
-Python, just use the ``key`` argument for the ``sort()`` method::
+Python, use the ``key`` argument for the :meth:`list.sort` method::
 
    Isorted = L[:]
    Isorted.sort(key=lambda s: int(s[10:15]))
 
-The ``key`` argument is new in Python 2.4, for older versions this kind of
-sorting is quite simple to do with list comprehensions.  To sort a list of
-strings by their uppercase values::
-
-  tmp1 = [(x.upper(), x) for x in L]  # Schwartzian transform
-  tmp1.sort()
-  Usorted = [x[1] for x in tmp1]
-
-To sort by the integer value of a subfield extending from positions 10-15 in
-each string::
-
-  tmp2 = [(int(s[10:15]), s) for s in L]  # Schwartzian transform
-  tmp2.sort()
-  Isorted = [x[1] for x in tmp2]
-
-For versions prior to 3.0, Isorted may also be computed by ::
-
-   def intfield(s):
-       return int(s[10:15])
-
-   def Icmp(s1, s2):
-       return cmp(intfield(s1), intfield(s2))
-
-   Isorted = L[:]
-   Isorted.sort(Icmp)
-
-but since this method calls ``intfield()`` many times for each element of L, it
-is slower than the Schwartzian Transform.
-
 
 How can I sort one list by values from another list?
 ----------------------------------------------------
@@ -1406,7 +1387,7 @@ A method is a function on some object ``x`` that you normally call as
 definition::
 
    class C:
-       def meth (self, arg):
+       def meth(self, arg):
            return arg * 2 + self.attribute
 
 
@@ -1439,9 +1420,9 @@ that does something::
 
    def search(obj):
        if isinstance(obj, Mailbox):
-           # ... code to search a mailbox
+           ...  # code to search a mailbox
        elif isinstance(obj, Document):
-           # ... code to search a document
+           ...  # code to search a document
        elif ...
 
 A better approach is to define a ``search()`` method on all the classes and just
@@ -1449,11 +1430,11 @@ call it::
 
    class Mailbox:
        def search(self):
-           # ... code to search a mailbox
+           ...  # code to search a mailbox
 
    class Document:
        def search(self):
-           # ... code to search a document
+           ...  # code to search a document
 
    obj.search()
 
@@ -1510,7 +1491,7 @@ How do I call a method defined in a base class from a derived class that overrid
 Use the built-in :func:`super` function::
 
    class Derived(Base):
-       def meth (self):
+       def meth(self):
            super(Derived, self).meth()
 
 For version prior to 3.0, you may be using classic classes: For a class
@@ -1695,9 +1676,9 @@ address, it happens frequently that after an object is deleted from memory, the
 next freshly created object is allocated at the same position in memory.  This
 is illustrated by this example:
 
->>> id(1000)
+>>> id(1000) # doctest: +SKIP
 13901272
->>> id(2000)
+>>> id(2000) # doctest: +SKIP
 13901272
 
 The two ids belong to different integer objects that are created before, and
@@ -1706,9 +1687,9 @@ objects whose id you want to examine are still alive, create another reference
 to the object:
 
 >>> a = 1000; b = 2000
->>> id(a)
+>>> id(a) # doctest: +SKIP
 13901272
->>> id(b)
+>>> id(b) # doctest: +SKIP
 13891296
 
 
index 6db6637..d725343 100644 (file)
@@ -340,5 +340,5 @@ This is a mistake; the extension should be .TGZ.
 
 Simply rename the downloaded file to have the .TGZ extension, and WinZip will be
 able to handle it.  (If your copy of WinZip doesn't, get a newer one from
-http://www.winzip.com.)
+https://www.winzip.com.)
 
index 6808e7a..45b794f 100644 (file)
@@ -76,13 +76,12 @@ Glossary
 
    asynchronous iterable
       An object, that can be used in an :keyword:`async for` statement.
-      Must return an :term:`awaitable` from its :meth:`__aiter__` method,
-      which should in turn be resolved in an :term:`asynchronous iterator`
-      object.  Introduced by :pep:`492`.
+      Must return an :term:`asynchronous iterator` from its
+      :meth:`__aiter__` method.  Introduced by :pep:`492`.
 
    asynchronous iterator
       An object that implements :meth:`__aiter__` and :meth:`__anext__`
-      methods, that must return :term:`awaitable` objects.
+      methods.  ``__anext__`` must return an :term:`awaitable` object.
       :keyword:`async for` resolves awaitable returned from asynchronous
       iterator's :meth:`__anext__` method until it raises
       :exc:`StopAsyncIteration` exception.  Introduced by :pep:`492`.
@@ -177,7 +176,7 @@ Glossary
       A buffer is considered contiguous exactly if it is either
       *C-contiguous* or *Fortran contiguous*.  Zero-dimensional buffers are
       C and Fortran contiguous.  In one-dimensional arrays, the items
-      must be layed out in memory next to each other, in order of
+      must be laid out in memory next to each other, in order of
       increasing indexes starting from zero.  In multidimensional
       C-contiguous arrays, the last index varies the fastest when
       visiting items in order of memory address.  However, in
@@ -308,10 +307,14 @@ Glossary
       A synonym for :term:`file object`.
 
    finder
-      An object that tries to find the :term:`loader` for a module. It must
-      implement either a method named :meth:`find_loader` or a method named
-      :meth:`find_module`. See :pep:`302` and :pep:`420` for details and
-      :class:`importlib.abc.Finder` for an :term:`abstract base class`.
+      An object that tries to find the :term:`loader` for a module that is
+      being imported.
+
+      Since Python 3.3, there are two types of finder: :term:`meta path finders
+      <meta path finder>` for use with :data:`sys.meta_path`, and :term:`path
+      entry finders <path entry finder>` for use with :data:`sys.path_hooks`.
+
+      See :pep:`302`, :pep:`420` and :pep:`451` for much more detail.
 
    floor division
       Mathematical division that rounds down to nearest integer.  The floor
@@ -593,10 +596,13 @@ Glossary
       :class:`collections.OrderedDict` and :class:`collections.Counter`.
 
    meta path finder
-      A finder returned by a search of :data:`sys.meta_path`.  Meta path
+      A :term:`finder` returned by a search of :data:`sys.meta_path`.  Meta path
       finders are related to, but different from :term:`path entry finders
       <path entry finder>`.
 
+      See :class:`importlib.abc.MetaPathFinder` for the methods that meta path
+      finders implement.
+
    metaclass
       The class of a class.  Class definitions create a class name, a class
       dictionary, and a list of base classes.  The metaclass is responsible for
@@ -619,7 +625,8 @@ Glossary
    method resolution order
       Method Resolution Order is the order in which base classes are searched
       for a member during lookup. See `The Python 2.3 Method Resolution Order
-      <https://www.python.org/download/releases/2.3/mro/>`_.
+      <https://www.python.org/download/releases/2.3/mro/>`_ for details of the
+      algorithm used by the Python interpreter since the 2.3 release.
 
    module
       An object that serves as an organizational unit of Python code.  Modules
@@ -630,7 +637,7 @@ Glossary
 
    module spec
       A namespace containing the import-related information used to load a
-      module.
+      module. An instance of :class:`importlib.machinery.ModuleSpec`.
 
    MRO
       See :term:`method resolution order`.
@@ -757,6 +764,9 @@ Glossary
       (i.e. a :term:`path entry hook`) which knows how to locate modules given
       a :term:`path entry`.
 
+      See :class:`importlib.abc.PathEntryFinder` for the methods that path entry
+      finders implement.
+
    path entry hook
       A callable on the :data:`sys.path_hook` list which returns a :term:`path
       entry finder` if it knows how to find modules on a specific :term:`path
index 510d1d4..cfe9868 100644 (file)
@@ -511,7 +511,7 @@ to count the number of occurrences of a specific optional arguments:
 
 * Sadly, our help output isn't very informative on the new ability our script
   has acquired, but that can always be fixed by improving the documentation for
-  out script (e.g. via the ``help`` keyword argument).
+  our script (e.g. via the ``help`` keyword argument).
 
 * That last output exposes a bug in our program.
 
index d7a7086..27e7e6f 100644 (file)
@@ -161,7 +161,7 @@ simple example demonstrates how. ::
 
    #define INITERROR return NULL
 
-   PyObject *
+   PyMODINIT_FUNC
    PyInit_myextension(void)
 
    #else
index 87a5cab..188a5cf 100644 (file)
@@ -545,7 +545,7 @@ learn more about submitting patches to Python.
   a lengthy tutorial for C programmers.
 * `The ncurses man page <http://linux.die.net/man/3/ncurses>`_
 * `The ncurses FAQ <http://invisible-island.net/ncurses/ncurses.faq.html>`_
-* `"Use curses... don't swear" <http://www.youtube.com/watch?v=eN1eZtjLEnU>`_:
+* `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_:
   video of a PyCon 2013 talk on controlling terminals using curses or Urwid.
 * `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_:
   video of a PyCon CA 2012 talk demonstrating some applications written using
index 530f34b..d370eb5 100644 (file)
@@ -104,7 +104,7 @@ like::
         "Emulate type_getattro() in Objects/typeobject.c"
         v = object.__getattribute__(self, key)
         if hasattr(v, '__get__'):
-           return v.__get__(None, self)
+            return v.__get__(None, self)
         return v
 
 The important points to remember are:
@@ -163,9 +163,9 @@ descriptor is useful for monitoring just a few chosen attributes::
             self.val = val
 
     >>> class MyClass(object):
-        x = RevealAccess(10, 'var "x"')
-        y = 5
-
+    ...     x = RevealAccess(10, 'var "x"')
+    ...     y = 5
+    ...
     >>> m = MyClass()
     >>> m.x
     Retrieving var "x"
@@ -287,15 +287,15 @@ this::
 Running the interpreter shows how the function descriptor works in practice::
 
     >>> class D(object):
-         def f(self, x):
-              return x
-
+    ...     def f(self, x):
+    ...         return x
+    ...
     >>> d = D()
-    >>> D.__dict__['f'] # Stored internally as a function
+    >>> D.__dict__['f']  # Stored internally as a function
     <function f at 0x00C45070>
-    >>> D.f             # Get from a class becomes an unbound method
+    >>> D.f              # Get from a class becomes an unbound method
     <unbound method D.f>
-    >>> d.f             # Get from an instance becomes a bound method
+    >>> d.f              # Get from an instance becomes a bound method
     <bound method D.f of <__main__.D object at 0x00B18C90>>
 
 The output suggests that bound and unbound methods are two different types.
@@ -358,10 +358,10 @@ Since staticmethods return the underlying function with no changes, the example
 calls are unexciting::
 
     >>> class E(object):
-         def f(x):
-              print(x)
-         f = staticmethod(f)
-
+    ...     def f(x):
+    ...         print(x)
+    ...     f = staticmethod(f)
+    ...
     >>> print(E.f(3))
     3
     >>> print(E().f(3))
@@ -371,23 +371,23 @@ Using the non-data descriptor protocol, a pure Python version of
 :func:`staticmethod` would look like this::
 
     class StaticMethod(object):
-     "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
+        "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
 
-     def __init__(self, f):
-          self.f = f
+        def __init__(self, f):
+            self.f = f
 
-     def __get__(self, obj, objtype=None):
-          return self.f
+        def __get__(self, obj, objtype=None):
+            return self.f
 
 Unlike static methods, class methods prepend the class reference to the
 argument list before calling the function.  This format is the same
 for whether the caller is an object or a class::
 
     >>> class E(object):
-         def f(klass, x):
-              return klass.__name__, x
-         f = classmethod(f)
-
+    ...     def f(klass, x):
+    ...         return klass.__name__, x
+    ...     f = classmethod(f)
+    ...
     >>> print(E.f(3))
     ('E', 3)
     >>> print(E().f(3))
@@ -419,15 +419,15 @@ Using the non-data descriptor protocol, a pure Python version of
 :func:`classmethod` would look like this::
 
     class ClassMethod(object):
-         "Emulate PyClassMethod_Type() in Objects/funcobject.c"
+        "Emulate PyClassMethod_Type() in Objects/funcobject.c"
 
-         def __init__(self, f):
-              self.f = f
+        def __init__(self, f):
+            self.f = f
 
-         def __get__(self, obj, klass=None):
-              if klass is None:
-                   klass = type(obj)
-              def newfunc(*args):
-                   return self.f(klass, *args)
-              return newfunc
+        def __get__(self, obj, klass=None):
+            if klass is None:
+                klass = type(obj)
+            def newfunc(*args):
+                return self.f(klass, *args)
+            return newfunc
 
index 945a240..6e21f93 100644 (file)
@@ -332,7 +332,7 @@ substring.
 
 List comprehensions and generator expressions (short form: "listcomps" and
 "genexps") are a concise notation for such operations, borrowed from the
-functional programming language Haskell (http://www.haskell.org/).  You can strip
+functional programming language Haskell (https://www.haskell.org/).  You can strip
 all the whitespace from a stream of strings with the following code::
 
     line_list = ['  line 1\n', 'line 2  \n', ...]
@@ -395,14 +395,14 @@ equivalent to the following Python code::
             continue   # Skip this element
         for expr2 in sequence2:
             if not (condition2):
-                continue    # Skip this element
+                continue   # Skip this element
             ...
             for exprN in sequenceN:
-                 if not (conditionN):
-                     continue   # Skip this element
+                if not (conditionN):
+                    continue   # Skip this element
 
-                 # Output the value of
-                 # the expression.
+                # Output the value of
+                # the expression.
 
 This means that when there are multiple ``for...in`` clauses but no ``if``
 clauses, the length of the resulting output will be equal to the product of the
@@ -716,7 +716,7 @@ returns them in a tuple::
 It doesn't construct an in-memory list and exhaust all the input iterators
 before returning; instead tuples are constructed and returned only if they're
 requested.  (The technical term for this behaviour is `lazy evaluation
-<http://en.wikipedia.org/wiki/Lazy_evaluation>`__.)
+<https://en.wikipedia.org/wiki/Lazy_evaluation>`__.)
 
 This iterator is intended to be used with iterables that are all of the same
 length.  If the iterables are of different lengths, the resulting stream will be
@@ -1199,7 +1199,7 @@ General
 
 **Structure and Interpretation of Computer Programs**, by Harold Abelson and
 Gerald Jay Sussman with Julie Sussman.  Full text at
-http://mitpress.mit.edu/sicp/.  In this classic textbook of computer science,
+https://mitpress.mit.edu/sicp/.  In this classic textbook of computer science,
 chapters 2 and 3 discuss the use of sequences and streams to organize the data
 flow inside a program.  The book uses Scheme for its examples, but many of the
 design approaches described in these chapters are applicable to functional-style
@@ -1208,12 +1208,12 @@ Python code.
 http://www.defmacro.org/ramblings/fp.html: A general introduction to functional
 programming that uses Java examples and has a lengthy historical introduction.
 
-http://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry
+https://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry
 describing functional programming.
 
-http://en.wikipedia.org/wiki/Coroutine: Entry for coroutines.
+https://en.wikipedia.org/wiki/Coroutine: Entry for coroutines.
 
-http://en.wikipedia.org/wiki/Currying: Entry for the concept of currying.
+https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying.
 
 Python-specific
 ---------------
@@ -1225,9 +1225,9 @@ Text Processing".
 
 Mertz also wrote a 3-part series of articles on functional programming
 for IBM's DeveloperWorks site; see
-`part 1 <http://www.ibm.com/developerworks/linux/library/l-prog/index.html>`__,
-`part 2 <http://www.ibm.com/developerworks/linux/library/l-prog2/index.html>`__, and
-`part 3 <http://www.ibm.com/developerworks/linux/library/l-prog3/index.html>`__,
+`part 1 <https://www.ibm.com/developerworks/linux/library/l-prog/index.html>`__,
+`part 2 <https://www.ibm.com/developerworks/linux/library/l-prog2/index.html>`__, and
+`part 3 <https://www.ibm.com/developerworks/linux/library/l-prog3/index.html>`__,
 
 
 Python documentation
index 2c9d699..de65950 100644 (file)
@@ -25,7 +25,6 @@ Currently, the HOWTOs are:
    sorting.rst
    unicode.rst
    urllib2.rst
-   webservers.rst
    argparse.rst
    ipaddress.rst
    clinic.rst
index b979aa7..99b4cdc 100644 (file)
@@ -63,6 +63,7 @@ Here is the auxiliary module::
         def __init__(self):
             self.logger = logging.getLogger('spam_application.auxiliary.Auxiliary')
             self.logger.info('creating an instance of Auxiliary')
+
         def do_something(self):
             self.logger.info('doing something')
             a = 1 + 1
@@ -94,6 +95,61 @@ The output looks like this::
     2005-03-23 23:47:11,673 - spam_application - INFO -
        done with auxiliary_module.some_function()
 
+Logging from multiple threads
+-----------------------------
+
+Logging from multiple threads requires no special effort. The following example
+shows logging from the main (initial) thread and another thread::
+
+    import logging
+    import threading
+    import time
+
+    def worker(arg):
+        while not arg['stop']:
+            logging.debug('Hi from myfunc')
+            time.sleep(0.5)
+
+    def main():
+        logging.basicConfig(level=logging.DEBUG, format='%(relativeCreated)6d %(threadName)s %(message)s')
+        info = {'stop': False}
+        thread = threading.Thread(target=worker, args=(info,))
+        thread.start()
+        while True:
+            try:
+                logging.debug('Hello from main')
+                time.sleep(0.75)
+            except KeyboardInterrupt:
+                info['stop'] = True
+                break
+        thread.join()
+
+    if __name__ == '__main__':
+        main()
+
+When run, the script should print something like the following::
+
+     0 Thread-1 Hi from myfunc
+     3 MainThread Hello from main
+   505 Thread-1 Hi from myfunc
+   755 MainThread Hello from main
+  1007 Thread-1 Hi from myfunc
+  1507 MainThread Hello from main
+  1508 Thread-1 Hi from myfunc
+  2010 Thread-1 Hi from myfunc
+  2258 MainThread Hello from main
+  2512 Thread-1 Hi from myfunc
+  3009 MainThread Hello from main
+  3013 Thread-1 Hi from myfunc
+  3515 Thread-1 Hi from myfunc
+  3761 MainThread Hello from main
+  4017 Thread-1 Hi from myfunc
+  4513 MainThread Hello from main
+  4518 Thread-1 Hi from myfunc
+
+This shows the logging output interspersed as one might expect. This approach
+works for more threads than shown here, of course.
+
 Multiple handlers and formatters
 --------------------------------
 
@@ -305,7 +361,7 @@ classes, which would eat up one thread per handler for no particular benefit.
 
 An example of using these two classes follows (imports omitted)::
 
-    que = queue.Queue(-1) # no limit on size
+    que = queue.Queue(-1)  # no limit on size
     queue_handler = QueueHandler(que)
     handler = logging.StreamHandler()
     listener = QueueListener(que, handler)
@@ -601,21 +657,21 @@ script::
             return True
 
     if __name__ == '__main__':
-       levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
-       logging.basicConfig(level=logging.DEBUG,
-                           format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
-       a1 = logging.getLogger('a.b.c')
-       a2 = logging.getLogger('d.e.f')
-
-       f = ContextFilter()
-       a1.addFilter(f)
-       a2.addFilter(f)
-       a1.debug('A debug message')
-       a1.info('An info message with %s', 'some parameters')
-       for x in range(10):
-           lvl = choice(levels)
-           lvlname = logging.getLevelName(lvl)
-           a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
+        levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
+        logging.basicConfig(level=logging.DEBUG,
+                            format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
+        a1 = logging.getLogger('a.b.c')
+        a2 = logging.getLogger('d.e.f')
+
+        f = ContextFilter()
+        a1.addFilter(f)
+        a2.addFilter(f)
+        a1.debug('A debug message')
+        a1.info('An info message with %s', 'some parameters')
+        for x in range(10):
+            lvl = choice(levels)
+            lvlname = logging.getLevelName(lvl)
+            a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
 
 which, when run, produces something like::
 
@@ -709,10 +765,10 @@ the basis for code meeting your own specific requirements::
         while True:
             try:
                 record = queue.get()
-                if record is None: # We send this as a sentinel to tell the listener to quit.
+                if record is None:  # We send this as a sentinel to tell the listener to quit.
                     break
                 logger = logging.getLogger(record.name)
-                logger.handle(record) # No level or filter logic applied - just do it!
+                logger.handle(record)  # No level or filter logic applied - just do it!
             except Exception:
                 import sys, traceback
                 print('Whoops! Problem:', file=sys.stderr)
@@ -735,10 +791,11 @@ the basis for code meeting your own specific requirements::
     # Note that on Windows you can't rely on fork semantics, so each process
     # will run the logging configuration code when it starts.
     def worker_configurer(queue):
-        h = logging.handlers.QueueHandler(queue) # Just the one handler needed
+        h = logging.handlers.QueueHandler(queue)  # Just the one handler needed
         root = logging.getLogger()
         root.addHandler(h)
-        root.setLevel(logging.DEBUG) # send all messages, for demo; no other level or filter logic applied.
+        # send all messages, for demo; no other level or filter logic applied.
+        root.setLevel(logging.DEBUG)
 
     # This is the worker process top-level loop, which just logs ten events with
     # random intervening delays before terminating.
@@ -766,7 +823,7 @@ the basis for code meeting your own specific requirements::
         workers = []
         for i in range(10):
             worker = multiprocessing.Process(target=worker_process,
-                                           args=(queue, worker_configurer))
+                                             args=(queue, worker_configurer))
             workers.append(worker)
             worker.start()
         for w in workers:
@@ -1190,12 +1247,12 @@ You can use a :class:`QueueHandler` subclass to send messages to other kinds
 of queues, for example a ZeroMQ 'publish' socket. In the example below,the
 socket is created separately and passed to the handler (as its 'queue')::
 
-    import zmq # using pyzmq, the Python binding for ZeroMQ
-    import json # for serializing records portably
+    import zmq   # using pyzmq, the Python binding for ZeroMQ
+    import json  # for serializing records portably
 
     ctx = zmq.Context()
-    sock = zmq.Socket(ctx, zmq.PUB) # or zmq.PUSH, or other suitable value
-    sock.bind('tcp://*:5556') # or wherever
+    sock = zmq.Socket(ctx, zmq.PUB)  # or zmq.PUSH, or other suitable value
+    sock.bind('tcp://*:5556')        # or wherever
 
     class ZeroMQSocketHandler(QueueHandler):
         def enqueue(self, record):
@@ -1233,7 +1290,7 @@ of queues, for example a ZeroMQ 'subscribe' socket. Here's an example::
         def __init__(self, uri, *handlers, **kwargs):
             self.ctx = kwargs.get('ctx') or zmq.Context()
             socket = zmq.Socket(self.ctx, zmq.SUB)
-            socket.setsockopt(zmq.SUBSCRIBE, '') # subscribe to everything
+            socket.setsockopt(zmq.SUBSCRIBE, '')  # subscribe to everything
             socket.connect(uri)
 
         def dequeue(self):
@@ -1261,7 +1318,7 @@ An example dictionary-based configuration
 -----------------------------------------
 
 Below is an example of a logging configuration dictionary - it's taken from
-the `documentation on the Django project <https://docs.djangoproject.com/en/1.3/topics/logging/#configuring-logging>`_.
+the `documentation on the Django project <https://docs.djangoproject.com/en/1.9/topics/logging/#configuring-logging>`_.
 This dictionary is passed to :func:`~config.dictConfig` to put the configuration into effect::
 
     LOGGING = {
@@ -1317,7 +1374,7 @@ This dictionary is passed to :func:`~config.dictConfig` to put the configuration
     }
 
 For more information about this configuration, you can see the `relevant
-section <https://docs.djangoproject.com/en/1.6/topics/logging/#configuring-logging>`_
+section <https://docs.djangoproject.com/en/1.9/topics/logging/#configuring-logging>`_
 of the Django documentation.
 
 .. _cookbook-rotator-namer:
@@ -1579,11 +1636,11 @@ works::
 Inserting a BOM into messages sent to a SysLogHandler
 -----------------------------------------------------
 
-`RFC 5424 <http://tools.ietf.org/html/rfc5424>`_ requires that a
+`RFC 5424 <https://tools.ietf.org/html/rfc5424>`_ 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 <http://tools.ietf.org/html/rfc5424#section-6>`_.)
+section of the specification <https://tools.ietf.org/html/rfc5424#section-6>`_.)
 
 In Python 3.1, code was added to
 :class:`~logging.handlers.SysLogHandler` to insert a BOM into the message, but
@@ -2061,7 +2118,7 @@ class, as shown in the following example::
             Format an exception so that it prints on a single line.
             """
             result = super(OneLineExceptionFormatter, self).formatException(exc_info)
-            return repr(result) # or format into one line however you want to
+            return repr(result)  # or format into one line however you want to
 
         def format(self, record):
             s = super(OneLineExceptionFormatter, self).format(record)
@@ -2176,7 +2233,7 @@ flushing behavior.
 
 The example script has a simple function, ``foo``, which just cycles through
 all the logging levels, writing to ``sys.stderr`` to say what level it's about
-to log at, and then actually logging a message that that level. You can pass a
+to log at, and then actually logging a message at that level. You can pass a
 parameter to ``foo`` which, if true, will log at ERROR and CRITICAL levels -
 otherwise, it only logs at DEBUG, INFO and WARNING levels.
 
@@ -2354,3 +2411,105 @@ When this script is run, it should print something like::
 
 showing how the time is formatted both as local time and UTC, one for each
 handler.
+
+
+.. _context-manager:
+
+Using a context manager for selective logging
+---------------------------------------------
+
+There are times when it would be useful to temporarily change the logging
+configuration and revert it back after doing something. For this, a context
+manager is the most obvious way of saving and restoring the logging context.
+Here is a simple example of such a context manager, which allows you to
+optionally change the logging level and add a logging handler purely in the
+scope of the context manager::
+
+    import logging
+    import sys
+
+    class LoggingContext(object):
+        def __init__(self, logger, level=None, handler=None, close=True):
+            self.logger = logger
+            self.level = level
+            self.handler = handler
+            self.close = close
+
+        def __enter__(self):
+            if self.level is not None:
+                self.old_level = self.logger.level
+                self.logger.setLevel(self.level)
+            if self.handler:
+                self.logger.addHandler(self.handler)
+
+        def __exit__(self, et, ev, tb):
+            if self.level is not None:
+                self.logger.setLevel(self.old_level)
+            if self.handler:
+                self.logger.removeHandler(self.handler)
+            if self.handler and self.close:
+                self.handler.close()
+            # implicit return of None => don't swallow exceptions
+
+If you specify a level value, the logger's level is set to that value in the
+scope of the with block covered by the context manager. If you specify a
+handler, it is added to the logger on entry to the block and removed on exit
+from the block. You can also ask the manager to close the handler for you on
+block exit - you could do this if you don't need the handler any more.
+
+To illustrate how it works, we can add the following block of code to the
+above::
+
+    if __name__ == '__main__':
+        logger = logging.getLogger('foo')
+        logger.addHandler(logging.StreamHandler())
+        logger.setLevel(logging.INFO)
+        logger.info('1. This should appear just once on stderr.')
+        logger.debug('2. This should not appear.')
+        with LoggingContext(logger, level=logging.DEBUG):
+            logger.debug('3. This should appear once on stderr.')
+        logger.debug('4. This should not appear.')
+        h = logging.StreamHandler(sys.stdout)
+        with LoggingContext(logger, level=logging.DEBUG, handler=h, close=True):
+            logger.debug('5. This should appear twice - once on stderr and once on stdout.')
+        logger.info('6. This should appear just once on stderr.')
+        logger.debug('7. This should not appear.')
+
+We initially set the logger's level to ``INFO``, so message #1 appears and
+message #2 doesn't. We then change the level to ``DEBUG`` temporarily in the
+following ``with`` block, and so message #3 appears. After the block exits, the
+logger's level is restored to ``INFO`` and so message #4 doesn't appear. In the
+next ``with`` block, we set the level to ``DEBUG`` again but also add a handler
+writing to ``sys.stdout``. Thus, message #5 appears twice on the console (once
+via ``stderr`` and once via ``stdout``). After the ``with`` statement's
+completion, the status is as it was before so message #6 appears (like message
+#1) whereas message #7 doesn't (just like message #2).
+
+If we run the resulting script, the result is as follows::
+
+    $ python logctx.py
+    1. This should appear just once on stderr.
+    3. This should appear once on stderr.
+    5. This should appear twice - once on stderr and once on stdout.
+    5. This should appear twice - once on stderr and once on stdout.
+    6. This should appear just once on stderr.
+
+If we run it again, but pipe ``stderr`` to ``/dev/null``, we see the following,
+which is the only message written to ``stdout``::
+
+    $ python logctx.py 2>/dev/null
+    5. This should appear twice - once on stderr and once on stdout.
+
+Once again, but piping ``stdout`` to ``/dev/null``, we get::
+
+    $ python logctx.py >/dev/null
+    1. This should appear just once on stderr.
+    3. This should appear once on stderr.
+    5. This should appear twice - once on stderr and once on stdout.
+    6. This should appear just once on stderr.
+
+In this case, the message #5 printed to ``stdout`` doesn't appear, as expected.
+
+Of course, the approach described here can be generalised, for example to attach
+logging filters temporarily. Note that the above code works in Python 2 as well
+as Python 3.
index 4ce14f9..51e8430 100644 (file)
@@ -103,8 +103,8 @@ A simple example
 A very simple example is::
 
    import logging
-   logging.warning('Watch out!') # will print a message to the console
-   logging.info('I told you so') # will not print anything
+   logging.warning('Watch out!')  # will print a message to the console
+   logging.info('I told you so')  # will not print anything
 
 If you type these lines into a script and run it, you'll see::
 
@@ -310,7 +310,7 @@ favourite beverage and carry on.
 If your logging needs are simple, then use the above examples to incorporate
 logging into your own scripts, and if you run into problems or don't
 understand something, please post a question on the comp.lang.python Usenet
-group (available at http://groups.google.com/group/comp.lang.python) and you
+group (available at https://groups.google.com/group/comp.lang.python) and you
 should receive help before too long.
 
 Still here? You can carry on reading the next few sections, which provide a
index a2aaf36..c479f22 100644 (file)
@@ -243,8 +243,8 @@ bothered to add the ``b`` mode when opening a binary file (e.g., ``rb`` for
 binary reading).  Under Python 3, binary files and text files are clearly
 distinct and mutually incompatible; see the :mod:`io` module for details.
 Therefore, you **must** make a decision of whether a file will be used for
-binary access (allowing to read and/or write binary data) or text access
-(allowing to read and/or write text data). You should also use :func:`io.open`
+binary access (allowing binary data to be read and/or written) or text access
+(allowing text data to be read and/or written). You should also use :func:`io.open`
 for opening files instead of the built-in :func:`open` function as the :mod:`io`
 module is consistent from Python 2 to 3 while the built-in :func:`open` function
 is not (in Python 3 it's actually :func:`io.open`).
@@ -282,6 +282,50 @@ To summarize:
    appropriate
 #. Be careful when indexing binary data
 
+
+Use feature detection instead of version detection
+++++++++++++++++++++++++++++++++++++++++++++++++++
+Inevitably you will have code that has to choose what to do based on what
+version of Python is running. The best way to do this is with feature detection
+of whether the version of Python you're running under supports what you need.
+If for some reason that doesn't work then you should make the version check is
+against Python 2 and not Python 3. To help explain this, let's look at an
+example.
+
+Let's pretend that you need access to a feature of importlib_ that
+is available in Python's standard library since Python 3.3 and available for
+Python 2 through importlib2_ on PyPI. You might be tempted to write code to
+access e.g. the ``importlib.abc`` module by doing the following::
+
+  import sys
+
+  if sys.version[0] == 3:
+      from importlib import abc
+  else:
+      from importlib2 import abc
+
+The problem with this code is what happens when Python 4 comes out? It would
+be better to treat Python 2 as the exceptional case instead of Python 3 and
+assume that future Python versions will be more compatible with Python 3 than
+Python 2::
+
+  import sys
+
+  if sys.version[0] > 2:
+      from importlib import abc
+  else:
+      from importlib2 import abc
+
+The best solution, though, is to do no version detection at all and instead rely
+on feature detection. That avoids any potential issues of getting the version
+detection wrong and helps keep you future-compatible::
+
+  try:
+      from importlib import abc
+  except ImportError:
+      from importlib2 import abc
+
+
 Prevent compatibility regressions
 ---------------------------------
 
@@ -346,7 +390,7 @@ your tests under multiple Python interpreters is tox_. You can then integrate
 tox with your continuous integration system so that you never accidentally break
 Python 2 or 3 support.
 
-You may also want to use use the ``-bb`` flag with the Python 3 interpreter to
+You may also want to use the ``-bb`` flag with the Python 3 interpreter to
 trigger an exception when you are comparing bytes to strings or bytes to an int
 (the latter is available starting in Python 3.5). By default type-differing
 comparisons simply return ``False``, but if you made a mistake in your
@@ -381,10 +425,12 @@ supported by Python 2. You should also update the classifiers in your
 .. _cheat sheet: http://python-future.org/compatible_idioms.html
 .. _coverage.py: https://pypi.python.org/pypi/coverage
 .. _Futurize: http://python-future.org/automatic_conversion.html
-.. _Modernize: http://python-modernize.readthedocs.org/en/latest/
+.. _importlib: https://docs.python.org/3/library/importlib.html#module-importlib
+.. _importlib2: https://pypi.python.org/pypi/importlib2
+.. _Modernize: https://python-modernize.readthedocs.org/en/latest/
 .. _Porting to Python 3: http://python3porting.com/
 .. _Pylint: https://pypi.python.org/pypi/pylint
-.. _Python 3 Q & A: http://ncoghlan-devs-python-notes.readthedocs.org/en/latest/python3/questions_and_answers.html
+.. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.org/en/latest/python3/questions_and_answers.html
 
 .. _python-future: http://python-future.org/
 .. _python-porting: https://mail.python.org/mailman/listinfo/python-porting
index ad2c6ab..de3f461 100644 (file)
@@ -178,7 +178,7 @@ are usually not written to match that much data.
 Repetitions such as ``*`` are :dfn:`greedy`; when repeating a RE, the matching
 engine will try to repeat it as many times as possible. If later portions of the
 pattern don't match, the matching engine will then back up and try again with
-few repetitions.
+fewer repetitions.
 
 A step-by-step example will make this more obvious.  Let's consider the
 expression ``a[bcd]*b``.  This matches the letter ``'a'``, zero or more letters
@@ -1004,17 +1004,18 @@ confusing.
 
 A negative lookahead cuts through all this confusion:
 
-``.*[.](?!bat$).*$``  The negative lookahead means: if the expression ``bat``
+``.*[.](?!bat$)[^.]*$``  The negative lookahead means: if the expression ``bat``
 doesn't match at this point, try the rest of the pattern; if ``bat$`` does
 match, the whole pattern will fail.  The trailing ``$`` is required to ensure
 that something like ``sample.batch``, where the extension only starts with
-``bat``, will be allowed.
+``bat``, will be allowed.  The ``[^.]*`` makes sure that the pattern works
+when there are multiple dots in the filename.
 
 Excluding another filename extension is now easy; simply add it as an
 alternative inside the assertion.  The following pattern excludes filenames that
 end in either ``bat`` or ``exe``:
 
-``.*[.](?!bat$|exe$).*$``
+``.*[.](?!bat$|exe$)[^.]*$``
 
 
 Modifying Strings
@@ -1114,19 +1115,19 @@ which can be either a string or a function, and the string to be processed.
 Here's a simple example of using the :meth:`sub` method.  It replaces colour
 names with the word ``colour``::
 
-   >>> p = re.compile( '(blue|white|red)')
-   >>> p.sub( 'colour', 'blue socks and red shoes')
+   >>> p = re.compile('(blue|white|red)')
+   >>> p.sub('colour', 'blue socks and red shoes')
    'colour socks and colour shoes'
-   >>> p.sub( 'colour', 'blue socks and red shoes', count=1)
+   >>> p.sub('colour', 'blue socks and red shoes', count=1)
    'colour socks and red shoes'
 
 The :meth:`subn` method does the same work, but returns a 2-tuple containing the
 new string value and the number of replacements  that were performed::
 
-   >>> p = re.compile( '(blue|white|red)')
-   >>> p.subn( 'colour', 'blue socks and red shoes')
+   >>> p = re.compile('(blue|white|red)')
+   >>> p.subn('colour', 'blue socks and red shoes')
    ('colour socks and colour shoes', 2)
-   >>> p.subn( 'colour', 'no colours at all')
+   >>> p.subn('colour', 'no colours at all')
    ('no colours at all', 0)
 
 Empty matches are replaced only when they're not adjacent to a previous match.
index f2e64ee..0334b26 100644 (file)
@@ -127,7 +127,7 @@ Sort Stability and Complex Sorts
 ================================
 
 Sorts are guaranteed to be `stable
-<http://en.wikipedia.org/wiki/Sorting_algorithm#Stability>`_\. That means that
+<https://en.wikipedia.org/wiki/Sorting_algorithm#Stability>`_\. That means that
 when multiple records have the same key, their original order is preserved.
 
     >>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
@@ -145,7 +145,7 @@ ascending *age*, do the *age* sort first and then sort again using *grade*:
     >>> sorted(s, key=attrgetter('grade'), reverse=True)       # now sort on primary key, descending
     [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
 
-The `Timsort <http://en.wikipedia.org/wiki/Timsort>`_ algorithm used in Python
+The `Timsort <https://en.wikipedia.org/wiki/Timsort>`_ algorithm used in Python
 does multiple sorts efficiently because it can take advantage of any ordering
 already present in a dataset.
 
@@ -184,7 +184,7 @@ decorated list, but including it gives two benefits:
   directly.
 
 Another name for this idiom is
-`Schwartzian transform <http://en.wikipedia.org/wiki/Schwartzian_transform>`_\,
+`Schwartzian transform <https://en.wikipedia.org/wiki/Schwartzian_transform>`_\,
 after Randal L. Schwartz, who popularized it among Perl programmers.
 
 Now that Python sorting provides key-functions, this technique is not often needed.
@@ -262,7 +262,11 @@ Odd and Ends
   twice:
 
     >>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
-    >>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))
+    >>> standard_way = sorted(data, key=itemgetter(0), reverse=True)
+    >>> double_reversed = list(reversed(sorted(reversed(data), key=itemgetter(0))))
+    >>> assert standard_way == double_reversed
+    >>> standard_way
+    [('red', 1), ('red', 2), ('blue', 1), ('blue', 2)]
 
 * The sort routines are guaranteed to use :meth:`__lt__` when making comparisons
   between two objects. So, it is easy to add a standard sort order to a class by
index ee31a9c..50a09ba 100644 (file)
@@ -73,7 +73,7 @@ revision of Unicode.
 precise historical details aren't necessary for understanding how to
 use Unicode effectively, but if you're curious, consult the Unicode
 consortium site listed in the References or
-the `Wikipedia entry for Unicode <http://en.wikipedia.org/wiki/Unicode#History>`_
+the `Wikipedia entry for Unicode <https://en.wikipedia.org/wiki/Unicode#History>`_
 for more information.)
 
 
@@ -214,7 +214,7 @@ difficult reading.  `A chronology <http://www.unicode.org/history/>`_ of the
 origin and development of Unicode is also available on the site.
 
 To help understand the standard, Jukka Korpela has written `an introductory
-guide <http://www.cs.tut.fi/~jkorpela/unicode/guide.html>`_ to reading the
+guide <https://www.cs.tut.fi/~jkorpela/unicode/guide.html>`_ to reading the
 Unicode character tables.
 
 Another `good introductory article <http://www.joelonsoftware.com/articles/Unicode.html>`_
@@ -223,8 +223,8 @@ If this introduction didn't make things clear to you, you should try
 reading this alternate article before continuing.
 
 Wikipedia entries are often helpful; see the entries for "`character encoding
-<http://en.wikipedia.org/wiki/Character_encoding>`_" and `UTF-8
-<http://en.wikipedia.org/wiki/UTF-8>`_, for example.
+<https://en.wikipedia.org/wiki/Character_encoding>`_" and `UTF-8
+<https://en.wikipedia.org/wiki/UTF-8>`_, for example.
 
 
 Python's Unicode Support
@@ -297,9 +297,6 @@ The following examples show the differences::
     >>> b'\x80abc'.decode("utf-8", "ignore")
     'abc'
 
-(In this code example, the Unicode replacement character has been replaced by
-a question mark because it may not be displayed on some systems.)
-
 Encodings are specified as strings containing the encoding's name.  Python 3.2
 comes with roughly 100 different encodings; see the Python Library Reference at
 :ref:`standard-encodings` for a list.  Some encodings have multiple names; for
@@ -690,7 +687,7 @@ with the ``surrogateescape`` error handler::
    # make changes to the string 'data'
 
    with open(fname + '.new', 'w',
-              encoding="ascii", errors="surrogateescape") as f:
+             encoding="ascii", errors="surrogateescape") as f:
        f.write(data)
 
 The ``surrogateescape`` error handler will decode any non-ASCII bytes
index e3d7714..24a4156 100644 (file)
@@ -64,7 +64,7 @@ you can do so via the :func:`~urllib.request.urlretrieve` function::
     html = open(local_filename)
 
 Many uses of urllib will be that simple (note that instead of an 'http:' URL we
-could have used an URL starting with 'ftp:', 'file:', etc.).  However, it's the
+could have used a URL starting with 'ftp:', 'file:', etc.).  However, it's the
 purpose of this tutorial to explain the more complicated cases, concentrating on
 HTTP.
 
@@ -115,14 +115,14 @@ library. ::
               'language' : 'Python' }
 
     data = urllib.parse.urlencode(values)
-    data = data.encode('utf-8') # data should be bytes
+    data = data.encode('ascii') # data should be bytes
     req = urllib.request.Request(url, data)
     with urllib.request.urlopen(req) as response:
        the_page = response.read()
 
 Note that other encodings are sometimes required (e.g. for file upload from HTML
 forms - see `HTML Specification, Form Submission
-<http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13>`_ for more
+<https://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13>`_ for more
 details).
 
 If you do not pass the ``data`` argument, urllib uses a **GET** request. One
@@ -175,13 +175,13 @@ Explorer [#]_. ::
 
     url = 'http://www.someserver.com/cgi-bin/register.cgi'
     user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'
-    values = {'name' : 'Michael Foord',
-              'location' : 'Northampton',
-              'language' : 'Python' }
-    headers = { 'User-Agent' : user_agent }
+    values = {'name': 'Michael Foord',
+              'location': 'Northampton',
+              'language': 'Python' }
+    headers = {'User-Agent': user_agent}
 
-    data  = urllib.parse.urlencode(values)
-    data = data.encode('utf-8')
+    data = urllib.parse.urlencode(values)
+    data = data.encode('ascii')
     req = urllib.request.Request(url, data, headers)
     with urllib.request.urlopen(req) as response:
        the_page = response.read()
@@ -215,7 +215,7 @@ e.g. ::
     >>> req = urllib.request.Request('http://www.pretend_server.org')
     >>> try: urllib.request.urlopen(req)
     ... except urllib.error.URLError as e:
-    ...    print(e.reason)      #doctest: +SKIP
+    ...     print(e.reason)      #doctest: +SKIP
     ...
     (4, 'getaddrinfo failed')
 
@@ -372,7 +372,7 @@ Number 2
 ::
 
     from urllib.request import Request, urlopen
-    from urllib.error import  URLError
+    from urllib.error import URLError
     req = Request(someurl)
     try:
         response = urlopen(req)
@@ -403,7 +403,7 @@ fetched, particularly the headers sent by the server. It is currently an
 :class:`http.client.HTTPMessage` instance.
 
 Typical headers include 'Content-length', 'Content-type', and so on. See the
-`Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_
+`Quick Reference to HTTP Headers <https://www.cs.tut.fi/~jkorpela/http.html>`_
 for a useful listing of HTTP headers with brief explanations of their meaning
 and use.
 
@@ -514,7 +514,7 @@ component and the hostname and optionally the port number)
 e.g. "http://example.com/" *or* an "authority" (i.e. the hostname,
 optionally including the port number) e.g. "example.com" or "example.com:8080"
 (the latter example includes a port number).  The authority, if present, must
-NOT contain the "userinfo" component - for example "joe@password:example.com" is
+NOT contain the "userinfo" component - for example "joe:password@example.com" is
 not correct.
 
 
@@ -586,5 +586,5 @@ This document was reviewed and revised by John Lee.
        scripts with a localhost server, I have to prevent urllib from using
        the proxy.
 .. [#] urllib opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe
-       <http://code.activestate.com/recipes/456195/>`_.
+       <https://code.activestate.com/recipes/456195/>`_.
 
diff --git a/Doc/howto/webservers.rst b/Doc/howto/webservers.rst
deleted file mode 100644 (file)
index 9e9b69d..0000000
+++ /dev/null
@@ -1,731 +0,0 @@
-*******************************
-  HOWTO Use Python in the web
-*******************************
-
-:Author: Marek Kubica
-
-.. topic:: Abstract
-
-   This document shows how Python fits into the web.  It presents some ways
-   to integrate Python with a web server, and general practices useful for
-   developing web sites.
-
-
-Programming for the Web has become a hot topic since the rise of "Web 2.0",
-which focuses on user-generated content on web sites.  It has always been
-possible to use Python for creating web sites, but it was a rather tedious task.
-Therefore, many frameworks and helper tools have been created to assist
-developers in creating faster and more robust sites.  This HOWTO describes
-some of the methods used to combine Python with a web server to create
-dynamic content.  It is not meant as a complete introduction, as this topic is
-far too broad to be covered in one single document.  However, a short overview
-of the most popular libraries is provided.
-
-.. seealso::
-
-   While this HOWTO tries to give an overview of Python in the web, it cannot
-   always be as up to date as desired.  Web development in Python is rapidly
-   moving forward, so the wiki page on `Web Programming
-   <https://wiki.python.org/moin/WebProgramming>`_ may be more in sync with
-   recent development.
-
-
-The Low-Level View
-==================
-
-When a user enters a web site, their browser makes a connection to the site's
-web server (this is called the *request*).  The server looks up the file in the
-file system and sends it back to the user's browser, which displays it (this is
-the *response*).  This is roughly how the underlying protocol, HTTP, works.
-
-Dynamic web sites are not based on files in the file system, but rather on
-programs which are run by the web server when a request comes in, and which
-*generate* the content that is returned to the user.  They can do all sorts of
-useful things, like display the postings of a bulletin board, show your email,
-configure software, or just display the current time.  These programs can be
-written in any programming language the server supports.  Since most servers
-support Python, it is easy to use Python to create dynamic web sites.
-
-Most HTTP servers are written in C or C++, so they cannot execute Python code
-directly -- a bridge is needed between the server and the program.  These
-bridges, or rather interfaces, define how programs interact with the server.
-There have been numerous attempts to create the best possible interface, but
-there are only a few worth mentioning.
-
-Not every web server supports every interface.  Many web servers only support
-old, now-obsolete interfaces; however, they can often be extended using
-third-party modules to support newer ones.
-
-
-Common Gateway Interface
-------------------------
-
-This interface, most commonly referred to as "CGI", is the oldest, and is
-supported by nearly every web server out of the box.  Programs using CGI to
-communicate with their web server need to be started by the server for every
-request.  So, every request starts a new Python interpreter -- which takes some
-time to start up -- thus making the whole interface only usable for low load
-situations.
-
-The upside of CGI is that it is simple -- writing a Python program which uses
-CGI is a matter of about three lines of code.  This simplicity comes at a
-price: it does very few things to help the developer.
-
-Writing CGI programs, while still possible, is no longer recommended.  With
-:ref:`WSGI <WSGI>`, a topic covered later in this document, it is possible to write
-programs that emulate CGI, so they can be run as CGI if no better option is
-available.
-
-.. seealso::
-
-   The Python standard library includes some modules that are helpful for
-   creating plain CGI programs:
-
-   * :mod:`cgi` -- Handling of user input in CGI scripts
-   * :mod:`cgitb` -- Displays nice tracebacks when errors happen in CGI
-     applications, instead of presenting a "500 Internal Server Error" message
-
-   The Python wiki features a page on `CGI scripts
-   <https://wiki.python.org/moin/CgiScripts>`_ with some additional information
-   about CGI in Python.
-
-
-Simple script for testing CGI
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To test whether your web server works with CGI, you can use this short and
-simple CGI program::
-
-    #!/usr/bin/env python
-    # -*- coding: UTF-8 -*-
-
-    # enable debugging
-    import cgitb
-    cgitb.enable()
-
-    print("Content-Type: text/plain;charset=utf-8")
-    print()
-
-    print("Hello World!")
-
-Depending on your web server configuration, you may need to save this code with
-a ``.py`` or ``.cgi`` extension.  Additionally, this file may also need to be
-in a ``cgi-bin`` folder, for security reasons.
-
-You might wonder what the ``cgitb`` line is about.  This line makes it possible
-to display a nice traceback instead of just crashing and displaying an "Internal
-Server Error" in the user's browser.  This is useful for debugging, but it might
-risk exposing some confidential data to the user.  You should not use ``cgitb``
-in production code for this reason.  You should *always* catch exceptions, and
-display proper error pages -- end-users don't like to see nondescript "Internal
-Server Errors" in their browsers.
-
-
-Setting up CGI on your own server
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If you don't have your own web server, this does not apply to you.  You can
-check whether it works as-is, and if not you will need to talk to the
-administrator of your web server. If it is a big host, you can try filing a
-ticket asking for Python support.
-
-If you are your own administrator or want to set up CGI for testing purposes on
-your own computers, you have to configure it by yourself.  There is no single
-way to configure CGI, as there are many web servers with different
-configuration options.  Currently the most widely used free web server is
-`Apache HTTPd <http://httpd.apache.org/>`_, or Apache for short. Apache can be
-easily installed on nearly every system using the system's package management
-tool.  `lighttpd <http://www.lighttpd.net>`_ is another alternative and is
-said to have better performance.  On many systems this server can also be
-installed using the package management tool, so manually compiling the web
-server may not be needed.
-
-* On Apache you can take a look at the `Dynamic Content with CGI
-  <http://httpd.apache.org/docs/2.2/howto/cgi.html>`_ tutorial, where everything
-  is described.  Most of the time it is enough just to set ``+ExecCGI``.  The
-  tutorial also describes the most common gotchas that might arise.
-
-* On lighttpd you need to use the `CGI module
-  <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModCGI>`_\ , which can be configured
-  in a straightforward way.  It boils down to setting ``cgi.assign`` properly.
-
-
-Common problems with CGI scripts
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Using CGI sometimes leads to small annoyances while trying to get these
-scripts to run.  Sometimes a seemingly correct script does not work as
-expected, the cause being some small hidden problem that's difficult to spot.
-
-Some of these potential problems are:
-
-* The Python script is not marked as executable.  When CGI scripts are not
-  executable most web servers will let the user download it, instead of
-  running it and sending the output to the user.  For CGI scripts to run
-  properly on Unix-like operating systems, the ``+x`` bit needs to be set.
-  Using ``chmod a+x your_script.py`` may solve this problem.
-
-* On a Unix-like system, The line endings in the program file must be Unix
-  style line endings.  This is important because the web server checks the
-  first line of the script (called shebang) and tries to run the program
-  specified there.  It gets easily confused by Windows line endings (Carriage
-  Return & Line Feed, also called CRLF), so you have to convert the file to
-  Unix line endings (only Line Feed, LF).  This can be done automatically by
-  uploading the file via FTP in text mode instead of binary mode, but the
-  preferred way is just telling your editor to save the files with Unix line
-  endings.  Most editors support this.
-
-* Your web server must be able to read the file, and you need to make sure the
-  permissions are correct.  On unix-like systems, the server often runs as user
-  and group ``www-data``, so it might be worth a try to change the file
-  ownership, or making the file world readable by using ``chmod a+r
-  your_script.py``.
-
-* The web server must know that the file you're trying to access is a CGI script.
-  Check the configuration of your web server, as it may be configured
-  to expect a specific file extension for CGI scripts.
-
-* On Unix-like systems, the path to the interpreter in the shebang
-  (``#!/usr/bin/env python``) must be correct.  This line calls
-  ``/usr/bin/env`` to find Python, but it will fail if there is no
-  ``/usr/bin/env``, or if Python is not in the web server's path.  If you know
-  where your Python is installed, you can also use that full path.  The
-  commands ``whereis python`` and ``type -p python`` could help you find
-  where it is installed.  Once you know the path, you can change the shebang
-  accordingly: ``#!/usr/bin/python``.
-
-* The file must not contain a BOM (Byte Order Mark). The BOM is meant for
-  determining the byte order of UTF-16 and UTF-32 encodings, but some editors
-  write this also into UTF-8 files.  The BOM interferes with the shebang line,
-  so be sure to tell your editor not to write the BOM.
-
-* If the web server is using :ref:`mod-python`, ``mod_python`` may be having
-  problems.  ``mod_python`` is able to handle CGI scripts by itself, but it can
-  also be a source of issues.
-
-
-.. _mod-python:
-
-mod_python
-----------
-
-People coming from PHP often find it hard to grasp how to use Python in the web.
-Their first thought is mostly `mod_python <http://modpython.org/>`_\ ,
-because they think that this is the equivalent to ``mod_php``.  Actually, there
-are many differences.  What ``mod_python`` does is embed the interpreter into
-the Apache process, thus speeding up requests by not having to start a Python
-interpreter for each request.  On the other hand, it is not "Python intermixed
-with HTML" in the way that PHP is often intermixed with HTML. The Python
-equivalent of that is a template engine.  ``mod_python`` itself is much more
-powerful and provides more access to Apache internals.  It can emulate CGI,
-work in a "Python Server Pages" mode (similar to JSP) which is "HTML
-intermingled with Python", and it has a "Publisher" which designates one file
-to accept all requests and decide what to do with them.
-
-``mod_python`` does have some problems.  Unlike the PHP interpreter, the Python
-interpreter uses caching when executing files, so changes to a file will
-require the web server to be restarted.  Another problem is the basic concept
--- Apache starts child processes to handle the requests, and unfortunately
-every child process needs to load the whole Python interpreter even if it does
-not use it.  This makes the whole web server slower.  Another problem is that,
-because ``mod_python`` is linked against a specific version of ``libpython``,
-it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5)
-without recompiling ``mod_python``.  ``mod_python`` is also bound to the Apache
-web server, so programs written for ``mod_python`` cannot easily run on other
-web servers.
-
-These are the reasons why ``mod_python`` should be avoided when writing new
-programs.  In some circumstances it still might be a good idea to use
-``mod_python`` for deployment, but WSGI makes it possible to run WSGI programs
-under ``mod_python`` as well.
-
-
-FastCGI and SCGI
-----------------
-
-FastCGI and SCGI try to solve the performance problem of CGI in another way.
-Instead of embedding the interpreter into the web server, they create
-long-running background processes. There is still a module in the web server
-which makes it possible for the web server to "speak" with the background
-process.  As the background process is independent of the server, it can be
-written in any language, including Python.  The language just needs to have a
-library which handles the communication with the webserver.
-
-The difference between FastCGI and SCGI is very small, as SCGI is essentially
-just a "simpler FastCGI".  As the web server support for SCGI is limited,
-most people use FastCGI instead, which works the same way.  Almost everything
-that applies to SCGI also applies to FastCGI as well, so we'll only cover
-the latter.
-
-These days, FastCGI is never used directly.  Just like ``mod_python``, it is only
-used for the deployment of WSGI applications.
-
-
-Setting up FastCGI
-^^^^^^^^^^^^^^^^^^
-
-Each web server requires a specific module.
-
-* Apache has both `mod_fastcgi <http://www.fastcgi.com/drupal/>`_ and `mod_fcgid
-  <http://httpd.apache.org/mod_fcgid/>`_.  ``mod_fastcgi`` is the original one, but it
-  has some licensing issues, which is why it is sometimes considered non-free.
-  ``mod_fcgid`` is a smaller, compatible alternative.  One of these modules needs
-  to be loaded by Apache.
-
-* lighttpd ships its own `FastCGI module
-  <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI>`_ as well as an
-  `SCGI module <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSCGI>`_.
-
-* `nginx <http://nginx.org/>`_ also supports `FastCGI
-  <http://wiki.nginx.org/NginxSimplePythonFCGI>`_.
-
-Once you have installed and configured the module, you can test it with the
-following WSGI-application::
-
-    #!/usr/bin/env python
-    # -*- coding: UTF-8 -*-
-
-    import sys, os
-    from html import escape
-    from flup.server.fcgi import WSGIServer
-
-    def app(environ, start_response):
-        start_response('200 OK', [('Content-Type', 'text/html')])
-
-        yield '<h1>FastCGI Environment</h1>'
-        yield '<table>'
-        for k, v in sorted(environ.items()):
-             yield '<tr><th>{0}</th><td>{1}</td></tr>'.format(
-                 escape(k), escape(v))
-        yield '</table>'
-
-    WSGIServer(app).run()
-
-This is a simple WSGI application, but you need to install `flup
-<https://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level
-FastCGI access.
-
-.. seealso::
-
-   There is some documentation on `setting up Django with FastCGI
-   <https://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/>`_, most of
-   which can be reused for other WSGI-compliant frameworks and libraries.
-   Only the ``manage.py`` part has to be changed, the example used here can be
-   used instead.  Django does more or less the exact same thing.
-
-
-mod_wsgi
---------
-
-`mod_wsgi <http://code.google.com/p/modwsgi/>`_ is an attempt to get rid of the
-low level gateways.  Given that FastCGI, SCGI, and mod_python are mostly used to
-deploy WSGI applications, mod_wsgi was started to directly embed WSGI applications
-into the Apache web server. mod_wsgi is specifically designed to host WSGI
-applications.  It makes the deployment of WSGI applications much easier than
-deployment using other low level methods, which need glue code.  The downside
-is that mod_wsgi is limited to the Apache web server; other servers would need
-their own implementations of mod_wsgi.
-
-mod_wsgi supports two modes: embedded mode, in which it integrates with the
-Apache process, and daemon mode, which is more FastCGI-like.  Unlike FastCGI,
-mod_wsgi handles the worker-processes by itself, which makes administration
-easier.
-
-
-.. _WSGI:
-
-Step back: WSGI
-===============
-
-WSGI has already been mentioned several times, so it has to be something
-important.  In fact it really is, and now it is time to explain it.
-
-The *Web Server Gateway Interface*,  or WSGI for short, is defined in
-:pep:`333` and is currently the best way to do Python web programming.  While
-it is great for programmers writing frameworks, a normal web developer does not
-need to get in direct contact with it.  When choosing a framework for web
-development it is a good idea to choose one which supports WSGI.
-
-The big benefit of WSGI is the unification of the application programming
-interface.  When your program is compatible with WSGI -- which at the outer
-level means that the framework you are using has support for WSGI -- your
-program can be deployed via any web server interface for which there are WSGI
-wrappers.  You do not need to care about whether the application user uses
-mod_python or FastCGI or mod_wsgi -- with WSGI your application will work on
-any gateway interface.  The Python standard library contains its own WSGI
-server, :mod:`wsgiref`, which is a small web server that can be used for
-testing.
-
-A really great WSGI feature is middleware.  Middleware is a layer around your
-program which can add various functionality to it.  There is quite a bit of
-`middleware <http://www.wsgi.org/en/latest/libraries.html>`_ already
-available.  For example, instead of writing your own session management (HTTP
-is a stateless protocol, so to associate multiple HTTP requests with a single
-user your application must create and manage such state via a session), you can
-just download middleware which does that, plug it in, and get on with coding
-the unique parts of your application.  The same thing with compression -- there
-is existing middleware which handles compressing your HTML using gzip to save
-on your server's bandwidth.  Authentication is another a problem easily solved
-using existing middleware.
-
-Although WSGI may seem complex, the initial phase of learning can be very
-rewarding because WSGI and the associated middleware already have solutions to
-many problems that might arise while developing web sites.
-
-
-WSGI Servers
-------------
-
-The code that is used to connect to various low level gateways like CGI or
-mod_python is called a *WSGI server*.  One of these servers is ``flup``, which
-supports FastCGI and SCGI, as well as `AJP
-<http://en.wikipedia.org/wiki/Apache_JServ_Protocol>`_.  Some of these servers
-are written in Python, as ``flup`` is, but there also exist others which are
-written in C and can be used as drop-in replacements.
-
-There are many servers already available, so a Python web application
-can be deployed nearly anywhere.  This is one big advantage that Python has
-compared with other web technologies.
-
-.. seealso::
-
-   A good overview of WSGI-related code can be found in the `WSGI homepage
-   <http://www.wsgi.org/en/latest/index.html>`_, which contains an extensive list of `WSGI servers
-   <http://www.wsgi.org/en/latest/servers.html>`_ which can be used by *any* application
-   supporting WSGI.
-
-   You might be interested in some WSGI-supporting modules already contained in
-   the standard library, namely:
-
-   * :mod:`wsgiref` -- some tiny utilities and servers for WSGI
-
-
-Case study: MoinMoin
---------------------
-
-What does WSGI give the web application developer?  Let's take a look at
-an application that's been around for a while, which was written in
-Python without using WSGI.
-
-One of the most widely used wiki software packages is `MoinMoin
-<http://moinmo.in/>`_.  It was created in 2000, so it predates WSGI by about
-three years.  Older versions needed separate code to run on CGI, mod_python,
-FastCGI and standalone.
-
-It now includes support for WSGI.  Using WSGI, it is possible to deploy
-MoinMoin on any WSGI compliant server, with no additional glue code.
-Unlike the pre-WSGI versions, this could include WSGI servers that the
-authors of MoinMoin know nothing about.
-
-
-Model-View-Controller
-=====================
-
-The term *MVC* is often encountered in statements such as "framework *foo*
-supports MVC".  MVC is more about the overall organization of code, rather than
-any particular API.  Many web frameworks use this model to help the developer
-bring structure to their program.  Bigger web applications can have lots of
-code, so it is a good idea to have an effective structure right from the beginning.
-That way, even users of other frameworks (or even other languages, since MVC is
-not Python-specific) can easily understand the code, given that they are
-already familiar with the MVC structure.
-
-MVC stands for three components:
-
-* The *model*.  This is the data that will be displayed and modified.  In
-  Python frameworks, this component is often represented by the classes used by
-  an object-relational mapper.
-
-* The *view*.  This component's job is to display the data of the model to the
-  user.  Typically this component is implemented via templates.
-
-* The *controller*.  This is the layer between the user and the model.  The
-  controller reacts to user actions (like opening some specific URL), tells
-  the model to modify the data if necessary, and tells the view code what to
-  display,
-
-While one might think that MVC is a complex design pattern, in fact it is not.
-It is used in Python because it has turned out to be useful for creating clean,
-maintainable web sites.
-
-.. note::
-
-   While not all Python frameworks explicitly support MVC, it is often trivial
-   to create a web site which uses the MVC pattern by separating the data logic
-   (the model) from the user interaction logic (the controller) and the
-   templates (the view).  That's why it is important not to write unnecessary
-   Python code in the templates -- it works against the MVC model and creates
-   chaos in the code base, making it harder to understand and modify.
-
-.. seealso::
-
-   The English Wikipedia has an article about the `Model-View-Controller pattern
-   <http://en.wikipedia.org/wiki/Model-view-controller>`_.  It includes a long
-   list of web frameworks for various programming languages.
-
-
-Ingredients for Websites
-========================
-
-Websites are complex constructs, so tools have been created to help web
-developers make their code easier to write and more maintainable.  Tools like
-these exist for all web frameworks in all languages.  Developers are not forced
-to use these tools, and often there is no "best" tool.  It is worth learning
-about the available tools because they can greatly simplify the process of
-developing a web site.
-
-
-.. seealso::
-
-   There are far more components than can be presented here.  The Python wiki
-   has a page about these components, called
-   `Web Components <https://wiki.python.org/moin/WebComponents>`_.
-
-
-Templates
----------
-
-Mixing of HTML and Python code is made possible by a few libraries.  While
-convenient at first, it leads to horribly unmaintainable code.  That's why
-templates exist.  Templates are, in the simplest case, just HTML files with
-placeholders.  The HTML is sent to the user's browser after filling in the
-placeholders.
-
-Python already includes a way to build simple templates::
-
-    # a simple template
-    template = "<html><body><h1>Hello {who}!</h1></body></html>"
-    print(template.format(who="Reader"))
-
-To generate complex HTML based on non-trivial model data, conditional
-and looping constructs like Python's *for* and *if* are generally needed.
-*Template engines* support templates of this complexity.
-
-There are a lot of template engines available for Python which can be used with
-or without a `framework`_.  Some of these define a plain-text programming
-language which is easy to learn, partly because it is limited in scope.
-Others use XML, and the template output is guaranteed to be always be valid
-XML.  There are many other variations.
-
-Some `frameworks`_ ship their own template engine or recommend one in
-particular.  In the absence of a reason to use a different template engine,
-using the one provided by or recommended by the framework is a good idea.
-
-Popular template engines include:
-
-   * `Mako <http://www.makotemplates.org/>`_
-   * `Genshi <http://genshi.edgewall.org/>`_
-   * `Jinja <http://jinja.pocoo.org/>`_
-
-.. seealso::
-
-   There are many template engines competing for attention, because it is
-   pretty easy to create them in Python.  The page `Templating
-   <https://wiki.python.org/moin/Templating>`_ in the wiki lists a big,
-   ever-growing number of these.  The three listed above are considered "second
-   generation" template engines and are a good place to start.
-
-
-Data persistence
-----------------
-
-*Data persistence*, while sounding very complicated, is just about storing data.
-This data might be the text of blog entries, the postings on a bulletin board or
-the text of a wiki page.  There are, of course, a number of different ways to store
-information on a web server.
-
-Often, relational database engines like `MySQL <http://www.mysql.com/>`_ or
-`PostgreSQL <http://www.postgresql.org/>`_ are used because of their good
-performance when handling very large databases consisting of millions of
-entries.  There is also a small database engine called `SQLite
-<http://www.sqlite.org/>`_, which is bundled with Python in the :mod:`sqlite3`
-module, and which uses only one file.  It has no other dependencies.  For
-smaller sites SQLite is just enough.
-
-Relational databases are *queried* using a language called `SQL
-<http://en.wikipedia.org/wiki/SQL>`_.  Python programmers in general do not
-like SQL too much, as they prefer to work with objects.  It is possible to save
-Python objects into a database using a technology called `ORM
-<http://en.wikipedia.org/wiki/Object-relational_mapping>`_ (Object Relational
-Mapping).  ORM translates all object-oriented access into SQL code under the
-hood, so the developer does not need to think about it.  Most `frameworks`_ use
-ORMs, and it works quite well.
-
-A second possibility is storing data in normal, plain text files (some
-times called "flat files").  This is very easy for simple sites,
-but can be difficult to get right if the web site is performing many
-updates to the stored data.
-
-A third possibility are object oriented databases (also called "object
-databases").  These databases store the object data in a form that closely
-parallels the way the objects are structured in memory during program
-execution.  (By contrast, ORMs store the object data as rows of data in tables
-and relations between those rows.)  Storing the objects directly has the
-advantage that nearly all objects can be saved in a straightforward way, unlike
-in relational databases where some objects are very hard to represent.
-
-`Frameworks`_ often give hints on which data storage method to choose.  It is
-usually a good idea to stick to the data store recommended by the framework
-unless the application has special requirements better satisfied by an
-alternate storage mechanism.
-
-.. seealso::
-
-   * `Persistence Tools <https://wiki.python.org/moin/PersistenceTools>`_ lists
-     possibilities on how to save data in the file system.  Some of these
-     modules are part of the standard library
-
-   * `Database Programming <https://wiki.python.org/moin/DatabaseProgramming>`_
-     helps with choosing a method for saving data
-
-   * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper
-     for Python, and `Elixir <http://elixir.ematia.de/>`_, which makes
-     SQLAlchemy easier to use
-
-   * `SQLObject <http://www.sqlobject.org/>`_, another popular OR-Mapper
-
-   * `ZODB <https://launchpad.net/zodb>`_ and `Durus
-     <http://www.mems-exchange.org/software/durus/>`_, two object oriented
-     databases
-
-
-.. _framework:
-
-Frameworks
-==========
-
-The process of creating code to run web sites involves writing code to provide
-various services.  The code to provide a particular service often works the
-same way regardless of the complexity or purpose of the web site in question.
-Abstracting these common solutions into reusable code produces what are called
-"frameworks" for web development.  Perhaps the most well-known framework for
-web development is Ruby on Rails, but Python has its own frameworks.  Some of
-these were partly inspired by Rails, or borrowed ideas from Rails, but many
-existed a long time before Rails.
-
-Originally Python web frameworks tended to incorporate all of the services
-needed to develop web sites as a giant, integrated set of tools.  No two web
-frameworks were interoperable:  a program developed for one could not be
-deployed on a different one without considerable re-engineering work.  This led
-to the development of "minimalist" web frameworks that provided just the tools
-to communicate between the Python code and the http protocol, with all other
-services to be added on top via separate components.  Some ad hoc standards
-were developed that allowed for limited interoperability between frameworks,
-such as a standard that allowed different template engines to be used
-interchangeably.
-
-Since the advent of WSGI, the Python web framework world has been evolving
-toward interoperability based on the WSGI standard.  Now many web frameworks,
-whether "full stack" (providing all the tools one needs to deploy the most
-complex web sites) or minimalist, or anything in between, are built from
-collections of reusable components that can be used with more than one
-framework.
-
-The majority of users will probably want to select a "full stack" framework
-that has an active community.  These frameworks tend to be well documented,
-and provide the easiest path to producing a fully functional web site in
-minimal time.
-
-
-Some notable frameworks
------------------------
-
-There are an incredible number of frameworks, so they cannot all be covered
-here.  Instead we will briefly touch on some of the most popular.
-
-
-Django
-^^^^^^
-
-`Django <https://www.djangoproject.com/>`_ is a framework consisting of several
-tightly coupled elements which were written from scratch and work together very
-well.  It includes an ORM which is quite powerful while being simple to use,
-and has a great online administration interface which makes it possible to edit
-the data in the database with a browser.  The template engine is text-based and
-is designed to be usable for page designers who cannot write Python.  It
-supports template inheritance and filters (which work like Unix pipes).  Django
-has many handy features bundled, such as creation of RSS feeds or generic views,
-which make it possible to create web sites almost without writing any Python code.
-
-It has a big, international community, the members of which have created many
-web sites.  There are also a lot of add-on projects which extend Django's normal
-functionality.  This is partly due to Django's well written `online
-documentation <https://docs.djangoproject.com/>`_ and the `Django book
-<http://www.djangobook.com/>`_.
-
-
-.. note::
-
-   Although Django is an MVC-style framework, it names the elements
-   differently, which is described in the `Django FAQ
-   <https://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names>`_.
-
-
-TurboGears
-^^^^^^^^^^
-
-Another popular web framework for Python is `TurboGears
-<http://www.turbogears.org/>`_.  TurboGears takes the approach of using already
-existing components and combining them with glue code to create a seamless
-experience.  TurboGears gives the user flexibility in choosing components. For
-example the ORM and template engine can be changed to use packages different
-from those used by default.
-
-The documentation can be found in the `TurboGears wiki
-<http://docs.turbogears.org/>`_, where links to screencasts can be found.
-TurboGears has also an active user community which can respond to most related
-questions.  There is also a `TurboGears book <http://turbogearsbook.com/>`_
-published, which is a good starting point.
-
-The newest version of TurboGears, version 2.0, moves even further in direction
-of WSGI support and a component-based architecture.  TurboGears 2 is based on
-the WSGI stack of another popular component-based web framework, `Pylons
-<http://www.pylonsproject.org/>`_.
-
-
-Zope
-^^^^
-
-The Zope framework is one of the "old original" frameworks.  Its current
-incarnation in Zope2 is a tightly integrated full-stack framework.  One of its
-most interesting feature is its tight integration with a powerful object
-database called the `ZODB <https://launchpad.net/zodb>`_ (Zope Object Database).
-Because of its highly integrated nature, Zope wound up in a somewhat isolated
-ecosystem:  code written for Zope wasn't very usable outside of Zope, and
-vice-versa.  To solve this problem the Zope 3 effort was started.  Zope 3
-re-engineers Zope as a set of more cleanly isolated components.  This effort
-was started before the advent of the WSGI standard, but there is WSGI support
-for Zope 3 from the `Repoze <http://repoze.org/>`_ project.  Zope components
-have many years of production use behind them, and the Zope 3 project gives
-access to these components to the wider Python community.  There is even a
-separate framework based on the Zope components: `Grok
-<http://grok.zope.org/>`_.
-
-Zope is also the infrastructure used by the `Plone <https://plone.org/>`_ content
-management system, one of the most powerful and popular content management
-systems available.
-
-
-Other notable frameworks
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-Of course these are not the only frameworks that are available.  There are
-many other frameworks worth mentioning.
-
-Another framework that's already been mentioned is `Pylons`_.  Pylons is much
-like TurboGears, but with an even stronger emphasis on flexibility, which comes
-at the cost of being more difficult to use.  Nearly every component can be
-exchanged, which makes it necessary to use the documentation of every single
-component, of which there are many.  Pylons builds upon `Paste
-<http://pythonpaste.org/>`_, an extensive set of tools which are handy for WSGI.
-
-And that's still not everything.  The most up-to-date information can always be
-found in the Python wiki.
-
-.. seealso::
-
-   The Python wiki contains an extensive list of `web frameworks
-   <https://wiki.python.org/moin/WebFrameworks>`_.
-
-   Most frameworks also have their own mailing lists and IRC channels, look out
-   for these on the projects' web sites.
index febdb7c..b22fc59 100644 (file)
 
 .. TODO: Fill in XXX comments
 
+.. seealso::
+
+   :ref:`installing-index`
+      The up to date module installation documentations
+
 .. The audience for this document includes people who don't know anything
    about Python and aren't about to learn the language just in order to
    install and maintain it for their users, i.e. system administrators.
@@ -865,12 +870,12 @@ config file will apply.  (Or if other commands that derive values from it are
 run, they will use the values in the config file.)
 
 You can find out the complete list of options for any command using the
-:option:`--help` option, e.g.::
+:option:`!--help` option, e.g.::
 
    python setup.py build --help
 
 and you can find out the complete list of global options by using
-:option:`--help` without a command::
+:option:`!--help` without a command::
 
    python setup.py --help
 
@@ -927,7 +932,7 @@ Let's examine each of the fields in turn.
   to be in Objective C.
 
 * *cpparg* is an argument for the C preprocessor,  and is anything starting with
-  :option:`-I`, :option:`-D`, :option:`-U` or :option:`-C`.
+  :option:`!-I`, :option:`-D`, :option:`!-U` or :option:`-C`.
 
 * *library* is anything ending in :file:`.a` or beginning with :option:`-l` or
   :option:`-L`.
@@ -1012,7 +1017,7 @@ section :ref:`inst-config-files`.)
 
 .. seealso::
 
-   `C++Builder Compiler <http://www.embarcadero.com/downloads>`_
+   `C++Builder Compiler <https://www.embarcadero.com/products>`_
       Information about the free C++ compiler from Borland, including links to the
       download pages.
 
@@ -1055,7 +1060,7 @@ These compilers require some special libraries.  This task is more complex than
 for Borland's C++, because there is no program to convert the library.  First
 you have to create a list of symbols which the Python DLL exports. (You can find
 a good program for this task at
-http://sourceforge.net/projects/mingw/files/MinGW/Extension/pexports/).
+https://sourceforge.net/projects/mingw/files/MinGW/Extension/pexports/).
 
 .. I don't understand what the next line means. --amk
 .. (inclusive the references on data structures.)
@@ -1093,7 +1098,7 @@ normal libraries do.
 .. [#] This also means you could replace all existing COFF-libraries with OMF-libraries
    of the same name.
 
-.. [#] Check http://www.sourceware.org/cygwin/ and http://www.mingw.org/ for more
+.. [#] Check https://www.sourceware.org/cygwin/ and http://www.mingw.org/ for more
    information
 
 .. [#] Then you have no POSIX emulation available, but you also don't need
index 973c689..1ef3149 100644 (file)
@@ -48,7 +48,7 @@ Key terms
   repository of open source licensed packages made available for use by
   other Python users
 * the `Python Packaging Authority
-  <https://packaging.python.org/en/latest/future.html>`__ are the group of
+  <https://www.pypa.io/en/latest/>`__ are the group of
   developers and documentation authors responsible for the maintenance and
   evolution of the standard packaging tools and the associated metadata and
   file format standards. They maintain a variety of tools, documentation
@@ -84,10 +84,12 @@ dependencies from the Python Packaging Index::
    Python.
 
 It's also possible to specify an exact or minimum version directly on the
-command line::
+command line. When using comparator operators such as ``>``, ``<`` or some other
+special character which get interpreted by shell, the package name and the
+version should be enclosed within double quotes::
 
     python -m pip install SomePackage==1.0.4    # specific version
-    python -m pip install 'SomePackage>=1.0.4'  # minimum version
+    python -m pip install "SomePackage>=1.0.4"  # minimum version
 
 Normally, if a suitable module is already installed, attempting to install
 it again will have no effect. Upgrading existing modules must be requested
@@ -104,7 +106,7 @@ into an active virtual environment uses the commands shown above.
 .. seealso::
 
     `Python Packaging User Guide: Installing Python Distribution Packages
-    <https://packaging.python.org/en/latest/installing.html#installing-python-distribution-packages>`__
+    <https://packaging.python.org/en/latest/installing/>`__
 
 
 How do I ...?
@@ -121,8 +123,8 @@ User Guide.
 
 .. seealso::
 
-   `Python Packaging User Guide: Setup for Installing Distribution Packages
-   <https://packaging.python.org/en/latest/installing.html#setup-for-installing-distribution-packages>`__
+   `Python Packaging User Guide: Requirements for Installing Packages
+   <https://packaging.python.org/en/latest/installing/#requirements-for-installing-packages>`__
 
 
 .. installing-per-user-installation:
@@ -141,13 +143,13 @@ A number of scientific Python packages have complex binary dependencies, and
 aren't currently easy to install using ``pip`` directly. At this point in
 time, it will often be easier for users to install these packages by
 `other means
-<https://packaging.python.org/en/latest/science.html>`__
+<https://packaging.python.org/en/latest/science/>`__
 rather than attempting to install them with ``pip``.
 
 .. seealso::
 
    `Python Packaging User Guide: Installing Scientific Packages
-   <https://packaging.python.org/en/latest/science.html>`__
+   <https://packaging.python.org/en/latest/science/>`__
 
 
 ... work with multiple versions of Python installed in parallel?
@@ -177,7 +179,7 @@ switch::
    Once the Development & Deployment part of PPUG is fleshed out, some of
    those sections should be linked from new questions here (most notably,
    we should have a question about avoiding depending on PyPI that links to
-   https://packaging.python.org/en/latest/deployment.html#pypi-mirrors-and-caches)
+   https://packaging.python.org/en/latest/mirrors/)
 
 
 Common installation issues
@@ -210,11 +212,11 @@ as users are more regularly able to install pre-built extensions rather
 than needing to build them themselves.
 
 Some of the solutions for installing `scientific software
-<https://packaging.python.org/en/latest/science.html>`__
+<https://packaging.python.org/en/latest/science/>`__
 that is not yet available as pre-built ``wheel`` files may also help with
 obtaining other binary extensions without needing to build them locally.
 
 .. seealso::
 
    `Python Packaging User Guide: Binary Extensions
-   <https://packaging.python.org/en/latest/extensions.html>`__
+   <https://packaging.python.org/en/latest/extensions/>`__
index 31f681d..6fc2865 100644 (file)
@@ -56,7 +56,7 @@ Comments and exact indentation are preserved throughout the translation process.
 
 By default, 2to3 runs a set of :ref:`predefined fixers <2to3-fixers>`.  The
 :option:`-l` flag lists all available fixers.  An explicit set of fixers to run
-can be given with :option:`-f`.  Likewise the :option:`-x` explicitly disables a
+can be given with :option:`-f`.  Likewise the :option:`!-x` explicitly disables a
 fixer.  The following example runs only the ``imports`` and ``has_key`` fixers::
 
    $ 2to3 -f imports -f has_key example.py
@@ -78,12 +78,12 @@ but 2to3 cannot fix automatically.  In this case, 2to3 will print a warning
 beneath the diff for a file.  You should address the warning in order to have
 compliant 3.x code.
 
-2to3 can also refactor doctests.  To enable this mode, use the :option:`-d`
+2to3 can also refactor doctests.  To enable this mode, use the :option:`!-d`
 flag.  Note that *only* doctests will be refactored.  This also doesn't require
 the module to be valid Python.  For example, doctest like examples in a reST
 document could also be refactored with this option.
 
-The :option:`-v` option enables output of more information on the translation
+The :option:`!-v` option enables output of more information on the translation
 process.
 
 Since some print statements can be parsed as function calls or statements, 2to3
@@ -102,14 +102,14 @@ when not overwriting the input files.
 .. versionadded:: 3.2.3
    The :option:`-o` option was added.
 
-The :option:`-W` or :option:`--write-unchanged-files` flag tells 2to3 to always
+The :option:`!-W` or :option:`--write-unchanged-files` flag tells 2to3 to always
 write output files even if no changes were required to the file.  This is most
 useful with :option:`-o` so that an entire Python source tree is copied with
 translation from one directory to another.
 This option implies the :option:`-w` flag as it would not make sense otherwise.
 
 .. versionadded:: 3.2.3
-   The :option:`-W` flag was added.
+   The :option:`!-W` flag was added.
 
 The :option:`--add-suffix` option specifies a string to append to all output
 filenames.  The :option:`-n` flag is required when specifying this as backups
@@ -449,10 +449,14 @@ and off individually.  They are described here in more detail.
 
 .. module:: lib2to3
    :synopsis: the 2to3 library
+
 .. moduleauthor:: Guido van Rossum
 .. moduleauthor:: Collin Winter
 .. moduleauthor:: Benjamin Peterson <benjamin@python.org>
 
+**Source code:** :source:`Lib/lib2to3/`
+
+--------------
 
 .. note::
 
index a46993d..a64faf1 100644 (file)
@@ -5,6 +5,8 @@
 .. module:: __main__
    :synopsis: The environment where the top-level script is run.
 
+--------------
+
 ``'__main__'`` is the name of the scope in which top-level code executes.
 A module's __name__ is set equal to ``'__main__'`` when read from
 standard input, a script, or from an interactive prompt.
index 7122861..0d2d818 100644 (file)
@@ -4,13 +4,14 @@
 .. module:: _thread
    :synopsis: Low-level threading API.
 
-
 .. index::
    single: light-weight processes
    single: processes, light-weight
    single: binary semaphores
    single: semaphores, binary
 
+--------------
+
 This module provides low-level primitives for working with multiple threads
 (also called :dfn:`light-weight processes` or :dfn:`tasks`) --- multiple threads of
 control sharing their global data space.  For synchronization, simple locks
index 7a73704..966003b 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: abc
    :synopsis: Abstract base classes according to PEP 3119.
+
 .. moduleauthor:: Guido van Rossum
 .. sectionauthor:: Georg Brandl
 .. much of the content adapted from docstrings
index 6fbcf28..23a9620 100644 (file)
@@ -4,14 +4,13 @@
 .. module:: aifc
    :synopsis: Read and write audio files in AIFF or AIFC format.
 
+**Source code:** :source:`Lib/aifc.py`
 
 .. index::
    single: Audio Interchange File Format
    single: AIFF
    single: AIFF-C
 
-**Source code:** :source:`Lib/aifc.py`
-
 --------------
 
 This module provides support for reading and writing AIFF and AIFF-C files.
index 2877437..10789e9 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: argparse
    :synopsis: Command-line option and argument parsing library.
+
 .. moduleauthor:: Steven Bethard <steven.bethard@gmail.com>
 .. sectionauthor:: Steven Bethard <steven.bethard@gmail.com>
 
@@ -35,10 +36,10 @@ produces either the sum or the max::
 
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('integers', metavar='N', type=int, nargs='+',
-                      help='an integer for the accumulator')
+                       help='an integer for the accumulator')
    parser.add_argument('--sum', dest='accumulate', action='store_const',
-                      const=sum, default=max,
-                      help='sum the integers (default: find the max)')
+                       const=sum, default=max,
+                       help='sum the integers (default: find the max)')
 
    args = parser.parse_args()
    print(args.accumulate(args.integers))
@@ -488,7 +489,7 @@ specified characters will be treated as files, and will be replaced by the
 arguments they contain.  For example::
 
    >>> with open('args.txt', 'w') as fp:
-   ...    fp.write('-f\nbar')
+   ...     fp.write('-f\nbar')
    >>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
    >>> parser.add_argument('-f')
    >>> parser.parse_args(['-f', 'foo', '@args.txt'])
@@ -720,24 +721,25 @@ how the command-line arguments should be handled. The supplied actions are:
     Namespace(foo='1')
 
 * ``'store_const'`` - This stores the value specified by the const_ keyword
-  argument.  (Note that the const_ keyword argument defaults to the rather
-  unhelpful ``None``.)  The ``'store_const'`` action is most commonly used with
+  argument.  The ``'store_const'`` action is most commonly used with
   optional arguments that specify some sort of flag.  For example::
 
     >>> parser = argparse.ArgumentParser()
     >>> parser.add_argument('--foo', action='store_const', const=42)
-    >>> parser.parse_args('--foo'.split())
+    >>> parser.parse_args(['--foo'])
     Namespace(foo=42)
 
-* ``'store_true'`` and ``'store_false'`` - These store the values ``True`` and
-  ``False`` respectively.  These are special cases of ``'store_const'``.  For
-  example::
+* ``'store_true'`` and ``'store_false'`` - These are special cases of
+  ``'store_const'`` used for storing the values ``True`` and ``False``
+  respectively.  In addition, they create default values of ``False`` and
+  ``True`` respectively.  For example::
 
     >>> parser = argparse.ArgumentParser()
     >>> parser.add_argument('--foo', action='store_true')
     >>> parser.add_argument('--bar', action='store_false')
+    >>> parser.add_argument('--baz', action='store_false')
     >>> parser.parse_args('--foo --bar'.split())
-    Namespace(bar=False, foo=True)
+    Namespace(foo=True, bar=False, baz=True)
 
 * ``'append'`` - This stores a list, and appends each argument value to the
   list.  This is useful to allow an option to be specified multiple times.
@@ -765,7 +767,7 @@ how the command-line arguments should be handled. The supplied actions are:
 
     >>> parser = argparse.ArgumentParser()
     >>> parser.add_argument('--verbose', '-v', action='count')
-    >>> parser.parse_args('-vvv'.split())
+    >>> parser.parse_args(['-vvv'])
     Namespace(verbose=3)
 
 * ``'help'`` - This prints a complete help message for all the options in the
@@ -840,11 +842,11 @@ values are:
      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', nargs='?', const='c', default='d')
      >>> parser.add_argument('bar', nargs='?', default='d')
-     >>> parser.parse_args('XX --foo YY'.split())
+     >>> parser.parse_args(['XX', '--foo', 'YY'])
      Namespace(bar='XX', foo='YY')
-     >>> parser.parse_args('XX --foo'.split())
+     >>> parser.parse_args(['XX', '--foo'])
      Namespace(bar='XX', foo='c')
-     >>> parser.parse_args(''.split())
+     >>> parser.parse_args([])
      Namespace(bar='d', foo='d')
 
   One of the more common uses of ``nargs='?'`` is to allow optional input and
@@ -880,9 +882,9 @@ values are:
 
      >>> parser = argparse.ArgumentParser(prog='PROG')
      >>> parser.add_argument('foo', nargs='+')
-     >>> parser.parse_args('a b'.split())
+     >>> parser.parse_args(['a', 'b'])
      Namespace(foo=['a', 'b'])
-     >>> parser.parse_args(''.split())
+     >>> parser.parse_args([])
      usage: PROG [-h] foo [foo ...]
      PROG: error: too few arguments
 
@@ -921,7 +923,8 @@ the various :class:`ArgumentParser` actions.  The two most common uses of it are
   command-line argument following it, the value of ``const`` will be assumed instead.
   See the nargs_ description for examples.
 
-The ``const`` keyword argument defaults to ``None``.
+With the ``'store_const'`` and ``'append_const'`` actions, the ``const``
+keyword argument must be given.  For other actions, it defaults to ``None``.
 
 
 default
@@ -936,9 +939,9 @@ was not present at the command line::
 
    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', default=42)
-   >>> parser.parse_args('--foo 2'.split())
+   >>> parser.parse_args(['--foo', '2'])
    Namespace(foo='2')
-   >>> parser.parse_args(''.split())
+   >>> parser.parse_args([])
    Namespace(foo=42)
 
 If the ``default`` value is a string, the parser parses the value as if it
@@ -957,9 +960,9 @@ is used when no command-line argument was present::
 
    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('foo', nargs='?', default=42)
-   >>> parser.parse_args('a'.split())
+   >>> parser.parse_args(['a'])
    Namespace(foo='a')
-   >>> parser.parse_args(''.split())
+   >>> parser.parse_args([])
    Namespace(foo=42)
 
 
@@ -1016,9 +1019,9 @@ the converted value::
    ...
    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('foo', type=perfect_square)
-   >>> parser.parse_args('9'.split())
+   >>> parser.parse_args(['9'])
    Namespace(foo=9)
-   >>> parser.parse_args('7'.split())
+   >>> parser.parse_args(['7'])
    usage: PROG [-h] foo
    PROG: error: argument foo: '7' is not a perfect square
 
@@ -1027,9 +1030,9 @@ simply check against a range of values::
 
    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('foo', type=int, choices=range(5, 10))
-   >>> parser.parse_args('7'.split())
+   >>> parser.parse_args(['7'])
    Namespace(foo=7)
-   >>> parser.parse_args('11'.split())
+   >>> parser.parse_args(['11'])
    usage: PROG [-h] {5,6,7,8,9}
    PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
 
@@ -1107,10 +1110,10 @@ argument::
 
    >>> parser = argparse.ArgumentParser(prog='frobble')
    >>> parser.add_argument('--foo', action='store_true',
-   ...         help='foo the bars before frobbling')
+   ...                     help='foo the bars before frobbling')
    >>> parser.add_argument('bar', nargs='+',
-   ...         help='one of the bars to be frobbled')
-   >>> parser.parse_args('-h'.split())
+   ...                     help='one of the bars to be frobbled')
+   >>> parser.parse_args(['-h'])
    usage: frobble [-h] [--foo] bar [bar ...]
 
    positional arguments:
@@ -1127,7 +1130,7 @@ specifiers include the program name, ``%(prog)s`` and most keyword arguments to
 
    >>> parser = argparse.ArgumentParser(prog='frobble')
    >>> parser.add_argument('bar', nargs='?', type=int, default=42,
-   ...         help='the bar to %(prog)s (default: %(default)s)')
+   ...                     help='the bar to %(prog)s (default: %(default)s)')
    >>> parser.print_help()
    usage: frobble [-h] [bar]
 
@@ -1228,7 +1231,7 @@ attribute is determined by the ``dest`` keyword argument of
 
    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('bar')
-   >>> parser.parse_args('XXX'.split())
+   >>> parser.parse_args(['XXX'])
    Namespace(bar='XXX')
 
 For optional argument actions, the value of ``dest`` is normally inferred from
@@ -1325,22 +1328,22 @@ option and its value are passed as two separate arguments::
    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-x')
    >>> parser.add_argument('--foo')
-   >>> parser.parse_args('-x X'.split())
+   >>> parser.parse_args(['-x', 'X'])
    Namespace(foo=None, x='X')
-   >>> parser.parse_args('--foo FOO'.split())
+   >>> parser.parse_args(['--foo', 'FOO'])
    Namespace(foo='FOO', x=None)
 
 For long options (options with names longer than a single character), the option
 and value can also be passed as a single command-line argument, using ``=`` to
 separate them::
 
-   >>> parser.parse_args('--foo=FOO'.split())
+   >>> parser.parse_args(['--foo=FOO'])
    Namespace(foo='FOO', x=None)
 
 For short options (options only one character long), the option and its value
 can be concatenated::
 
-   >>> parser.parse_args('-xX'.split())
+   >>> parser.parse_args(['-xX'])
    Namespace(foo=None, x='X')
 
 Several short options can be joined together, using only a single ``-`` prefix,
@@ -1350,7 +1353,7 @@ as long as only the last option (or none of them) requires a value::
    >>> parser.add_argument('-x', action='store_true')
    >>> parser.add_argument('-y', action='store_true')
    >>> parser.add_argument('-z')
-   >>> parser.parse_args('-xyzZ'.split())
+   >>> parser.parse_args(['-xyzZ'])
    Namespace(x=True, y=True, z='Z')
 
 
@@ -1466,13 +1469,13 @@ interactive prompt::
    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument(
    ...     'integers', metavar='int', type=int, choices=range(10),
-   ...  nargs='+', help='an integer in the range 0..9')
+   ...     nargs='+', help='an integer in the range 0..9')
    >>> parser.add_argument(
    ...     '--sum', dest='accumulate', action='store_const', const=sum,
-   ...   default=max, help='sum the integers (default: find the max)')
+   ...     default=max, help='sum the integers (default: find the max)')
    >>> parser.parse_args(['1', '2', '3', '4'])
    Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
-   >>> parser.parse_args('1 2 3 4 --sum'.split())
+   >>> parser.parse_args(['1', '2', '3', '4', '--sum'])
    Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])
 
 
index f1ab959..24f3f62 100644 (file)
@@ -4,9 +4,10 @@
 .. module:: array
    :synopsis: Space efficient arrays of uniformly typed numeric values.
 
-
 .. index:: single: arrays
 
+--------------
+
 This module defines an object type which can compactly represent an array of
 basic values: characters, integers, floating point numbers.  Arrays are sequence
 types and behave very much like lists, except that the type of objects stored in
@@ -91,7 +92,7 @@ Array objects support the ordinary sequence operations of indexing, slicing,
 concatenation, and multiplication.  When using slice assignment, the assigned
 value must be an array object with the same type code; in all other cases,
 :exc:`TypeError` is raised. Array objects also implement the buffer interface,
-and may be used wherever :term:`bytes-like object`\ s are supported.
+and may be used wherever :term:`bytes-like objects <bytes-like object>` are supported.
 
 The following data items and methods are also supported:
 
@@ -271,7 +272,7 @@ Examples::
       Packing and unpacking of External Data Representation (XDR) data as used in some
       remote procedure call systems.
 
-   `The Numerical Python Documentation <http://docs.scipy.org/doc/>`_
+   `The Numerical Python Documentation <https://docs.scipy.org/doc/>`_
       The Numeric Python extension (NumPy) defines another array type; see
       http://www.numpy.org/ for further information about Numerical Python.
 
index 5373acd..8c3b7e4 100644 (file)
@@ -249,3 +249,8 @@ and classes for traversing abstract syntax trees:
    wanted *annotate_fields* must be set to ``False``.  Attributes such as line
    numbers and column offsets are not dumped by default.  If this is wanted,
    *include_attributes* can be set to ``True``.
+
+.. seealso::
+
+    `Green Tree Snakes <https://greentreesnakes.readthedocs.org/>`_, an external documentation resource, has good
+    details on working with Python ASTs.
index 794da8c..ae72d26 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: asynchat
    :synopsis: Support for asynchronous command/response protocols.
+
 .. moduleauthor:: Sam Rushing <rushing@nightmare.com>
 .. sectionauthor:: Steve Holden <sholden@holdenweb.com>
 
@@ -202,7 +203,7 @@ any extraneous data sent by the web client are ignored. ::
                    self.set_terminator(None)
                    self.handle_request()
            elif not self.handling:
-               self.set_terminator(None) # browsers sometimes over-send
+               self.set_terminator(None)  # browsers sometimes over-send
                self.cgi_data = parse(self.headers, b"".join(self.ibuffer))
                self.handling = True
                self.ibuffer = []
index dbe351d..7ec3aa1 100644 (file)
@@ -179,6 +179,20 @@ a different clock than :func:`time.time`.
    The :func:`asyncio.sleep` function.
 
 
+Futures
+-------
+
+.. method:: BaseEventLoop.create_future()
+
+   Create an :class:`asyncio.Future` object attached to the loop.
+
+   This is a preferred way to create futures in asyncio, as event
+   loop implementations can provide alternative implementations
+   of the Future class (with better performance or instrumentation).
+
+   .. versionadded:: 3.5.2
+
+
 Tasks
 -----
 
@@ -253,7 +267,7 @@ Creating connections
       a class.  For example, if you want to use a pre-created
       protocol instance, you can pass ``lambda: my_protocol``.
 
-   Options allowing to change how the connection is created:
+   Options that change how the connection is created:
 
    * *ssl*: if given and not false, a SSL/TLS transport is created
      (by default a plain TCP transport is created).  If *ssl* is
@@ -477,7 +491,10 @@ Low-level socket operations
 
 .. coroutinemethod:: BaseEventLoop.sock_recv(sock, nbytes)
 
-   Receive data from the socket.  The return value is a bytes object
+   Receive data from the socket.  Modeled after blocking
+   :meth:`socket.socket.recv` method.
+
+   The return value is a bytes object
    representing the data received.  The maximum amount of data to be received
    at once is specified by *nbytes*.
 
@@ -486,13 +503,12 @@ Low-level socket operations
 
    This method is a :ref:`coroutine <coroutine>`.
 
-   .. seealso::
-
-      The :meth:`socket.socket.recv` method.
-
 .. coroutinemethod:: BaseEventLoop.sock_sendall(sock, data)
 
-   Send data to the socket.  The socket must be connected to a remote socket.
+   Send data to the socket.  Modeled after blocking
+   :meth:`socket.socket.sendall` method.
+
+   The socket must be connected to a remote socket.
    This method continues to send data from *data* until either all data has
    been sent or an error occurs.  ``None`` is returned on success.  On error,
    an exception is raised, and there is no way to determine how much data, if
@@ -503,35 +519,35 @@ Low-level socket operations
 
    This method is a :ref:`coroutine <coroutine>`.
 
-   .. seealso::
-
-      The :meth:`socket.socket.sendall` method.
-
 .. coroutinemethod:: BaseEventLoop.sock_connect(sock, address)
 
-   Connect to a remote socket at *address*.
-
-   The *address* must be already resolved to avoid the trap of hanging the
-   entire event loop when the address requires doing a DNS lookup.  For
-   example, it must be an IP address, not an hostname, for
-   :py:data:`~socket.AF_INET` and :py:data:`~socket.AF_INET6` address families.
-   Use :meth:`getaddrinfo` to resolve the hostname asynchronously.
+   Connect to a remote socket at *address*.  Modeled after
+   blocking :meth:`socket.socket.connect` method.
 
    With :class:`SelectorEventLoop` event loop, the socket *sock* must be
    non-blocking.
 
    This method is a :ref:`coroutine <coroutine>`.
 
+   .. versionchanged:: 3.5.2
+      ``address`` no longer needs to be resolved.  ``sock_connect``
+      will try to check if the *address* is already resolved by calling
+      :func:`socket.inet_pton`.  If not,
+      :meth:`BaseEventLoop.getaddrinfo` will be used to resolve the
+      *address*.
+
    .. seealso::
 
-      The :meth:`BaseEventLoop.create_connection` method, the
-      :func:`open_connection` function and the :meth:`socket.socket.connect`
-      method.
+      :meth:`BaseEventLoop.create_connection`
+      and  :func:`asyncio.open_connection() <open_connection>`.
 
 
 .. coroutinemethod:: BaseEventLoop.sock_accept(sock)
 
-   Accept a connection. The socket must be bound to an address and listening
+   Accept a connection.  Modeled after blocking
+   :meth:`socket.socket.accept`.
+
+   The socket must be bound to an address and listening
    for connections. The return value is a pair ``(conn, address)`` where *conn*
    is a *new* socket object usable to send and receive data on the connection,
    and *address* is the address bound to the socket on the other end of the
@@ -543,8 +559,7 @@ Low-level socket operations
 
    .. seealso::
 
-      The :meth:`BaseEventLoop.create_server` method, the :func:`start_server`
-      function and the :meth:`socket.socket.accept` method.
+      :meth:`BaseEventLoop.create_server` and :func:`start_server`.
 
 
 Resolve host name
@@ -654,7 +669,7 @@ pool of processes). By default, an event loop uses a thread pool executor
 Error Handling API
 ------------------
 
-Allows to customize how exceptions are handled in the event loop.
+Allows customizing how exceptions are handled in the event loop.
 
 .. method:: BaseEventLoop.set_exception_handler(handler)
 
@@ -669,6 +684,13 @@ Allows to customize how exceptions are handled in the event loop.
    will be a ``dict`` object (see :meth:`call_exception_handler`
    documentation for details about context).
 
+.. method:: BaseEventLoop.get_exception_handler()
+
+   Return the exception handler, or ``None`` if the default one
+   is in use.
+
+   .. versionadded:: 3.5.2
+
 .. method:: BaseEventLoop.default_exception_handler(context)
 
    Default exception handler.
@@ -739,11 +761,11 @@ Server
       Stop serving: close listening sockets and set the :attr:`sockets`
       attribute to ``None``.
 
-      The sockets that represent existing incoming client connections are
-      leaved open.
+      The sockets that represent existing incoming client connections are left
+      open.
 
-      The server is closed asynchonously, use the :meth:`wait_closed` coroutine
-      to wait until the server is closed.
+      The server is closed asynchronously, use the :meth:`wait_closed`
+      coroutine to wait until the server is closed.
 
    .. coroutinemethod:: wait_closed()
 
index b2e7d7c..b8f29d7 100644 (file)
@@ -41,7 +41,7 @@ asyncio currently provides two implementations of event loops:
 
    On Windows, only sockets are supported (ex: pipes are not supported):
    see the `MSDN documentation of select
-   <http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx>`_.
+   <https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx>`_.
 
 .. class:: ProactorEventLoop
 
@@ -53,7 +53,7 @@ asyncio currently provides two implementations of event loops:
    .. seealso::
 
       `MSDN documentation on I/O Completion Ports
-      <http://msdn.microsoft.com/en-us/library/windows/desktop/aa365198%28v=vs.85%29.aspx>`_.
+      <https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198%28v=vs.85%29.aspx>`_.
 
 Example to use a :class:`ProactorEventLoop` on Windows::
 
@@ -107,7 +107,7 @@ Common limits of Windows event loops:
 The resolution of the monotonic clock on Windows is usually around 15.6 msec.
 The best resolution is 0.5 msec. The resolution depends on the hardware
 (availability of `HPET
-<http://fr.wikipedia.org/wiki/High_Precision_Event_Timer>`_) and on the Windows
+<https://en.wikipedia.org/wiki/High_Precision_Event_Timer>`_) and on the Windows
 configuration. See :ref:`asyncio delayed calls <asyncio-delayed-calls>`.
 
 .. versionchanged:: 3.5
index fffd3e8..23d34d0 100644 (file)
@@ -1,8 +1,8 @@
 .. currentmodule:: asyncio
 
-+++++++++++++++++++++++++++++++++++++++++
-Transports  and protocols (low-level API)
-+++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++
+Transports  and protocols (callback based API)
+++++++++++++++++++++++++++++++++++++++++++++++
 
 .. _asyncio-transport:
 
index 171fd86..08fe071 100644 (file)
@@ -2,16 +2,16 @@
 
 .. _asyncio-streams:
 
-++++++++++++++++++++++++
-Streams (high-level API)
-++++++++++++++++++++++++
++++++++++++++++++++++++++++++
+Streams (coroutine based API)
++++++++++++++++++++++++++++++
 
 Stream functions
 ================
 
 .. note::
 
-   The top-level functions in this module are meant convenience wrappers
+   The top-level functions in this module are meant as convenience wrappers
    only; there's really nothing special there, and if they don't do
    exactly what you want, feel free to copy their code.
 
@@ -142,6 +142,30 @@ StreamReader
 
       This method is a :ref:`coroutine <coroutine>`.
 
+   .. coroutinemethod:: readuntil(separator=b'\n')
+
+      Read data from the stream until ``separator`` is found.
+
+      On success, the data and separator will be removed from the
+      internal buffer (consumed). Returned data will include the
+      separator at the end.
+
+      Configured stream limit is used to check result. Limit sets the
+      maximal length of data that can be returned, not counting the
+      separator.
+
+      If an EOF occurs and the complete separator is still not found,
+      an :exc:`IncompleteReadError` exception will be
+      raised, and the internal buffer will be reset.  The
+      :attr:`IncompleteReadError.partial` attribute may contain the
+      separator partially.
+
+      If the data cannot be read because of over limit, a
+      :exc:`LimitOverrunError` exception  will be raised, and the data
+      will be left in the internal buffer, so it can be read again.
+
+      .. versionadded:: 3.5.2
+
    .. method:: at_eof()
 
       Return ``True`` if the buffer is empty and :meth:`feed_eof` was called.
@@ -223,7 +247,7 @@ StreamReaderProtocol
 .. class:: StreamReaderProtocol(stream_reader, client_connected_cb=None, loop=None)
 
     Trivial helper class to adapt between :class:`Protocol` and
-    :class:`StreamReader`. Sublclass of :class:`Protocol`.
+    :class:`StreamReader`. Subclass of :class:`Protocol`.
 
     *stream_reader* is a :class:`StreamReader` instance, *client_connected_cb*
     is an optional function called with (stream_reader, stream_writer) when a
@@ -251,6 +275,18 @@ IncompleteReadError
       Read bytes string before the end of stream was reached (:class:`bytes`).
 
 
+LimitOverrunError
+=================
+
+.. exception:: LimitOverrunError
+
+   Reached the buffer limit while looking for a separator.
+
+   .. attribute:: consumed
+
+      Total number of to be consumed bytes.
+
+
 Stream examples
 ===============
 
index 21dae54..51ce427 100644 (file)
@@ -51,7 +51,7 @@ Create a subprocess: high-level API using Process
 
    It is the application's responsibility to ensure that all whitespace and
    metacharacters are quoted appropriately to avoid `shell injection
-   <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
+   <https://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
    vulnerabilities. The :func:`shlex.quote` function can be used to properly
    escape whitespace and shell metacharacters in strings that are going to be
    used to construct shell commands.
@@ -134,7 +134,7 @@ Run subprocesses asynchronously using the :mod:`subprocess` module.
 
    It is the application's responsibility to ensure that all whitespace and
    metacharacters are quoted appropriately to avoid `shell injection
-   <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
+   <https://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
    vulnerabilities. The :func:`shlex.quote` function can be used to properly
    escape whitespace and shell metacharacters in strings that are going to be
    used to construct shell commands.
index ad3b523..0909352 100644 (file)
@@ -52,7 +52,7 @@ Lock
    :meth:`acquire` is a coroutine and should be called with ``yield from``.
 
    Locks also support the context management protocol.  ``(yield from lock)``
-   should be used as context manager expression.
+   should be used as the context manager expression.
 
    This class is :ref:`not thread safe <asyncio-multithreading>`.
 
@@ -71,14 +71,14 @@ Lock
        lock = Lock()
        ...
        with (yield from lock):
-            ...
+           ...
 
    Lock objects can be tested for locking state::
 
        if not lock.locked():
-          yield from lock
+           yield from lock
        else:
-          # lock is acquired
+           # lock is acquired
            ...
 
    .. method:: locked()
index 051ae09..de6ee58 100644 (file)
@@ -383,9 +383,10 @@ Task
    running in different threads. While a task waits for the completion of a
    future, the event loop executes a new task.
 
-   The cancellation of a task is different from the cancelation of a future. Calling
-   :meth:`cancel` will throw a :exc:`~concurrent.futures.CancelledError` to the
-   wrapped coroutine. :meth:`~Future.cancelled` only returns ``True`` if the
+   The cancellation of a task is different from the cancelation of a
+   future. Calling :meth:`cancel` will throw a
+   :exc:`~concurrent.futures.CancelledError` to the wrapped
+   coroutine. :meth:`~Future.cancelled` only returns ``True`` if the
    wrapped coroutine did not catch the
    :exc:`~concurrent.futures.CancelledError` exception, or raised a
    :exc:`~concurrent.futures.CancelledError` exception.
@@ -437,10 +438,11 @@ Task
 
       Return the list of stack frames for this task's coroutine.
 
-      If the coroutine is not done, this returns the stack where it is suspended.
-      If the coroutine has completed successfully or was cancelled, this
-      returns an empty list.  If the coroutine was terminated by an exception,
-      this returns the list of traceback frames.
+      If the coroutine is not done, this returns the stack where it is
+      suspended.  If the coroutine has completed successfully or was
+      cancelled, this returns an empty list.  If the coroutine was
+      terminated by an exception, this returns the list of traceback
+      frames.
 
       The frames are always ordered from oldest to newest.
 
@@ -508,7 +510,7 @@ Task functions
 
 .. note::
 
-   In the functions below, the optional *loop* argument allows to explicitly set
+   In the functions below, the optional *loop* argument allows explicitly setting
    the event loop object used by the underlying task or coroutine.  If it's
    not provided, the default event loop is used.
 
@@ -539,6 +541,9 @@ Task functions
 
    .. versionadded:: 3.4.4
 
+   .. versionchanged:: 3.5.1
+      The function accepts any :term:`awaitable` object.
+
    .. seealso::
 
       The :meth:`BaseEventLoop.create_task` method.
@@ -579,6 +584,46 @@ Task functions
    <coroutine>`, which may be a decorated generator function or an
    :keyword:`async def` function.
 
+.. function:: run_coroutine_threadsafe(coro, loop)
+
+   Submit a :ref:`coroutine object <coroutine>` to a given event loop.
+
+   Return a :class:`concurrent.futures.Future` to access the result.
+
+   This function is meant to be called from a different thread than the one
+   where the event loop is running. Usage::
+
+     # Create a coroutine
+     coro = asyncio.sleep(1, result=3)
+     # Submit the coroutine to a given loop
+     future = asyncio.run_coroutine_threadsafe(coro, loop)
+     # Wait for the result with an optional timeout argument
+     assert future.result(timeout) == 3
+
+   If an exception is raised in the coroutine, the returned future will be
+   notified. It can also be used to cancel the task in the event loop::
+
+     try:
+         result = future.result(timeout)
+     except asyncio.TimeoutError:
+         print('The coroutine took too long, cancelling the task...')
+         future.cancel()
+     except Exception as exc:
+         print('The coroutine raised an exception: {!r}'.format(exc))
+     else:
+         print('The coroutine returned: {!r}'.format(result))
+
+   See the :ref:`concurrency and multithreading <asyncio-multithreading>`
+   section of the documentation.
+
+   .. note::
+
+      Unlike other functions from the module,
+      :func:`run_coroutine_threadsafe` requires the *loop* argument to
+      be passed explicitly.
+
+   .. versionadded:: 3.5.1
+
 .. coroutinefunction:: sleep(delay, result=None, \*, loop=None)
 
    Create a :ref:`coroutine <coroutine>` that completes after a given
@@ -617,7 +662,9 @@ Task functions
        except CancelledError:
            res = None
 
-.. coroutinefunction:: wait(futures, \*, loop=None, timeout=None, return_when=ALL_COMPLETED)
+
+.. coroutinefunction:: wait(futures, \*, loop=None, timeout=None,\
+                            return_when=ALL_COMPLETED)
 
    Wait for the Futures and coroutine objects given by the sequence *futures*
    to complete.  Coroutines will be wrapped in Tasks. Returns two sets of
@@ -682,43 +729,3 @@ Task functions
 
    .. versionchanged:: 3.4.3
       If the wait is cancelled, the future *fut* is now also cancelled.
-
-
-.. function:: run_coroutine_threadsafe(coro, loop)
-
-   Submit a :ref:`coroutine object <coroutine>` to a given event loop.
-
-   Return a :class:`concurrent.futures.Future` to access the result.
-
-   This function is meant to be called from a different thread than the one
-   where the event loop is running. Usage::
-
-     # Create a coroutine
-     coro = asyncio.sleep(1, result=3)
-     # Submit the coroutine to a given loop
-     future = asyncio.run_coroutine_threadsafe(coro, loop)
-     # Wait for the result with an optional timeout argument
-     assert future.result(timeout) == 3
-
-   If an exception is raised in the coroutine, the returned future will be
-   notified. It can also be used to cancel the task in the event loop::
-
-     try:
-         result = future.result(timeout)
-     except asyncio.TimeoutError:
-         print('The coroutine took too long, cancelling the task...')
-         future.cancel()
-     except Exception as exc:
-         print('The coroutine raised an exception: {!r}'.format(exc))
-     else:
-         print('The coroutine returned: {!r}'.format(result))
-
-   See the :ref:`concurrency and multithreading <asyncio-multithreading>`
-   section of the documentation.
-
-   .. note::
-
-      Unlike the functions above, :func:`run_coroutine_threadsafe` requires the
-      *loop* argument to be passed explicitely.
-
-   .. versionadded:: 3.4.4, 3.5.1
index 9b4d65e..f764c68 100644 (file)
@@ -4,6 +4,10 @@
 .. module:: asyncio
    :synopsis: Asynchronous I/O, event loop, coroutines and tasks.
 
+.. versionadded:: 3.4
+
+**Source code:** :source:`Lib/asyncio/`
+
 .. note::
 
    The asyncio package has been included in the standard library on a
    changes (up to and including removal of the module) may occur if deemed
    necessary by the core developers.
 
-.. versionadded:: 3.4
-
-**Source code:** :source:`Lib/asyncio/`
-
 --------------
 
 This module provides infrastructure for writing single-threaded concurrent
index 917d044..61061be 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: asyncore
    :synopsis: A base class for developing asynchronous socket handling
               services.
+
 .. moduleauthor:: Sam Rushing <rushing@nightmare.com>
 .. sectionauthor:: Christopher Petrilli <petrilli@amber.org>
 .. sectionauthor:: Steve Holden <sholden@holdenweb.com>
@@ -315,8 +316,8 @@ implement its socket handling::
            self.buffer = self.buffer[sent:]
 
 
-    client = HTTPClient('www.python.org', '/')
-    asyncore.loop()
+   client = HTTPClient('www.python.org', '/')
+   asyncore.loop()
 
 .. _asyncore-example-2:
 
index dbdd81e..1d84d45 100644 (file)
@@ -3,9 +3,11 @@
 
 .. module:: atexit
    :synopsis: Register and execute cleanup functions.
+
 .. moduleauthor:: Skip Montanaro <skip@pobox.com>
 .. sectionauthor:: Skip Montanaro <skip@pobox.com>
 
+--------------
 
 The :mod:`atexit` module defines functions to register and unregister cleanup
 functions.  Functions thus registered are automatically executed upon normal
index ce127aa..bad9da2 100644 (file)
@@ -4,10 +4,11 @@
 .. module:: audioop
    :synopsis: Manipulate raw audio data.
 
+--------------
 
 The :mod:`audioop` module contains some useful operations on sound fragments.
 It operates on sound fragments consisting of signed integer samples 8, 16, 24
-or 32 bits wide, stored in :term:`bytes-like object`\ s.  All scalar items are
+or 32 bits wide, stored in :term:`bytes-like objects <bytes-like object>`.  All scalar items are
 integers, unless specified otherwise.
 
 .. versionchanged:: 3.4
@@ -276,6 +277,6 @@ sample and subtract the whole output sample from the input sample::
        #              out_test)
        prefill = '\0'*(pos+ipos)*2
        postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))
-       outputdata = prefill + audioop.mul(outputdata,2,-factor) + postfill
+       outputdata = prefill + audioop.mul(outputdata, 2, -factor) + postfill
        return audioop.add(inputdata, outputdata, 2)
 
index 3d23dfc..080d9d7 100644 (file)
@@ -5,11 +5,14 @@
    :synopsis: RFC 3548: Base16, Base32, Base64 Data Encodings;
               Base85 and Ascii85
 
+**Source code:** :source:`Lib/base64.py`
 
 .. index::
    pair: base64; encoding
    single: MIME; base64 encoding
 
+--------------
+
 This module provides functions for encoding binary data to printable
 ASCII characters and decoding such encodings back to binary data.
 It provides encoding and decoding functions for the encodings specified in
@@ -21,88 +24,103 @@ safely sent by email, used as parts of URLs, or included as part of an HTTP
 POST request.  The encoding algorithm is not the same as the
 :program:`uuencode` program.
 
-There are two :rfc:`3548` interfaces provided by this module.  The modern
-interface supports encoding and decoding ASCII byte string objects using all
-three :rfc:`3548` defined alphabets (normal, URL-safe, and filesystem-safe).
-Additionally, the decoding functions of the modern interface also accept
-Unicode strings containing only ASCII characters. The legacy interface provides
-for encoding and decoding to and from file-like objects as well as byte
-strings, but only using the Base64 standard alphabet.
+There are two interfaces provided by this module.  The modern interface
+supports encoding :term:`bytes-like objects <bytes-like object>` to ASCII
+:class:`bytes`, and decoding :term:`bytes-like objects <bytes-like object>` or
+strings containing ASCII to :class:`bytes`.  Both base-64 alphabets
+defined in :rfc:`3548` (normal, and URL- and filesystem-safe) are supported.
+
+The legacy interface does not support decoding from strings, but it does
+provide functions for encoding and decoding to and from :term:`file objects
+<file object>`.  It only supports the Base64 standard alphabet, and it adds
+newlines every 76 characters as per :rfc:`2045`.  Note that if you are looking
+for :rfc:`2045` support you probably want to be looking at the :mod:`email`
+package instead.
+
 
 .. versionchanged:: 3.3
    ASCII-only Unicode strings are now accepted by the decoding functions of
    the modern interface.
 
 .. versionchanged:: 3.4
-   Any :term:`bytes-like object`\ s are now accepted by all
+   Any :term:`bytes-like objects <bytes-like object>` are now accepted by all
    encoding and decoding functions in this module.  Ascii85/Base85 support added.
 
 The modern interface provides:
 
 .. function:: b64encode(s, altchars=None)
 
-   Encode a byte string using Base64.
+   Encode the :term:`bytes-like object` *s* using Base64 and return the encoded
+   :class:`bytes`.
 
-   *s* is the string to encode.  Optional *altchars* must be a string of at least
+   Optional *altchars* must be a :term:`bytes-like object` of at least
    length 2 (additional characters are ignored) which specifies an alternative
    alphabet for the ``+`` and ``/`` characters.  This allows an application to e.g.
    generate URL or filesystem safe Base64 strings.  The default is ``None``, for
    which the standard Base64 alphabet is used.
 
-   The encoded byte string is returned.
-
 
 .. function:: b64decode(s, altchars=None, validate=False)
 
-   Decode a Base64 encoded byte string.
+   Decode the Base64 encoded :term:`bytes-like object` or ASCII string
+   *s* and return the decoded :class:`bytes`.
 
-   *s* is the byte string to decode.  Optional *altchars* must be a string of
+   Optional *altchars* must be a :term:`bytes-like object` or ASCII string of
    at least length 2 (additional characters are ignored) which specifies the
    alternative alphabet used instead of the ``+`` and ``/`` characters.
 
-   The decoded string is returned.  A :exc:`binascii.Error` exception is raised
+   A :exc:`binascii.Error` exception is raised
    if *s* is incorrectly padded.
 
-   If *validate* is ``False`` (the default), non-base64-alphabet characters are
+   If *validate* is ``False`` (the default), characters that are neither
+   in the normal base-64 alphabet nor the alternative alphabet are
    discarded prior to the padding check.  If *validate* is ``True``,
-   non-base64-alphabet characters in the input result in a
+   these non-alphabet characters in the input result in a
    :exc:`binascii.Error`.
 
 
 .. function:: standard_b64encode(s)
 
-   Encode byte string *s* using the standard Base64 alphabet.
+   Encode :term:`bytes-like object` *s* using the standard Base64 alphabet
+   and return the encoded :class:`bytes`.
 
 
 .. function:: standard_b64decode(s)
 
-   Decode byte string *s* using the standard Base64 alphabet.
+   Decode :term:`bytes-like object` or ASCII string *s* using the standard
+   Base64 alphabet and return the decoded :class:`bytes`.
 
 
 .. function:: urlsafe_b64encode(s)
 
-   Encode byte string *s* using a URL-safe alphabet, which substitutes ``-`` instead of
-   ``+`` and ``_`` instead of ``/`` in the standard Base64 alphabet.  The result
+   Encode :term:`bytes-like object` *s* using the
+   URL- and filesystem-safe alphabet, which
+   substitutes ``-`` instead of ``+`` and ``_`` instead of ``/`` in the
+   standard Base64 alphabet, and return the encoded :class:`bytes`.  The result
    can still contain ``=``.
 
 
 .. function:: urlsafe_b64decode(s)
 
-   Decode byte string *s* using a URL-safe alphabet, which substitutes ``-`` instead of
-   ``+`` and ``_`` instead of ``/`` in the standard Base64 alphabet.
+   Decode :term:`bytes-like object` or ASCII string *s*
+   using the URL- and filesystem-safe
+   alphabet, which substitutes ``-`` instead of ``+`` and ``_`` instead of
+   ``/`` in the standard Base64 alphabet, and return the decoded
+   :class:`bytes`.
 
 
 .. function:: b32encode(s)
 
-   Encode a byte string using Base32.  *s* is the string to encode.  The encoded string
-   is returned.
+   Encode the :term:`bytes-like object` *s* using Base32 and return the
+   encoded :class:`bytes`.
 
 
 .. function:: b32decode(s, casefold=False, map01=None)
 
-   Decode a Base32 encoded byte string.
+   Decode the Base32 encoded :term:`bytes-like object` or ASCII string *s* and
+   return the decoded :class:`bytes`.
 
-   *s* is the byte string to decode.  Optional *casefold* is a flag specifying
+   Optional *casefold* is a flag specifying
    whether a lowercase alphabet is acceptable as input.  For security purposes,
    the default is ``False``.
 
@@ -113,46 +131,45 @@ The modern interface provides:
    digit 0 is always mapped to the letter O).  For security purposes the default is
    ``None``, so that 0 and 1 are not allowed in the input.
 
-   The decoded byte string is returned.  A :exc:`binascii.Error` is raised if *s* is
+   A :exc:`binascii.Error` is raised if *s* is
    incorrectly padded or if there are non-alphabet characters present in the
-   string.
+   input.
 
 
 .. function:: b16encode(s)
 
-   Encode a byte string using Base16.
-
-   *s* is the string to encode.  The encoded byte string is returned.
+   Encode the :term:`bytes-like object` *s* using Base16 and return the
+   encoded :class:`bytes`.
 
 
 .. function:: b16decode(s, casefold=False)
 
-   Decode a Base16 encoded byte string.
+   Decode the Base16 encoded :term:`bytes-like object` or ASCII string *s* and
+   return the decoded :class:`bytes`.
 
-   *s* is the string to decode.  Optional *casefold* is a flag specifying whether a
+   Optional *casefold* is a flag specifying whether a
    lowercase alphabet is acceptable as input.  For security purposes, the default
    is ``False``.
 
-   The decoded byte string is returned.  A :exc:`TypeError` is raised if *s* were
+   A :exc:`binascii.Error` is raised if *s* is
    incorrectly padded or if there are non-alphabet characters present in the
-   string.
-
+   input.
 
-.. function:: a85encode(s, *, foldspaces=False, wrapcol=0, pad=False, adobe=False)
 
-   Encode a byte string using Ascii85.
+.. function:: a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False)
 
-   *s* is the string to encode. The encoded byte string is returned.
+   Encode the :term:`bytes-like object` *b* using Ascii85 and return the
+   encoded :class:`bytes`.
 
    *foldspaces* is an optional flag that uses the special short sequence 'y'
    instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This
    feature is not supported by the "standard" Ascii85 encoding.
 
-   *wrapcol* controls whether the output should have newline ('\n')
+   *wrapcol* controls whether the output should have newline (``b'\n'``)
    characters added to it. If this is non-zero, each output line will be
    at most this many characters long.
 
-   *pad* controls whether the input string is padded to a multiple of 4
+   *pad* controls whether the input is padded to a multiple of 4
    before encoding. Note that the ``btoa`` implementation always pads.
 
    *adobe* controls whether the encoded byte sequence is framed with ``<~``
@@ -161,11 +178,10 @@ The modern interface provides:
    .. versionadded:: 3.4
 
 
-.. function:: a85decode(s, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v')
+.. function:: a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \\t\\n\\r\\v')
 
-   Decode an Ascii85 encoded byte string.
-
-   *s* is the byte string to decode.
+   Decode the Ascii85 encoded :term:`bytes-like object` or ASCII string *b* and
+   return the decoded :class:`bytes`.
 
    *foldspaces* is a flag that specifies whether the 'y' short sequence
    should be accepted as shorthand for 4 consecutive spaces (ASCII 0x20).
@@ -174,27 +190,29 @@ The modern interface provides:
    *adobe* controls whether the input sequence is in Adobe Ascii85 format
    (i.e. is framed with <~ and ~>).
 
-   *ignorechars* should be a byte string containing characters to ignore
+   *ignorechars* should be a :term:`bytes-like object` or ASCII string
+   containing characters to ignore
    from the input. This should only contain whitespace characters, and by
    default contains all whitespace characters in ASCII.
 
    .. versionadded:: 3.4
 
 
-.. function:: b85encode(s, pad=False)
+.. function:: b85encode(b, pad=False)
 
-   Encode a byte string using base85, as used in e.g. git-style binary
-   diffs.
+   Encode the :term:`bytes-like object` *b* using base85 (as used in e.g.
+   git-style binary diffs) and return the encoded :class:`bytes`.
 
-   If *pad* is true, the input is padded with "\\0" so its length is a
-   multiple of 4 characters before encoding.
+   If *pad* is true, the input is padded with ``b'\0'`` so its length is a
+   multiple of 4 bytes before encoding.
 
    .. versionadded:: 3.4
 
 
 .. function:: b85decode(b)
 
-   Decode base85-encoded byte string.  Padding is implicitly removed, if
+   Decode the base85-encoded :term:`bytes-like object` or ASCII string *b* and
+   return the decoded :class:`bytes`.  Padding is implicitly removed, if
    necessary.
 
    .. versionadded:: 3.4
@@ -214,15 +232,15 @@ The legacy interface:
 
    Decode the contents of the binary *input* file and write the resulting binary
    data to the *output* file. *input* and *output* must be :term:`file objects
-   <file object>`. *input* will be read until ``input.read()`` returns an empty
-   bytes object.
+   <file object>`. *input* will be read until ``input.readline()`` returns an
+   empty bytes object.
 
 
 .. function:: decodebytes(s)
               decodestring(s)
 
-   Decode the byte string *s*, which must contain one or more lines of base64
-   encoded data, and return a byte string containing the resulting binary data.
+   Decode the :term:`bytes-like object` *s*, which must contain one or more
+   lines of base64 encoded data, and return the decoded :class:`bytes`.
    ``decodestring`` is a deprecated alias.
 
    .. versionadded:: 3.1
@@ -233,17 +251,19 @@ The legacy interface:
    Encode the contents of the binary *input* file and write the resulting base64
    encoded data to the *output* file. *input* and *output* must be :term:`file
    objects <file object>`. *input* will be read until ``input.read()`` returns
-   an empty bytes object. :func:`encode` returns the encoded data plus a trailing
-   newline character (``b'\n'``).
+   an empty bytes object. :func:`encode` inserts a newline character (``b'\n'``)
+   after every 76 bytes of the output, as well as ensuring that the output
+   always ends with a newline, as per :rfc:`2045` (MIME).
 
 
 .. function:: encodebytes(s)
               encodestring(s)
 
-   Encode the byte string *s*, which can contain arbitrary binary data, and
-   return a byte string containing one or more lines of base64-encoded data.
-   :func:`encodebytes` returns a string containing one or more lines of
-   base64-encoded data always including an extra trailing newline (``b'\n'``).
+   Encode the :term:`bytes-like object` *s*, which can contain arbitrary binary
+   data, and return :class:`bytes` containing the base64-encoded data, with newlines
+   (``b'\n'``) inserted after every 76 bytes of output, and ensuring that
+   there is a trailing newline, as per :rfc:`2045` (MIME).
+
    ``encodestring`` is a deprecated alias.
 
 
index e3f134b..878d8db 100644 (file)
@@ -5,12 +5,13 @@
    :synopsis: Tools for converting between binary and various ASCII-encoded binary
               representations.
 
-
 .. index::
    module: uu
    module: base64
    module: binhex
 
+--------------
+
 The :mod:`binascii` module contains a number of methods to convert between
 binary and various ASCII-encoded binary representations. Normally, you will not
 use these functions directly but use wrapper modules like :mod:`uu`,
@@ -21,7 +22,7 @@ higher-level modules.
 .. note::
 
    ``a2b_*`` functions accept Unicode strings containing only ASCII characters.
-   Other functions only accept :term:`bytes-like object`\ s (such as
+   Other functions only accept :term:`bytes-like objects <bytes-like object>` (such as
    :class:`bytes`, :class:`bytearray` and other objects that support the buffer
    protocol).
 
@@ -55,8 +56,10 @@ The :mod:`binascii` module defines the following functions:
 .. function:: b2a_base64(data)
 
    Convert binary data to a line of ASCII characters in base64 coding. The return
-   value is the converted line, including a newline char. The length of *data*
-   should be at most 57 to adhere to the base64 standard.
+   value is the converted line, including a newline char.  The newline is
+   added because the original use case for this function was to feed it a
+   series of 57 byte input lines to get output lines that conform to the
+   MIME-base64 standard.  Otherwise the output conforms to :rfc:`3548`.
 
 
 .. function:: a2b_qp(data, header=False)
@@ -110,15 +113,16 @@ The :mod:`binascii` module defines the following functions:
    possibly the last fragment).
 
 
-.. function:: crc_hqx(data, crc)
+.. function:: crc_hqx(data, value)
 
-   Compute the binhex4 crc value of *data*, starting with an initial *crc* and
-   returning the result.
+   Compute the binhex4 crc value of *data*, starting with *value* as the
+   initial crc, and return the result.
 
 
-.. function:: crc32(data[, crc])
+.. function:: crc32(data[, value])
 
-   Compute CRC-32, the 32-bit checksum of data, starting with an initial crc.  This
+   Compute CRC-32, the 32-bit checksum of *data*, starting with an
+   initial CRC of *value*.  The default initial CRC is zero.  The algorithm
    is consistent with the ZIP file checksum.  Since the algorithm is designed for
    use as a checksum algorithm, it is not suitable for use as a general hash
    algorithm.  Use as follows::
@@ -126,15 +130,13 @@ The :mod:`binascii` module defines the following functions:
       print(binascii.crc32(b"hello world"))
       # Or, in two pieces:
       crc = binascii.crc32(b"hello")
-      crc = binascii.crc32(b" world", crc) & 0xffffffff
+      crc = binascii.crc32(b" world", crc)
       print('crc32 = {:#010x}'.format(crc))
 
-.. note::
-   To generate the same numeric value across all Python versions and
-   platforms use crc32(data) & 0xffffffff.  If you are only using
-   the checksum in packed binary format this is not necessary as the
-   return value is the correct 32bit binary representation
-   regardless of sign.
+   .. versionchanged:: 3.0
+      The result is always unsigned.
+      To generate the same numeric value across all Python versions and
+      platforms, use ``crc32(data) & 0xffffffff``.
 
 
 .. function:: b2a_hex(data)
@@ -150,8 +152,8 @@ The :mod:`binascii` module defines the following functions:
 
    Return the binary data represented by the hexadecimal string *hexstr*.  This
    function is the inverse of :func:`b2a_hex`. *hexstr* must contain an even number
-   of hexadecimal digits (which can be upper or lower case), otherwise a
-   :exc:`TypeError` is raised.
+   of hexadecimal digits (which can be upper or lower case), otherwise an
+   :exc:`Error` exception is raised.
 
 
 .. exception:: Error
@@ -168,7 +170,8 @@ The :mod:`binascii` module defines the following functions:
 .. seealso::
 
    Module :mod:`base64`
-      Support for base64 encoding used in MIME email messages.
+      Support for RFC compliant base64-style encoding in base 16, 32, 64,
+      and 85.
 
    Module :mod:`binhex`
       Support for the binhex format used on the Macintosh.
index 43c7823..359ab23 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: binhex
    :synopsis: Encode and decode files in binhex4 format.
 
+**Source code:** :source:`Lib/binhex.py`
+
+--------------
 
 This module encodes and decodes files in binhex4 format, a format allowing
 representation of Macintosh files in ASCII. Only the data fork is handled.
index 13b0147..6bf7814 100644 (file)
@@ -60,7 +60,7 @@ The following functions are provided:
 .. seealso::
 
    `SortedCollection recipe
-   <http://code.activestate.com/recipes/577197-sortedcollection/>`_ that uses
+   <https://code.activestate.com/recipes/577197-sortedcollection/>`_ that uses
    bisect to build a full-featured collection class with straight-forward search
    methods and support for a key-function.  The keys are precomputed to save
    unnecessary calls to the key function during searches.
index 2cca1d0..4b589a5 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: builtins
    :synopsis: The module that provides the built-in namespace.
 
+--------------
 
 This module provides direct access to all 'built-in' identifiers of Python; for
 example, ``builtins.open`` is the full name for the built-in function
index 1b8d9cf..6c49d9f 100644 (file)
@@ -3,11 +3,15 @@
 
 .. module:: bz2
    :synopsis: Interfaces for bzip2 compression and decompression.
+
 .. moduleauthor:: Gustavo Niemeyer <niemeyer@conectiva.com>
 .. moduleauthor:: Nadeem Vawda <nadeem.vawda@gmail.com>
 .. sectionauthor:: Gustavo Niemeyer <niemeyer@conectiva.com>
 .. sectionauthor:: Nadeem Vawda <nadeem.vawda@gmail.com>
 
+**Source code:** :source:`Lib/bz2.py`
+
+--------------
 
 This module provides a comprehensive interface for compressing and
 decompressing data using the bzip2 compression algorithm.
index 3187c43..df76e33 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: calendar
    :synopsis: Functions for working with calendars, including some emulation
               of the Unix cal program.
+
 .. sectionauthor:: Drew Csillag <drew_csillag@geocities.com>
 
 **Source code:** :source:`Lib/calendar.py`
index 7e496ca..0bc2c35 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: cgi
    :synopsis: Helpers for running Python scripts via the Common Gateway Interface.
 
+**Source code:** :source:`Lib/cgi.py`
 
 .. index::
    pair: WWW; server
@@ -13,8 +14,6 @@
    single: URL
    single: Common Gateway Interface
 
-**Source code:** :source:`Lib/cgi.py`
-
 --------------
 
 Support module for Common Gateway Interface (CGI) scripts.
index 6827c8e..b65a635 100644 (file)
@@ -3,9 +3,11 @@
 
 .. module:: cgitb
    :synopsis: Configurable traceback handler for CGI scripts.
+
 .. moduleauthor:: Ka-Ping Yee <ping@lfw.org>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
+**Source code:** :source:`Lib/cgitb.py`
 
 .. index::
    single: CGI; exceptions
@@ -13,6 +15,8 @@
    single: exceptions; in CGI scripts
    single: tracebacks; in CGI scripts
 
+--------------
+
 The :mod:`cgitb` module provides a special exception handler for Python scripts.
 (Its name is a bit misleading.  It was originally designed to display extensive
 traceback information in HTML for CGI scripts.  It was later generalized to also
index a90e9f8..5e24df9 100644 (file)
@@ -3,9 +3,11 @@
 
 .. module:: chunk
    :synopsis: Module to read IFF chunks.
+
 .. moduleauthor:: Sjoerd Mullender <sjoerd@acm.org>
 .. sectionauthor:: Sjoerd Mullender <sjoerd@acm.org>
 
+**Source code:** :source:`Lib/chunk.py`
 
 .. index::
    single: Audio Interchange File Format
@@ -14,6 +16,8 @@
    single: Real Media File Format
    single: RMFF
 
+--------------
+
 This module provides an interface for reading files that use EA IFF 85 chunks.
 [#]_  This format is used in at least the Audio Interchange File Format
 (AIFF/AIFF-C) and the Real Media File Format (RMFF).  The WAVE audio file format
index ab619a0..62ddb6b 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: cmath
    :synopsis: Mathematical functions for complex numbers.
 
+--------------
 
 This module is always available.  It provides access to mathematical functions
 for complex numbers.  The functions in this module accept integers,
index 1ab2d74..61ef0f6 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: cmd
    :synopsis: Build line-oriented command interpreters.
+
 .. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
 
 **Source code:** :source:`Lib/cmd.py`
index 275201c..443af69 100644 (file)
@@ -6,6 +6,8 @@
 
 **Source code:** :source:`Lib/code.py`
 
+--------------
+
 The ``code`` module provides facilities to implement read-eval-print loops in
 Python.  Two classes and convenience functions are included which can be used to
 build applications which provide an interactive interpreter prompt.
index 46d72b5..1add300 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: codecs
    :synopsis: Encode and decode data and streams.
+
 .. moduleauthor:: Marc-André Lemburg <mal@lemburg.com>
 .. sectionauthor:: Marc-André Lemburg <mal@lemburg.com>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
@@ -17,6 +18,8 @@
    single: streams
    pair: stackable; streams
 
+--------------
+
 This module defines base classes for standard Python codecs (encoders and
 decoders) and provides access to the internal Python codec registry, which
 manages the codec and error handling lookup process. Most standard codecs
@@ -137,16 +140,16 @@ these additional functions which use :func:`lookup` for the codec lookup:
 
 .. function:: getreader(encoding)
 
-   Look up the codec for the given encoding and return its StreamReader class or
-   factory function.
+   Look up the codec for the given encoding and return its :class:`StreamReader`
+   class or factory function.
 
    Raises a :exc:`LookupError` in case the encoding cannot be found.
 
 
 .. function:: getwriter(encoding)
 
-   Look up the codec for the given encoding and return its StreamWriter class or
-   factory function.
+   Look up the codec for the given encoding and return its :class:`StreamWriter`
+   class or factory function.
 
    Raises a :exc:`LookupError` in case the encoding cannot be found.
 
@@ -977,7 +980,7 @@ particular, the following variants typically exist:
 
 * an ISO 8859 codeset
 
-* a Microsoft Windows code page, which is typically derived from a 8859 codeset,
+* a Microsoft Windows code page, which is typically derived from an 8859 codeset,
   but replaces control characters with additional graphic characters
 
 * an IBM EBCDIC code page
@@ -1414,7 +1417,7 @@ 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: http://tools.ietf.org/html/rfc3490#section-3.1
+.. _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
index 9ae4176..a52d2c6 100644 (file)
@@ -3,9 +3,14 @@
 
 .. module:: codeop
    :synopsis: Compile (possibly incomplete) Python code.
+
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 .. sectionauthor:: Michael Hudson <mwh@python.net>
 
+**Source code:** :source:`Lib/codeop.py`
+
+--------------
+
 The :mod:`codeop` module provides utilities upon which the Python
 read-eval-print loop can be emulated, as is done in the :mod:`code` module.  As
 a result, you probably don't want to use the module directly; if you want to
index d9b93ad..61682cc 100644 (file)
@@ -3,20 +3,21 @@
 
 .. module:: collections.abc
    :synopsis: Abstract base classes for containers
+
 .. moduleauthor:: Raymond Hettinger <python at rcn.com>
 .. sectionauthor:: Raymond Hettinger <python at rcn.com>
 
 .. versionadded:: 3.3
    Formerly, this module was part of the :mod:`collections` module.
 
+**Source code:** :source:`Lib/_collections_abc.py`
+
 .. testsetup:: *
 
    from collections import *
    import itertools
    __name__ = '<doctest>'
 
-**Source code:** :source:`Lib/_collections_abc.py`
-
 --------------
 
 This module provides :term:`abstract base classes <abstract base class>` that
@@ -218,19 +219,22 @@ The ABC supplies the remaining methods such as :meth:`__and__` and
 :meth:`isdisjoint`::
 
     class ListBasedSet(collections.abc.Set):
-         ''' Alternate set implementation favoring space over speed
-             and not requiring the set elements to be hashable. '''
-         def __init__(self, iterable):
-             self.elements = lst = []
-             for value in iterable:
-                 if value not in lst:
-                     lst.append(value)
-         def __iter__(self):
-             return iter(self.elements)
-         def __contains__(self, value):
-             return value in self.elements
-         def __len__(self):
-             return len(self.elements)
+        ''' Alternate set implementation favoring space over speed
+            and not requiring the set elements to be hashable. '''
+        def __init__(self, iterable):
+            self.elements = lst = []
+            for value in iterable:
+                if value not in lst:
+                    lst.append(value)
+
+        def __iter__(self):
+            return iter(self.elements)
+
+        def __contains__(self, value):
+            return value in self.elements
+
+        def __len__(self):
+            return len(self.elements)
 
     s1 = ListBasedSet('abcdef')
     s2 = ListBasedSet('defghi')
@@ -263,7 +267,7 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin:
 
 .. seealso::
 
-   * `OrderedSet recipe <http://code.activestate.com/recipes/576694/>`_ for an
+   * `OrderedSet recipe <https://code.activestate.com/recipes/576694/>`_ for an
      example built on :class:`MutableSet`.
 
    * For more about ABCs, see the :mod:`abc` module and :pep:`3119`.
index 2ab4413..4936b3a 100644 (file)
@@ -3,17 +3,18 @@
 
 .. module:: collections
     :synopsis: Container datatypes
+
 .. moduleauthor:: Raymond Hettinger <python@rcn.com>
 .. sectionauthor:: Raymond Hettinger <python@rcn.com>
 
+**Source code:** :source:`Lib/collections/__init__.py`
+
 .. testsetup:: *
 
     from collections import *
     import itertools
     __name__ = '<doctest>'
 
-**Source code:** :source:`Lib/collections/__init__.py`
-
 --------------
 
 This module implements specialized container datatypes providing alternatives to
@@ -56,7 +57,7 @@ The class can be used to simulate nested scopes and is useful in templating.
     dictionary is provided so that a new chain always has at least one mapping.
 
     The underlying mappings are stored in a list.  That list is public and can
-    accessed or updated using the *maps* attribute.  There is no other state.
+    be accessed or updated using the *maps* attribute.  There is no other state.
 
     Lookups search the underlying mappings successively until a key is found.  In
     contrast, writes, updates, and deletions only operate on the first mapping.
@@ -116,12 +117,12 @@ The class can be used to simulate nested scopes and is useful in templating.
       :meth:`~collections.ChainMap.parents` property.
 
     * The `Nested Contexts recipe
-      <http://code.activestate.com/recipes/577434/>`_ has options to control
+      <https://code.activestate.com/recipes/577434/>`_ has options to control
       whether writes and other mutations apply only to the first mapping or to
       any mapping in the chain.
 
     * A `greatly simplified read-only version of Chainmap
-      <http://code.activestate.com/recipes/305268/>`_.
+      <https://code.activestate.com/recipes/305268/>`_.
 
 
 :class:`ChainMap` Examples and Recipes
@@ -374,12 +375,12 @@ or subtracting from an empty counter.
 
 .. seealso::
 
-    * `Bag class <http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html>`_
+    * `Bag class <https://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html>`_
       in Smalltalk.
 
-    * Wikipedia entry for `Multisets <http://en.wikipedia.org/wiki/Multiset>`_.
+    * Wikipedia entry for `Multisets <https://en.wikipedia.org/wiki/Multiset>`_.
 
-    * `C++ multisets <http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm>`_
+    * `C++ multisets <http://www.java2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm>`_
       tutorial with examples.
 
     * For mathematical operations on multisets and their use cases, see
@@ -477,6 +478,9 @@ or subtracting from an empty counter.
 
         Insert *x* into the deque at position *i*.
 
+        If the insertion would cause a bounded deque to grow beyond *maxlen*,
+        an :exc:`IndexError` is raised.
+
         .. versionadded:: 3.5
 
 
@@ -789,6 +793,11 @@ they add the ability to access fields by name instead of position index.
     Named tuple instances do not have per-instance dictionaries, so they are
     lightweight and require no more memory than regular tuples.
 
+    For simple uses, where the only requirement is to be able to refer to a set
+    of values by name using attribute-style access, the
+    :class:`types.SimpleNamespace` type can be a suitable alternative to using
+    a namedtuple.
+
     .. versionchanged:: 3.1
         Added support for *rename*.
 
@@ -934,6 +943,9 @@ fields:
    >>> Book.title.__doc__ = 'Title of first printing'
    >>> Book.authors.__doc__ = 'List of authors sorted by last name'
 
+.. versionchanged:: 3.5
+   Property docstrings became writeable.
+
 Default values can be implemented by using :meth:`_replace` to
 customize a prototype instance:
 
@@ -946,7 +958,7 @@ customize a prototype instance:
 .. seealso::
 
     * `Recipe for named tuple abstract base class with a metaclass mix-in
-      <http://code.activestate.com/recipes/577629-namedtupleabc-abstract-base-class-mix-in-for-named/>`_
+      <https://code.activestate.com/recipes/577629-namedtupleabc-abstract-base-class-mix-in-for-named/>`_
       by Jan Kaliszewski.  Besides providing an :term:`abstract base class` for
       named tuples, it also supports an alternate :term:`metaclass`-based
       constructor that is convenient for use cases where named tuples are being
@@ -1018,7 +1030,7 @@ Since an ordered dictionary remembers its insertion order, it can be used
 in conjunction with sorting to make a sorted dictionary::
 
     >>> # regular unsorted dictionary
-    >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
+    >>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
 
     >>> # dictionary sorted by key
     >>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
index 225306c..c33f531 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: colorsys
    :synopsis: Conversion functions between RGB and other color systems.
+
 .. sectionauthor:: David Ascher <da@python.net>
 
 **Source code:** :source:`Lib/colorsys.py`
@@ -21,7 +22,7 @@ spaces, the coordinates are all between 0 and 1.
 
    More information about color spaces can be found at
    http://www.poynton.com/ColorFAQ.html and
-   http://www.cambridgeincolour.com/tutorials/color-spaces.htm.
+   https://www.cambridgeincolour.com/tutorials/color-spaces.htm.
 
 The :mod:`colorsys` module defines the following functions:
 
index c5736f2..511c581 100644 (file)
@@ -8,7 +8,6 @@
 
 --------------
 
-
 This module provides some utility functions to support installing Python
 libraries.  These functions compile Python source files in a directory tree.
 This module can be used to create the cached byte-code files at library
index 8bb70a5..ae03f4b 100644 (file)
@@ -42,7 +42,7 @@ Executor Objects
 
        Equivalent to :func:`map(func, *iterables) <map>` except *func* is executed
        asynchronously and several calls to *func* may be made concurrently.  The
-       returned iterator raises a :exc:`TimeoutError` if
+       returned iterator raises a :exc:`concurrent.futures.TimeoutError` if
        :meth:`~iterator.__next__` is called and the result isn't available
        after *timeout* seconds from the original call to :meth:`Executor.map`.
        *timeout* can be an int or a float.  If *timeout* is not specified or
@@ -99,12 +99,12 @@ the results of another :class:`Future`.  For example::
    import time
    def wait_on_b():
        time.sleep(5)
-       print(b.result()) # b will never complete because it is waiting on a.
+       print(b.result())  # b will never complete because it is waiting on a.
        return 5
 
    def wait_on_a():
        time.sleep(5)
-       print(a.result()) # a will never complete because it is waiting on b.
+       print(a.result())  # a will never complete because it is waiting on b.
        return 6
 
 
@@ -153,7 +153,7 @@ ThreadPoolExecutor Example
            'http://www.bbc.co.uk/',
            'http://some-made-up-domain.com/']
 
-   # Retrieve a single page and report the url and contents
+   # Retrieve a single page and report the URL and contents
    def load_url(url, timeout):
        with urllib.request.urlopen(url, timeout=timeout) as conn:
            return conn.read()
@@ -274,11 +274,12 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable.
 
        Return the value returned by the call. If the call hasn't yet completed
        then this method will wait up to *timeout* seconds.  If the call hasn't
-       completed in *timeout* seconds, then a :exc:`TimeoutError` will be
-       raised. *timeout* can be an int or float.  If *timeout* is not specified
-       or ``None``, there is no limit to the wait time.
+       completed in *timeout* seconds, then a
+       :exc:`concurrent.futures.TimeoutError` will be raised. *timeout* can be
+       an int or float.  If *timeout* is not specified or ``None``, there is no
+       limit to the wait time.
 
-       If the future is cancelled before completing then :exc:`CancelledError`
+       If the future is cancelled before completing then :exc:`.CancelledError`
        will be raised.
 
        If the call raised, this method will raise the same exception.
@@ -287,11 +288,12 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable.
 
        Return the exception raised by the call.  If the call hasn't yet
        completed then this method will wait up to *timeout* seconds.  If the
-       call hasn't completed in *timeout* seconds, then a :exc:`TimeoutError`
-       will be raised.  *timeout* can be an int or float.  If *timeout* is not
-       specified or ``None``, there is no limit to the wait time.
+       call hasn't completed in *timeout* seconds, then a
+       :exc:`concurrent.futures.TimeoutError` will be raised.  *timeout* can be
+       an int or float.  If *timeout* is not specified or ``None``, there is no
+       limit to the wait time.
 
-       If the future is cancelled before completing then :exc:`CancelledError`
+       If the future is cancelled before completing then :exc:`.CancelledError`
        will be raised.
 
        If the call completed without raising, ``None`` is returned.
@@ -391,13 +393,12 @@ Module Functions
    Returns an iterator over the :class:`Future` instances (possibly created by
    different :class:`Executor` instances) given by *fs* that yields futures as
    they complete (finished or were cancelled). Any futures given by *fs* that
-   are duplicated will be returned once. Any futures that completed
-   before :func:`as_completed` is called will be yielded first.  The returned
-   iterator raises a :exc:`TimeoutError` if :meth:`~iterator.__next__` is
-   called and the result isn't available after *timeout* seconds from the
-   original call to :func:`as_completed`.  *timeout* can be an int or float.
-   If *timeout* is not specified or ``None``, there is no limit to the wait
-   time.
+   are duplicated will be returned once. Any futures that completed before
+   :func:`as_completed` is called will be yielded first.  The returned iterator
+   raises a :exc:`concurrent.futures.TimeoutError` if :meth:`~iterator.__next__`
+   is called and the result isn't available after *timeout* seconds from the
+   original call to :func:`as_completed`.  *timeout* can be an int or float. If
+   *timeout* is not specified or ``None``, there is no limit to the wait time.
 
 
 .. seealso::
@@ -410,6 +411,16 @@ Module Functions
 Exception classes
 -----------------
 
+.. currentmodule:: concurrent.futures
+
+.. exception:: CancelledError
+
+   Raised when a future is cancelled.
+
+.. exception:: TimeoutError
+
+   Raised when a future operation exceeds the given timeout.
+
 .. currentmodule:: concurrent.futures.process
 
 .. exception:: BrokenProcessPool
index c9187a3..eeae96a 100644 (file)
@@ -19,6 +19,8 @@
    single: ini file
    single: Windows ini file
 
+--------------
+
 This module provides the :class:`ConfigParser` class which implements a basic
 configuration language which provides a structure similar to what's found in
 Microsoft Windows INI files.  You can use this to write Python programs which
@@ -833,13 +835,13 @@ To get interpolation, use :class:`ConfigParser`::
 
    # Set the optional *raw* argument of get() to True if you wish to disable
    # interpolation in a single get operation.
-   print(cfg.get('Section1', 'foo', raw=False)) # -> "Python is fun!"
-   print(cfg.get('Section1', 'foo', raw=True))  # -> "%(bar)s is %(baz)s!"
+   print(cfg.get('Section1', 'foo', raw=False))  # -> "Python is fun!"
+   print(cfg.get('Section1', 'foo', raw=True))   # -> "%(bar)s is %(baz)s!"
 
    # The optional *vars* argument is a dict with members that will take
    # precedence in interpolation.
    print(cfg.get('Section1', 'foo', vars={'bar': 'Documentation',
-                                             'baz': 'evil'}))
+                                          'baz': 'evil'}))
 
    # The optional *fallback* argument can be used to provide a fallback value
    print(cfg.get('Section1', 'foo'))
@@ -866,10 +868,10 @@ interpolation if an option used is not defined elsewhere. ::
    config = configparser.ConfigParser({'bar': 'Life', 'baz': 'hard'})
    config.read('example.cfg')
 
-   print(config.get('Section1', 'foo')) # -> "Python is fun!"
+   print(config.get('Section1', 'foo'))     # -> "Python is fun!"
    config.remove_option('Section1', 'bar')
    config.remove_option('Section1', 'baz')
-   print(config.get('Section1', 'foo')) # -> "Life is hard!"
+   print(config.get('Section1', 'foo'))     # -> "Life is hard!"
 
 
 .. _configparser-objects:
index 9e8463d..cf85fcd 100644 (file)
@@ -603,7 +603,7 @@ an explicit ``with`` statement.
 
 .. seealso::
 
-   :pep:`0343` - The "with" statement
+   :pep:`343` - The "with" statement
       The specification, background, and examples for the Python :keyword:`with`
       statement.
 
@@ -644,7 +644,7 @@ to yield if an attempt is made to use them a second time::
     Before
     After
     >>> with cm:
-    ...    pass
+    ...     pass
     ...
     Traceback (most recent call last):
         ...
index 02ef0e5..a8adcad 100644 (file)
@@ -4,6 +4,10 @@
 .. module:: copy
    :synopsis: Shallow and deep copy operations.
 
+**Source code:** :source:`Lib/copy.py`
+
+--------------
+
 Assignment statements in Python do not copy objects, they create bindings
 between a target and an object. For collections that are mutable or contain
 mutable items, a copy is sometimes needed so one can change one copy without
index 18306c7..eeabb4c 100644 (file)
@@ -4,11 +4,14 @@
 .. module:: copyreg
    :synopsis: Register pickle support functions.
 
+**Source code:** :source:`Lib/copyreg.py`
 
 .. index::
    module: pickle
    module: copy
 
+--------------
+
 The :mod:`copyreg` module offers a way to define functions used while pickling
 specific objects.  The :mod:`pickle` and :mod:`copy` modules use those functions
 when pickling/copying those objects.  The module provides configuration
index b4c90cd..a21c1e7 100644 (file)
@@ -4,15 +4,19 @@
 .. module:: crypt
    :platform: Unix
    :synopsis: The crypt() function used to check Unix passwords.
+
 .. moduleauthor:: Steven D. Majewski <sdm7g@virginia.edu>
 .. sectionauthor:: Steven D. Majewski <sdm7g@virginia.edu>
 .. sectionauthor:: Peter Funk <pf@artcom-gmbh.de>
 
+**Source code:** :source:`Lib/crypt.py`
 
 .. index::
    single: crypt(3)
    pair: cipher; DES
 
+--------------
+
 This module implements an interface to the :manpage:`crypt(3)` routine, which is
 a one-way hash function based upon a modified DES algorithm; see the Unix man
 page for further details.  Possible uses include storing hashed passwords
@@ -149,4 +153,4 @@ check it against the original::
 
    hashed = crypt.crypt(plaintext)
    if not compare_hash(hashed, crypt.crypt(plaintext, hashed)):
-      raise ValueError("hashed version doesn't validate against original")
+       raise ValueError("hashed version doesn't validate against original")
index 8ad24c8..1eddfdc 100644 (file)
@@ -16,14 +16,3 @@ Here's an overview:
 
    hashlib.rst
    hmac.rst
-
-.. index::
-   pair: AES; algorithm
-   single: cryptography
-   single: Kuchling, Andrew
-
-Hardcore cypherpunks will probably find the cryptographic modules written by
-A.M. Kuchling of further interest; the package contains modules for various
-encryption algorithms, most notably AES.  These modules are not distributed with
-Python but available separately.  See the URL http://www.pycrypto.org/ for more
-information.
index 4fcfaef..7fb4fc8 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: csv
    :synopsis: Write and read tabular data to and from delimited files.
+
 .. sectionauthor:: Skip Montanaro <skip@pobox.com>
 
 **Source code:** :source:`Lib/csv.py`
@@ -11,6 +12,8 @@
    single: csv
    pair: data; tabular
 
+--------------
+
 The so-called CSV (Comma Separated Values) format is the most common import and
 export format for spreadsheets and databases.  CSV format was used for many
 years prior to attempts to describe the format in a standardized way in
index 630d279..a675790 100644 (file)
@@ -3,8 +3,10 @@
 
 .. module:: ctypes
    :synopsis: A foreign function library for Python.
+
 .. moduleauthor:: Thomas Heller <theller@python.net>
 
+--------------
 
 :mod:`ctypes` is a foreign function library for Python.  It provides C compatible
 data types, and allows calling functions in DLLs or shared libraries.  It can be
@@ -20,11 +22,10 @@ Note: The code samples in this tutorial use :mod:`doctest` to make sure that
 they actually work.  Since some code samples behave differently under Linux,
 Windows, or Mac OS X, they contain doctest directives in comments.
 
-Note: Some code samples reference the ctypes :class:`c_int` type. This type is
-an alias for the :class:`c_long` type on 32-bit systems.  So, you should not be
-confused if :class:`c_long` is printed if you would expect :class:`c_int` ---
-they are actually the same type.
-
+Note: Some code samples reference the ctypes :class:`c_int` type.  On platforms
+where ``sizeof(long) == sizeof(int)`` it is an alias to :class:`c_long`.
+So, you should not be confused if :class:`c_long` is printed if you would expect
+:class:`c_int` --- they are actually the same type.
 
 .. _ctypes-loading-dynamic-link-libraries:
 
@@ -52,24 +53,30 @@ library containing most standard C functions, and uses the cdecl calling
 convention::
 
    >>> from ctypes import *
-   >>> print(windll.kernel32) # doctest: +WINDOWS
+   >>> print(windll.kernel32)  # doctest: +WINDOWS
    <WinDLL 'kernel32', handle ... at ...>
-   >>> print(cdll.msvcrt) # doctest: +WINDOWS
+   >>> print(cdll.msvcrt)      # doctest: +WINDOWS
    <CDLL 'msvcrt', handle ... at ...>
-   >>> libc = cdll.msvcrt # doctest: +WINDOWS
+   >>> libc = cdll.msvcrt      # doctest: +WINDOWS
    >>>
 
 Windows appends the usual ``.dll`` file suffix automatically.
 
+.. note::
+    Accessing the standard C library through ``cdll.msvcrt`` will use an
+    outdated version of the library that may be incompatible with the one
+    being used by Python. Where possible, use native Python functionality,
+    or else import and use the ``msvcrt`` module.
+
 On Linux, it is required to specify the filename *including* the extension to
 load a library, so attribute access can not be used to load libraries. Either the
 :meth:`LoadLibrary` method of the dll loaders should be used, or you should load
 the library by creating an instance of CDLL by calling the constructor::
 
-   >>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX
+   >>> cdll.LoadLibrary("libc.so.6")  # doctest: +LINUX
    <CDLL 'libc.so.6', handle ... at ...>
-   >>> libc = CDLL("libc.so.6")     # doctest: +LINUX
-   >>> libc                         # doctest: +LINUX
+   >>> libc = CDLL("libc.so.6")       # doctest: +LINUX
+   >>> libc                           # doctest: +LINUX
    <CDLL 'libc.so.6', handle ... at ...>
    >>>
 
@@ -86,9 +93,9 @@ Functions are accessed as attributes of dll objects::
    >>> from ctypes import *
    >>> libc.printf
    <_FuncPtr object at 0x...>
-   >>> print(windll.kernel32.GetModuleHandleA) # doctest: +WINDOWS
+   >>> print(windll.kernel32.GetModuleHandleA)  # doctest: +WINDOWS
    <_FuncPtr object at 0x...>
-   >>> print(windll.kernel32.MyOwnFunction) # doctest: +WINDOWS
+   >>> print(windll.kernel32.MyOwnFunction)     # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "ctypes.py", line 239, in __getattr__
@@ -117,16 +124,16 @@ Sometimes, dlls export functions with names which aren't valid Python
 identifiers, like ``"??2@YAPAXI@Z"``. In this case you have to use
 :func:`getattr` to retrieve the function::
 
-   >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") # doctest: +WINDOWS
+   >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z")  # doctest: +WINDOWS
    <_FuncPtr object at 0x...>
    >>>
 
 On Windows, some dlls export functions not by name but by ordinal. These
 functions can be accessed by indexing the dll object with the ordinal number::
 
-   >>> cdll.kernel32[1] # doctest: +WINDOWS
+   >>> cdll.kernel32[1]  # doctest: +WINDOWS
    <_FuncPtr object at 0x...>
-   >>> cdll.kernel32[0] # doctest: +WINDOWS
+   >>> cdll.kernel32[0]  # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "ctypes.py", line 310, in __getitem__
@@ -148,9 +155,9 @@ handle.
 This example calls both functions with a NULL pointer (``None`` should be used
 as the NULL pointer)::
 
-   >>> print(libc.time(None)) # doctest: +SKIP
+   >>> print(libc.time(None))  # doctest: +SKIP
    1150640792
-   >>> print(hex(windll.kernel32.GetModuleHandleA(None))) # doctest: +WINDOWS
+   >>> print(hex(windll.kernel32.GetModuleHandleA(None)))  # doctest: +WINDOWS
    0x1d000000
    >>>
 
@@ -159,11 +166,11 @@ of arguments or the wrong calling convention.  Unfortunately this only works on
 Windows.  It does this by examining the stack after the function returns, so
 although an error is raised the function *has* been called::
 
-   >>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWS
+   >>> windll.kernel32.GetModuleHandleA()      # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: Procedure probably called with not enough arguments (4 bytes missing)
-   >>> windll.kernel32.GetModuleHandleA(0, 0) # doctest: +WINDOWS
+   >>> windll.kernel32.GetModuleHandleA(0, 0)  # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: Procedure probably called with too many arguments (4 bytes in excess)
@@ -172,13 +179,13 @@ although an error is raised the function *has* been called::
 The same exception is raised when you call an ``stdcall`` function with the
 ``cdecl`` calling convention, or vice versa::
 
-   >>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWS
+   >>> cdll.kernel32.GetModuleHandleA(None)  # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: Procedure probably called with not enough arguments (4 bytes missing)
    >>>
 
-   >>> windll.msvcrt.printf(b"spam") # doctest: +WINDOWS
+   >>> windll.msvcrt.printf(b"spam")  # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: Procedure probably called with too many arguments (4 bytes in excess)
@@ -191,7 +198,7 @@ On Windows, :mod:`ctypes` uses win32 structured exception handling to prevent
 crashes from general protection faults when functions are called with invalid
 argument values::
 
-   >>> windll.kernel32.GetModuleHandleA(32) # doctest: +WINDOWS
+   >>> windll.kernel32.GetModuleHandleA(32)  # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    OSError: exception: access violation reading 0x00000020
@@ -456,9 +463,9 @@ Here is a more advanced example, it uses the ``strchr`` function, which expects
 a string pointer and a char, and returns a pointer to a string::
 
    >>> strchr = libc.strchr
-   >>> strchr(b"abcdef", ord("d")) # doctest: +SKIP
+   >>> strchr(b"abcdef", ord("d"))  # doctest: +SKIP
    8059983
-   >>> strchr.restype = c_char_p   # c_char_p is a pointer to a string
+   >>> strchr.restype = c_char_p    # c_char_p is a pointer to a string
    >>> strchr(b"abcdef", ord("d"))
    b'def'
    >>> print(strchr(b"abcdef", ord("x")))
@@ -489,17 +496,17 @@ callable will be called with the *integer* the C function returns, and the
 result of this call will be used as the result of your function call. This is
 useful to check for error return values and automatically raise an exception::
 
-   >>> GetModuleHandle = windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
+   >>> GetModuleHandle = windll.kernel32.GetModuleHandleA  # doctest: +WINDOWS
    >>> def ValidHandle(value):
    ...     if value == 0:
    ...         raise WinError()
    ...     return value
    ...
    >>>
-   >>> GetModuleHandle.restype = ValidHandle # doctest: +WINDOWS
-   >>> GetModuleHandle(None) # doctest: +WINDOWS
+   >>> GetModuleHandle.restype = ValidHandle  # doctest: +WINDOWS
+   >>> GetModuleHandle(None)  # doctest: +WINDOWS
    486539264
-   >>> GetModuleHandle("something silly") # doctest: +WINDOWS
+   >>> GetModuleHandle("something silly")  # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 3, in ValidHandle
@@ -665,17 +672,17 @@ positive integer::
 
    TenPointsArrayType = POINT * 10
 
-Here is an example of an somewhat artificial data type, a structure containing 4
+Here is an example of a somewhat artificial data type, a structure containing 4
 POINTs among other stuff::
 
    >>> from ctypes import *
    >>> class POINT(Structure):
-   ...    _fields_ = ("x", c_int), ("y", c_int)
+   ...     _fields_ = ("x", c_int), ("y", c_int)
    ...
    >>> class MyStruct(Structure):
-   ...    _fields_ = [("a", c_int),
-   ...                ("b", c_float),
-   ...                ("point_array", POINT * 4)]
+   ...     _fields_ = [("a", c_int),
+   ...                 ("b", c_float),
+   ...                 ("point_array", POINT * 4)]
    >>>
    >>> print(len(MyStruct().point_array))
    4
@@ -716,8 +723,8 @@ Pointer instances are created by calling the :func:`pointer` function on a
    >>> pi = pointer(i)
    >>>
 
-Pointer instances have a :attr:`contents` attribute which returns the object to
-which the pointer points, the ``i`` object above::
+Pointer instances have a :attr:`~_Pointer.contents` attribute which
+returns the object to which the pointer points, the ``i`` object above::
 
    >>> pi.contents
    c_long(42)
@@ -942,7 +949,7 @@ other, and finally follow the pointer chain a few times::
 Callback functions
 ^^^^^^^^^^^^^^^^^^
 
-:mod:`ctypes` allows to create C callable function pointers from Python callables.
+:mod:`ctypes` allows creating C callable function pointers from Python callables.
 These are sometimes called *callback functions*.
 
 First, you must create a class for the callback function. The class knows the
@@ -992,7 +999,7 @@ passed::
 
 The result::
 
-   >>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +LINUX
+   >>> qsort(ia, len(ia), sizeof(c_int), cmp_func)  # doctest: +LINUX
    py_cmp_func 5 1
    py_cmp_func 33 99
    py_cmp_func 7 33
@@ -1094,14 +1101,15 @@ access violation or whatever, so it's better to break out of the loop when we
 hit the NULL entry::
 
    >>> for item in table:
-   ...    print(item.name, item.size)
-   ...    if item.name is None:
-   ...        break
+   ...     if item.name is None:
+   ...         break
+   ...     print(item.name.decode("ascii"), item.size)
    ...
-   __hello__ 104
-   __phello__ -104
-   __phello__.spam 104
-   None 0
+   _frozen_importlib 31764
+   _frozen_importlib_external 41499
+   __hello__ 161
+   __phello__ -161
+   __phello__.spam 161
    >>>
 
 The fact that standard Python has a frozen module and a frozen package
@@ -1291,7 +1299,7 @@ module instead of using :func:`find_library` to locate the library at runtime.
 Loading shared libraries
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
-There are several ways to loaded shared libraries into the Python process.  One
+There are several ways to load shared libraries into the Python process.  One
 way is to instantiate one of the following classes:
 
 
@@ -1350,7 +1358,7 @@ details, consult the :manpage:`dlopen(3)` manpage, on Windows, *mode* is
 ignored.
 
 The *use_errno* parameter, when set to True, enables a ctypes mechanism that
-allows to access the system :data:`errno` error number in a safe way.
+allows accessing the system :data:`errno` error number in a safe way.
 :mod:`ctypes` maintains a thread-local copy of the systems :data:`errno`
 variable; if you call foreign functions created with ``use_errno=True`` then the
 :data:`errno` value before the function call is swapped with the ctypes private
@@ -1421,7 +1429,7 @@ loader instance.
    Class which loads shared libraries.  *dlltype* should be one of the
    :class:`CDLL`, :class:`PyDLL`, :class:`WinDLL`, or :class:`OleDLL` types.
 
-   :meth:`__getattr__` has special behavior: It allows to load a shared library by
+   :meth:`__getattr__` has special behavior: It allows loading a shared library by
    accessing it as attribute of a library loader instance.  The result is cached,
    so repeated attribute accesses return the same library each time.
 
@@ -1498,7 +1506,7 @@ They are instances of a private class:
 
       It is possible to assign a callable Python object that is not a ctypes
       type, in this case the function is assumed to return a C :c:type:`int`, and
-      the callable will be called with this integer, allowing to do further
+      the callable will be called with this integer, allowing further
       processing or error checking.  Using this is deprecated, for more flexible
       post processing or error checking use a ctypes data type as
       :attr:`restype` and assign a callable to the :attr:`errcheck` attribute.
@@ -1513,7 +1521,7 @@ They are instances of a private class:
 
       When a foreign function is called, each actual argument is passed to the
       :meth:`from_param` class method of the items in the :attr:`argtypes`
-      tuple, this method allows to adapt the actual argument to an object that
+      tuple, this method allows adapting the actual argument to an object that
       the foreign function accepts.  For example, a :class:`c_char_p` item in
       the :attr:`argtypes` tuple will convert a string passed as argument into
       a bytes object using ctypes conversion rules.
@@ -1521,7 +1529,7 @@ They are instances of a private class:
       New: It is now possible to put items in argtypes which are not ctypes
       types, but each item must have a :meth:`from_param` method which returns a
       value usable as argument (integer, string, ctypes instance).  This allows
-      to define adapters that can adapt custom objects as function parameters.
+      defining adapters that can adapt custom objects as function parameters.
 
    .. attribute:: errcheck
 
@@ -1535,12 +1543,12 @@ They are instances of a private class:
          *result* is what the foreign function returns, as specified by the
          :attr:`restype` attribute.
 
-         *func* is the foreign function object itself, this allows to reuse the
+         *func* is the foreign function object itself, this allows reusing the
          same callable object to check or post process the results of several
          functions.
 
          *arguments* is a tuple containing the parameters originally passed to
-         the function call, this allows to specialize the behavior on the
+         the function call, this allows specializing the behavior on the
          arguments used.
 
       The object that this function returns will be returned from the
@@ -1785,7 +1793,7 @@ Utility functions
    If a bytes object is specified as first argument, the buffer is made one item
    larger than its length so that the last element in the array is a NUL
    termination character. An integer can be passed as second argument which allows
-   to specify the size of the array if the length of the bytes should not be used.
+   specifying the size of the array if the length of the bytes should not be used.
 
 
 
@@ -1800,21 +1808,21 @@ Utility functions
    If a string is specified as first argument, the buffer is made one item
    larger than the length of the string so that the last element in the array is a
    NUL termination character. An integer can be passed as second argument which
-   allows to specify the size of the array if the length of the string should not
+   allows specifying the size of the array if the length of the string should not
    be used.
 
 
 
 .. function:: DllCanUnloadNow()
 
-   Windows only: This function is a hook which allows to implement in-process
+   Windows only: This function is a hook which allows implementing in-process
    COM servers with ctypes.  It is called from the DllCanUnloadNow function that
    the _ctypes extension dll exports.
 
 
 .. function:: DllGetClassObject()
 
-   Windows only: This function is a hook which allows to implement in-process
+   Windows only: This function is a hook which allows implementing in-process
    COM servers with ctypes.  It is called from the DllGetClassObject function
    that the ``_ctypes`` extension dll exports.
 
@@ -1882,7 +1890,7 @@ Utility functions
 .. function:: POINTER(type)
 
    This factory function creates and returns a new ctypes pointer type. Pointer
-   types are cached an reused internally, so calling this function repeatedly is
+   types are cached and reused internally, so calling this function repeatedly is
    cheap. *type* must be a ctypes type.
 
 
@@ -2321,7 +2329,7 @@ other data types containing pointer type fields.
       checked, only one field can be accessed when names are repeated.
 
       It is possible to define the :attr:`_fields_` class variable *after* the
-      class statement that defines the Structure subclass, this allows to create
+      class statement that defines the Structure subclass, this allows creating
       data types that directly or indirectly reference themselves::
 
          class List(Structure):
@@ -2342,7 +2350,7 @@ other data types containing pointer type fields.
 
    .. attribute:: _pack_
 
-      An optional small integer that allows to override the alignment of
+      An optional small integer that allows overriding the alignment of
       structure fields in the instance.  :attr:`_pack_` must already be defined
       when :attr:`_fields_` is assigned, otherwise it will have no effect.
 
@@ -2354,8 +2362,8 @@ other data types containing pointer type fields.
       assigned, otherwise it will have no effect.
 
       The fields listed in this variable must be structure or union type fields.
-      :mod:`ctypes` will create descriptors in the structure type that allows to
-      access the nested fields directly, without the need to create the
+      :mod:`ctypes` will create descriptors in the structure type that allows
+      accessing the nested fields directly, without the need to create the
       structure or union field.
 
       Here is an example type (Windows)::
@@ -2401,6 +2409,56 @@ other data types containing pointer type fields.
 Arrays and pointers
 ^^^^^^^^^^^^^^^^^^^
 
-Not yet written - please see the sections :ref:`ctypes-pointers` and section
-:ref:`ctypes-arrays` in the tutorial.
+.. class:: Array(\*args)
+
+   Abstract base class for arrays.
+
+   The recommended way to create concrete array types is by multiplying any
+   :mod:`ctypes` data type with a positive integer.  Alternatively, you can subclass
+   this type and define :attr:`_length_` and :attr:`_type_` class variables.
+   Array elements can be read and written using standard
+   subscript and slice accesses; for slice reads, the resulting object is
+   *not* itself an :class:`Array`.
+
+
+   .. attribute:: _length_
+
+        A positive integer specifying the number of elements in the array.
+        Out-of-range subscripts result in an :exc:`IndexError`. Will be
+        returned by :func:`len`.
+
+
+   .. attribute:: _type_
+
+        Specifies the type of each element in the array.
+
+
+   Array subclass constructors accept positional arguments, used to
+   initialize the elements in order.
+
+
+.. class:: _Pointer
+
+   Private, abstract base class for pointers.
+
+   Concrete pointer types are created by calling :func:`POINTER` with the
+   type that will be pointed to; this is done automatically by
+   :func:`pointer`.
+
+   If a pointer points to an array, its elements can be read and
+   written using standard subscript and slice accesses.  Pointer objects
+   have no size, so :func:`len` will raise :exc:`TypeError`.  Negative
+   subscripts will read from the memory *before* the pointer (as in C), and
+   out-of-range subscripts will probably crash with an access violation (if
+   you're lucky).
+
+
+   .. attribute:: _type_
+
+        Specifies the type pointed to.
+
+   .. attribute:: contents
+
+        Returns the object to which to pointer points.  Assigning to this
+        attribute changes the pointer to point to the assigned object.
 
index 6bc1fb9..f3661d9 100644 (file)
@@ -3,9 +3,11 @@
 
 .. module:: curses.ascii
    :synopsis: Constants and set-membership functions for ASCII characters.
+
 .. moduleauthor:: Eric S. Raymond <esr@thyrsus.com>
 .. sectionauthor:: Eric S. Raymond <esr@thyrsus.com>
 
+--------------
 
 The :mod:`curses.ascii` module supplies name constants for ASCII characters and
 functions to test membership in various ASCII character classes.  The constants
index a3c8bda..c99c37a 100644 (file)
@@ -3,8 +3,10 @@
 
 .. module:: curses.panel
    :synopsis: A panel stack extension that adds depth to  curses windows.
+
 .. sectionauthor:: A.M. Kuchling <amk@amk.ca>
 
+--------------
 
 Panels are windows with the added feature of depth, so they can be stacked on
 top of each other, and only the visible portions of each window will be
index e8dfd83..b12a325 100644 (file)
@@ -5,9 +5,12 @@
    :synopsis: An interface to the curses library, providing portable
               terminal handling.
    :platform: Unix
+
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 .. sectionauthor:: Eric Raymond <esr@thyrsus.com>
 
+--------------
+
 The :mod:`curses` module provides an interface to the curses library, the
 de-facto standard for portable advanced terminal handling.
 
@@ -1508,9 +1511,9 @@ keys); also, the following keypad mappings are standard:
 +------------------+-----------+
 | :kbd:`End`       | KEY_END   |
 +------------------+-----------+
-| :kbd:`Page Up`   | KEY_NPAGE |
+| :kbd:`Page Up`   | KEY_PPAGE |
 +------------------+-----------+
-| :kbd:`Page Down` | KEY_PPAGE |
+| :kbd:`Page Down` | KEY_NPAGE |
 +------------------+-----------+
 
 The following table lists characters from the alternate character set. These are
index 976cd49..9254ae8 100644 (file)
@@ -3,12 +3,15 @@
 
 .. module:: datetime
    :synopsis: Basic date and time types.
+
 .. moduleauthor:: Tim Peters <tim@zope.com>
 .. sectionauthor:: Tim Peters <tim@zope.com>
 .. sectionauthor:: A.M. Kuchling <amk@amk.ca>
 
 **Source code:** :source:`Lib/datetime.py`
 
+--------------
+
 .. XXX what order should the types be discussed in?
 
 The :mod:`datetime` module supplies classes for manipulating dates and times in
@@ -33,7 +36,7 @@ particular number represents metres, miles, or mass.  Naive objects are easy to
 understand and to work with, at the cost of ignoring some aspects of reality.
 
 For applications requiring aware objects, :class:`.datetime` and :class:`.time`
-objects have an optional time zone information attribute, :attr:`tzinfo`, that
+objects have an optional time zone information attribute, :attr:`!tzinfo`, that
 can be set to an instance of a subclass of the abstract :class:`tzinfo` class.
 These :class:`tzinfo` objects capture information about the offset from UTC
 time, the time zone name, and whether Daylight Saving Time is in effect.  Note
@@ -85,7 +88,7 @@ Available Types
    An idealized time, independent of any particular day, assuming that every day
    has exactly 24\*60\*60 seconds (there is no notion of "leap seconds" here).
    Attributes: :attr:`hour`, :attr:`minute`, :attr:`second`, :attr:`microsecond`,
-   and :attr:`tzinfo`.
+   and :attr:`.tzinfo`.
 
 
 .. class:: datetime
@@ -93,7 +96,7 @@ Available Types
 
    A combination of a date and a time. Attributes: :attr:`year`, :attr:`month`,
    :attr:`day`, :attr:`hour`, :attr:`minute`, :attr:`second`, :attr:`microsecond`,
-   and :attr:`tzinfo`.
+   and :attr:`.tzinfo`.
 
 
 .. class:: timedelta
@@ -104,6 +107,7 @@ Available Types
 
 
 .. class:: tzinfo
+   :noindex:
 
    An abstract base class for time zone information objects.  These are used by the
    :class:`.datetime` and :class:`.time` classes to provide a customizable notion of
@@ -111,6 +115,7 @@ Available Types
    time).
 
 .. class:: timezone
+   :noindex:
 
    A class that implements the :class:`tzinfo` abstract base class as a
    fixed offset from the UTC.
@@ -560,7 +565,7 @@ Instance methods:
    Return a 3-tuple, (ISO year, ISO week number, ISO weekday).
 
    The ISO calendar is a widely used variant of the Gregorian calendar. See
-   http://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm for a good
+   https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm for a good
    explanation.
 
    The ISO year consists of 52 or 53 full weeks, and where a week starts on a
@@ -604,7 +609,7 @@ Instance methods:
 
 .. method:: date.__format__(format)
 
-   Same as :meth:`.date.strftime`. This makes it possible to specify format
+   Same as :meth:`.date.strftime`. This makes it possible to specify format
    string for a :class:`.date` object when using :meth:`str.format`. For a
    complete list of formatting directives, see
    :ref:`strftime-strptime-behavior`.
@@ -697,7 +702,7 @@ Other constructors, all class methods:
 
 .. classmethod:: datetime.today()
 
-   Return the current local datetime, with :attr:`tzinfo` ``None``. This is
+   Return the current local datetime, with :attr:`.tzinfo` ``None``. This is
    equivalent to ``datetime.fromtimestamp(time.time())``. See also :meth:`now`,
    :meth:`fromtimestamp`.
 
@@ -710,15 +715,15 @@ Other constructors, all class methods:
    (for example, this may be possible on platforms supplying the C
    :c:func:`gettimeofday` function).
 
-   Else *tz* must be an instance of a class :class:`tzinfo` subclass, and the
-   current date and time are converted to *tz*'s time zone.  In this case the
+   If *tz* is not ``None``, it must be an instance of a :class:`tzinfo` subclass, and the
+   current date and time are converted to *tz*s time zone.  In this case the
    result is equivalent to ``tz.fromutc(datetime.utcnow().replace(tzinfo=tz))``.
    See also :meth:`today`, :meth:`utcnow`.
 
 
 .. classmethod:: datetime.utcnow()
 
-   Return the current UTC date and time, with :attr:`tzinfo` ``None``. This is like
+   Return the current UTC date and time, with :attr:`.tzinfo` ``None``. This is like
    :meth:`now`, but returns the current UTC date and time, as a naive
    :class:`.datetime` object.  An aware current UTC datetime can be obtained by
    calling ``datetime.now(timezone.utc)``.  See also :meth:`now`.
@@ -730,8 +735,8 @@ Other constructors, all class methods:
    specified, the timestamp is converted to the platform's local date and time, and
    the returned :class:`.datetime` object is naive.
 
-   Else *tz* must be an instance of a class :class:`tzinfo` subclass, and the
-   timestamp is converted to *tz*'s time zone.  In this case the result is
+   If *tz* is not ``None``, it must be an instance of a :class:`tzinfo` subclass, and the
+   timestamp is converted to *tz*s time zone.  In this case the result is
    equivalent to
    ``tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))``.
 
@@ -756,7 +761,7 @@ Other constructors, all class methods:
 .. classmethod:: datetime.utcfromtimestamp(timestamp)
 
    Return the UTC :class:`.datetime` corresponding to the POSIX timestamp, with
-   :attr:`tzinfo` ``None``. This may raise :exc:`OverflowError`, if the timestamp is
+   :attr:`.tzinfo` ``None``. This may raise :exc:`OverflowError`, if the timestamp is
    out of the range of values supported by the platform C :c:func:`gmtime` function,
    and :exc:`OSError` on :c:func:`gmtime` failure.
    It's common for this to be restricted to years in 1970 through 2038.
@@ -785,17 +790,17 @@ Other constructors, all class methods:
    Return the :class:`.datetime` corresponding to the proleptic Gregorian ordinal,
    where January 1 of year 1 has ordinal 1. :exc:`ValueError` is raised unless ``1
    <= ordinal <= datetime.max.toordinal()``.  The hour, minute, second and
-   microsecond of the result are all 0, and :attr:`tzinfo` is ``None``.
+   microsecond of the result are all 0, and :attr:`.tzinfo` is ``None``.
 
 
 .. classmethod:: datetime.combine(date, time)
 
    Return a new :class:`.datetime` object whose date components are equal to the
-   given :class:`date` object's, and whose time components and :attr:`tzinfo`
+   given :class:`date` object's, and whose time components and :attr:`.tzinfo`
    attributes are equal to the given :class:`.time` object's. For any
    :class:`.datetime` object *d*,
    ``d == datetime.combine(d.date(), d.timetz())``.  If date is a
-   :class:`.datetime` object, its time components and :attr:`tzinfo` attributes
+   :class:`.datetime` object, its time components and :attr:`.tzinfo` attributes
    are ignored.
 
 
@@ -891,7 +896,7 @@ Supported operations:
 (1)
    datetime2 is a duration of timedelta removed from datetime1, moving forward in
    time if ``timedelta.days`` > 0, or backward if ``timedelta.days`` < 0.  The
-   result has the same :attr:`tzinfo` attribute as the input datetime, and
+   result has the same :attr:`~.datetime.tzinfo` attribute as the input datetime, and
    datetime2 - datetime1 == timedelta after. :exc:`OverflowError` is raised if
    datetime2.year would be smaller than :const:`MINYEAR` or larger than
    :const:`MAXYEAR`. Note that no time zone adjustments are done even if the
@@ -899,7 +904,7 @@ Supported operations:
 
 (2)
    Computes the datetime2 such that datetime2 + timedelta == datetime1. As for
-   addition, the result has the same :attr:`tzinfo` attribute as the input
+   addition, the result has the same :attr:`~.datetime.tzinfo` attribute as the input
    datetime, and no time zone adjustments are done even if the input is aware.
    This isn't quite equivalent to datetime1 + (-timedelta), because -timedelta
    in isolation can overflow in cases where datetime1 - timedelta does not.
@@ -909,12 +914,12 @@ Supported operations:
    both operands are naive, or if both are aware.  If one is aware and the other is
    naive, :exc:`TypeError` is raised.
 
-   If both are naive, or both are aware and have the same :attr:`tzinfo` attribute,
-   the :attr:`tzinfo` attributes are ignored, and the result is a :class:`timedelta`
+   If both are naive, or both are aware and have the same :attr:`~.datetime.tzinfo` attribute,
+   the :attr:`~.datetime.tzinfo` attributes are ignored, and the result is a :class:`timedelta`
    object *t* such that ``datetime2 + t == datetime1``.  No time zone adjustments
    are done in this case.
 
-   If both are aware and have different :attr:`tzinfo` attributes, ``a-b`` acts
+   If both are aware and have different :attr:`~.datetime.tzinfo` attributes, ``a-b`` acts
    as if *a* and *b* were first converted to naive UTC datetimes first.  The
    result is ``(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None)
    - b.utcoffset())`` except that the implementation never overflows.
@@ -927,14 +932,14 @@ Supported operations:
    is raised if an order comparison is attempted.  For equality
    comparisons, naive instances are never equal to aware instances.
 
-   If both comparands are aware, and have the same :attr:`tzinfo` attribute, the
-   common :attr:`tzinfo` attribute is ignored and the base datetimes are
-   compared.  If both comparands are aware and have different :attr:`tzinfo`
+   If both comparands are aware, and have the same :attr:`~.datetime.tzinfo` attribute, the
+   common :attr:`~.datetime.tzinfo` attribute is ignored and the base datetimes are
+   compared.  If both comparands are aware and have different :attr:`~.datetime.tzinfo`
    attributes, the comparands are first adjusted by subtracting their UTC
    offsets (obtained from ``self.utcoffset()``).
 
    .. versionchanged:: 3.3
-      Equality comparisons between naive and aware :class:`datetime`
+      Equality comparisons between naive and aware :class:`.datetime`
       instances don't raise :exc:`TypeError`.
 
    .. note::
@@ -962,7 +967,7 @@ Instance methods:
 .. method:: datetime.time()
 
    Return :class:`.time` object with same hour, minute, second and microsecond.
-   :attr:`tzinfo` is ``None``.  See also method :meth:`timetz`.
+   :attr:`.tzinfo` is ``None``.  See also method :meth:`timetz`.
 
 
 .. method:: datetime.timetz()
@@ -981,7 +986,7 @@ Instance methods:
 
 .. method:: datetime.astimezone(tz=None)
 
-   Return a :class:`datetime` object with new :attr:`tzinfo` attribute *tz*,
+   Return a :class:`.datetime` object with new :attr:`.tzinfo` attribute *tz*,
    adjusting the date and time data so the result is the same UTC time as
    *self*, but in *tz*'s local time.
 
@@ -991,7 +996,7 @@ Instance methods:
    not return ``None``).
 
    If called without arguments (or with ``tz=None``) the system local
-   timezone is assumed.  The ``tzinfo`` attribute of the converted
+   timezone is assumed.  The ``.tzinfo`` attribute of the converted
    datetime instance will be set to an instance of :class:`timezone`
    with the zone name and offset obtained from the OS.
 
@@ -1027,7 +1032,7 @@ Instance methods:
 
 .. method:: datetime.utcoffset()
 
-   If :attr:`tzinfo` is ``None``, returns ``None``, else returns
+   If :attr:`.tzinfo` is ``None``, returns ``None``, else returns
    ``self.tzinfo.utcoffset(self)``, and raises an exception if the latter doesn't
    return ``None``, or a :class:`timedelta` object representing a whole number of
    minutes with magnitude less than one day.
@@ -1035,7 +1040,7 @@ Instance methods:
 
 .. method:: datetime.dst()
 
-   If :attr:`tzinfo` is ``None``, returns ``None``, else returns
+   If :attr:`.tzinfo` is ``None``, returns ``None``, else returns
    ``self.tzinfo.dst(self)``, and raises an exception if the latter doesn't return
    ``None``, or a :class:`timedelta` object representing a whole number of minutes
    with magnitude less than one day.
@@ -1043,7 +1048,7 @@ Instance methods:
 
 .. method:: datetime.tzname()
 
-   If :attr:`tzinfo` is ``None``, returns ``None``, else returns
+   If :attr:`.tzinfo` is ``None``, returns ``None``, else returns
    ``self.tzinfo.tzname(self)``, raises an exception if the latter doesn't return
    ``None`` or a string object,
 
@@ -1055,7 +1060,7 @@ Instance methods:
    d.hour, d.minute, d.second, d.weekday(), yday, dst))``, where ``yday =
    d.toordinal() - date(d.year, 1, 1).toordinal() + 1`` is the day number within
    the current year starting with ``1`` for January 1st. The :attr:`tm_isdst` flag
-   of the result is set according to the :meth:`dst` method: :attr:`tzinfo` is
+   of the result is set according to the :meth:`dst` method: :attr:`.tzinfo` is
    ``None`` or :meth:`dst` returns ``None``, :attr:`tm_isdst` is set to ``-1``;
    else if :meth:`dst` returns a non-zero value, :attr:`tm_isdst` is set to ``1``;
    else :attr:`tm_isdst` is set to ``0``.
@@ -1082,18 +1087,18 @@ Instance methods:
 
 .. method:: datetime.timestamp()
 
-   Return POSIX timestamp corresponding to the :class:`datetime`
+   Return POSIX timestamp corresponding to the :class:`.datetime`
    instance.  The return value is a :class:`float` similar to that
    returned by :func:`time.time`.
 
-   Naive :class:`datetime` instances are assumed to represent local
+   Naive :class:`.datetime` instances are assumed to represent local
    time and this method relies on the platform C :c:func:`mktime`
-   function to perform the conversion.  Since :class:`datetime`
+   function to perform the conversion.  Since :class:`.datetime`
    supports wider range of values than :c:func:`mktime` on many
    platforms, this method may raise :exc:`OverflowError` for times far
    in the past or far in the future.
 
-   For aware :class:`datetime` instances, the return value is computed
+   For aware :class:`.datetime` instances, the return value is computed
    as::
 
       (dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()
@@ -1103,7 +1108,7 @@ Instance methods:
    .. note::
 
       There is no method to obtain the POSIX timestamp directly from a
-      naive :class:`datetime` instance representing UTC time.  If your
+      naive :class:`.datetime` instance representing UTC time.  If your
       application uses this convention and your system timezone is not
       set to UTC, you can obtain the POSIX timestamp by supplying
       ``tzinfo=timezone.utc``::
@@ -1179,7 +1184,7 @@ Instance methods:
 
 .. method:: datetime.__format__(format)
 
-   Same as :meth:`.datetime.strftime`.  This makes it possible to specify format
+   Same as :meth:`.datetime.strftime`.  This makes it possible to specify format
    string for a :class:`.datetime` object when using :meth:`str.format`.  For a
    complete list of formatting directives, see
    :ref:`strftime-strptime-behavior`.
@@ -1367,9 +1372,9 @@ Supported operations:
   comparisons, naive instances are never equal to aware instances.
 
   If both comparands are aware, and have
-  the same :attr:`tzinfo` attribute, the common :attr:`tzinfo` attribute is
+  the same :attr:`~time.tzinfo` attribute, the common :attr:`~time.tzinfo` attribute is
   ignored and the base times are compared.  If both comparands are aware and
-  have different :attr:`tzinfo` attributes, the comparands are first adjusted by
+  have different :attr:`~time.tzinfo` attributes, the comparands are first adjusted by
   subtracting their UTC offsets (obtained from ``self.utcoffset()``). In order
   to stop mixed-type comparisons from falling back to the default comparison by
   object address, when a :class:`.time` object is compared to an object of a
@@ -1424,7 +1429,7 @@ Instance methods:
 
 .. method:: time.__format__(format)
 
-   Same as :meth:`.time.strftime`. This makes it possible to specify format string
+   Same as :meth:`.time.strftime`. This makes it possible to specify format string
    for a :class:`.time` object when using :meth:`str.format`.  For a
    complete list of formatting directives, see
    :ref:`strftime-strptime-behavior`.
@@ -1432,7 +1437,7 @@ Instance methods:
 
 .. method:: time.utcoffset()
 
-   If :attr:`tzinfo` is ``None``, returns ``None``, else returns
+   If :attr:`.tzinfo` is ``None``, returns ``None``, else returns
    ``self.tzinfo.utcoffset(None)``, and raises an exception if the latter doesn't
    return ``None`` or a :class:`timedelta` object representing a whole number of
    minutes with magnitude less than one day.
@@ -1440,7 +1445,7 @@ Instance methods:
 
 .. method:: time.dst()
 
-   If :attr:`tzinfo` is ``None``, returns ``None``, else returns
+   If :attr:`.tzinfo` is ``None``, returns ``None``, else returns
    ``self.tzinfo.dst(None)``, and raises an exception if the latter doesn't return
    ``None``, or a :class:`timedelta` object representing a whole number of minutes
    with magnitude less than one day.
@@ -1448,7 +1453,7 @@ Instance methods:
 
 .. method:: time.tzname()
 
-   If :attr:`tzinfo` is ``None``, returns ``None``, else returns
+   If :attr:`.tzinfo` is ``None``, returns ``None``, else returns
    ``self.tzinfo.tzname(None)``, or raises an exception if the latter doesn't
    return ``None`` or a string object.
 
@@ -1485,28 +1490,30 @@ Example:
 :class:`tzinfo` Objects
 -----------------------
 
-:class:`tzinfo` is an abstract base class, meaning that this class should not be
-instantiated directly.  You need to derive a concrete subclass, and (at least)
-supply implementations of the standard :class:`tzinfo` methods needed by the
-:class:`.datetime` methods you use.  The :mod:`datetime` module supplies
-a simple concrete subclass of :class:`tzinfo` :class:`timezone` which can represent
-timezones with fixed offset from UTC such as UTC itself or North American EST and
-EDT.
+.. class:: tzinfo()
+
+   This is an abstract base class, meaning that this class should not be
+   instantiated directly.  You need to derive a concrete subclass, and (at least)
+   supply implementations of the standard :class:`tzinfo` methods needed by the
+   :class:`.datetime` methods you use.  The :mod:`datetime` module supplies
+   a simple concrete subclass of :class:`tzinfo`, :class:`timezone`, which can represent
+   timezones with fixed offset from UTC such as UTC itself or North American EST and
+   EDT.
 
-An instance of (a concrete subclass of) :class:`tzinfo` can be passed to the
-constructors for :class:`.datetime` and :class:`.time` objects. The latter objects
-view their attributes as being in local time, and the :class:`tzinfo` object
-supports methods revealing offset of local time from UTC, the name of the time
-zone, and DST offset, all relative to a date or time object passed to them.
+   An instance of (a concrete subclass of) :class:`tzinfo` can be passed to the
+   constructors for :class:`.datetime` and :class:`.time` objects. The latter objects
+   view their attributes as being in local time, and the :class:`tzinfo` object
+   supports methods revealing offset of local time from UTC, the name of the time
+   zone, and DST offset, all relative to a date or time object passed to them.
 
-Special requirement for pickling:  A :class:`tzinfo` subclass must have an
-:meth:`__init__` method that can be called with no arguments, else it can be
-pickled but possibly not unpickled again.  This is a technical requirement that
-may be relaxed in the future.
+   Special requirement for pickling:  A :class:`tzinfo` subclass must have an
+   :meth:`__init__` method that can be called with no arguments, else it can be
+   pickled but possibly not unpickled again.  This is a technical requirement that
+   may be relaxed in the future.
 
-A concrete subclass of :class:`tzinfo` may need to implement the following
-methods.  Exactly which methods are needed depends on the uses made of aware
-:mod:`datetime` objects.  If in doubt, simply implement all of them.
+   A concrete subclass of :class:`tzinfo` may need to implement the following
+   methods.  Exactly which methods are needed depends on the uses made of aware
+   :mod:`datetime` objects.  If in doubt, simply implement all of them.
 
 
 .. method:: tzinfo.utcoffset(dt)
@@ -1539,7 +1546,7 @@ methods.  Exactly which methods are needed depends on the uses made of aware
    (see :meth:`utcoffset` for details). Note that DST offset, if applicable, has
    already been added to the UTC offset returned by :meth:`utcoffset`, so there's
    no need to consult :meth:`dst` unless you're interested in obtaining DST info
-   separately.  For example, :meth:`datetime.timetuple` calls its :attr:`tzinfo`
+   separately.  For example, :meth:`datetime.timetuple` calls its :attr:`~.datetime.tzinfo`
    attribute's :meth:`dst` method to determine how the :attr:`tm_isdst` flag
    should be set, and :meth:`tzinfo.fromutc` calls :meth:`dst` to account for
    DST changes when crossing time zones.
@@ -1704,7 +1711,7 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)).
       *pytz* library brings the *IANA timezone database* (also known as the
       Olson database) to Python and its usage is recommended.
 
-   `IANA timezone database <http://www.iana.org/time-zones>`_
+   `IANA timezone database <https://www.iana.org/time-zones>`_
       The Time Zone Database (often called tz or zoneinfo) contains code and
       data that represent the history of local time for many representative
       locations around the globe. It is updated periodically to reflect changes
@@ -1865,7 +1872,7 @@ format codes.
 +-----------+--------------------------------+------------------------+-------+
 | ``%z``    | UTC offset in the form +HHMM   | (empty), +0000, -0400, | \(6)  |
 |           | or -HHMM (empty string if the  | +1030                  |       |
-|           | the object is naive).          |                        |       |
+|           | object is naive).              |                        |       |
 +-----------+--------------------------------+------------------------+-------+
 | ``%Z``    | Time zone name (empty string   | (empty), UTC, EST, CST |       |
 |           | if the object is naive).       |                        |       |
index 3f3c43d..6f64196 100644 (file)
@@ -4,10 +4,14 @@
 .. module:: dbm
    :synopsis: Interfaces to various Unix "database" formats.
 
+**Source code:** :source:`Lib/dbm/__init__.py`
+
+--------------
+
 :mod:`dbm` is a generic interface to variants of the DBM database ---
 :mod:`dbm.gnu` or :mod:`dbm.ndbm`.  If none of these modules is installed, the
 slow-but-simple implementation in module :mod:`dbm.dumb` will be used.  There
-is a `third party interface <http://www.jcea.es/programacion/pybsddb.htm>`_ to
+is a `third party interface <https://www.jcea.es/programacion/pybsddb.htm>`_ to
 the Oracle Berkeley DB.
 
 
index 2de0ea0..528f97b 100644 (file)
@@ -23,6 +23,8 @@
    # make sure each group gets a fresh context
    setcontext(Context())
 
+--------------
+
 The :mod:`decimal` module provides support for fast correctly-rounded
 decimal floating point arithmetic. It offers several advantages over the
 :class:`float` datatype:
@@ -109,9 +111,6 @@ reset them before monitoring a calculation.
    * IBM's General Decimal Arithmetic Specification, `The General Decimal Arithmetic
      Specification <http://speleotrove.com/decimal/decarith.html>`_.
 
-   * IEEE standard 854-1987, `Unofficial IEEE 854 Text
-     <http://754r.ucbtest.org/standards/854.pdf>`_.
-
 .. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
index e7e5df6..59a6478 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: difflib
    :synopsis: Helpers for computing differences between objects.
+
 .. moduleauthor:: Tim Peters <tim_one@users.sourceforge.net>
 .. sectionauthor:: Tim Peters <tim_one@users.sourceforge.net>
 .. Markup by Fred L. Drake, Jr. <fdrake@acm.org>
@@ -14,6 +15,8 @@
    import sys
    from difflib import *
 
+--------------
+
 This module provides classes and functions for comparing sequences. It
 can be used for example, for comparing files, and can produce difference
 information in various formats, including HTML and context and unified
@@ -501,16 +504,14 @@ The :class:`SequenceMatcher` class has this constructor:
       |               | are equal).                                 |
       +---------------+---------------------------------------------+
 
-      For example:
+      For example::
 
         >>> a = "qabxcd"
         >>> b = "abycdf"
         >>> s = SequenceMatcher(None, a, b)
         >>> for tag, i1, i2, j1, j2 in s.get_opcodes():
-            print('{:7}   a[{}:{}] --> b[{}:{}] {!r:>8} --> {!r}'.format(
-                tag, i1, i2, j1, j2, a[i1:i2], b[j1:j2]))
-
-
+        ...     print('{:7}   a[{}:{}] --> b[{}:{}] {!r:>8} --> {!r}'.format(
+        ...         tag, i1, i2, j1, j2, a[i1:i2], b[j1:j2]))
         delete    a[0:1] --> b[0:0]      'q' --> ''
         equal     a[1:3] --> b[0:2]     'ab' --> 'ab'
         replace   a[3:4] --> b[2:3]      'x' --> 'y'
@@ -615,7 +616,7 @@ If you want to know how to change the first sequence into the second, use
      work.
 
    * `Simple version control recipe
-     <http://code.activestate.com/recipes/576729/>`_ for a small application
+     <https://code.activestate.com/recipes/576729/>`_ for a small application
      built with :class:`SequenceMatcher`.
 
 
index 1bcb3a4..d2d8ac7 100644 (file)
@@ -139,11 +139,11 @@ operation is being performed, so the intermediate analysis object isn't useful:
    Disassemble the *x* object.  *x* can denote either a module, a class, a
    method, a function, a generator, a code object, a string of source code or
    a byte sequence of raw bytecode.  For a module, it disassembles all functions.
-   For a class, it disassembles all methods.  For a code object or sequence of
-   raw bytecode, it prints one line per bytecode instruction.  Strings are first
-   compiled to code objects with the :func:`compile` built-in function before being
-   disassembled.  If no object is provided, this function disassembles the last
-   traceback.
+   For a class, it disassembles all methods (including class and static methods).
+   For a code object or sequence of raw bytecode, it prints one line per bytecode
+   instruction.  Strings are first compiled to code objects with the :func:`compile`
+   built-in function before being disassembled.  If no object is provided, this
+   function disassembles the last traceback.
 
    The disassembly is written as text to the supplied *file* argument if
    provided and to ``sys.stdout`` otherwise.
@@ -708,7 +708,7 @@ the more significant byte last.
 
    Implements assignment with a starred target: Unpacks an iterable in TOS into
    individual values, where the total number of values can be smaller than the
-   number of items in the iterable: one the new values will be a list of all
+   number of items in the iterable: one of the new values will be a list of all
    leftover items.
 
    The low byte of *counts* is the number of values before the list value, the
index e3d1314..62abc85 100644 (file)
@@ -4,8 +4,10 @@
 .. module:: distutils
    :synopsis: Support for building and installing Python modules into an
               existing Python installation.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
+--------------
 
 The :mod:`distutils` package provides support for building and installing
 additional modules into a Python installation.  The new modules may be either
@@ -15,7 +17,7 @@ collections of Python packages which include modules coded in both Python and C.
 Most Python users will *not* want to use this module directly, but instead
 use the cross-version tools maintained by the Python Packaging Authority. In
 particular,
-`setuptools <https://setuptools.pypa.io/en/latest/setuptools.html>`__ is an
+`setuptools <https://setuptools.readthedocs.io/en/latest/>`__ is an
 enhanced alternative to :mod:`distutils` that provides:
 
 * support for declaring project dependencies
index 9f7d12c..c58f417 100644 (file)
@@ -5,11 +5,15 @@
 
 .. module:: doctest
    :synopsis: Test pieces of code within docstrings.
+
 .. moduleauthor:: Tim Peters <tim@python.org>
 .. sectionauthor:: Tim Peters <tim@python.org>
 .. sectionauthor:: Moshe Zadka <moshez@debian.org>
 .. sectionauthor:: Edward Loper <edloper@users.sourceforge.net>
 
+**Source code:** :source:`Lib/doctest.py`
+
+--------------
 
 The :mod:`doctest` module searches for pieces of text that look like interactive
 Python sessions, and then executes those sessions to verify that they work
index 80ef3d6..161d86a 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.charset
    :synopsis: Character Sets
 
+**Source code:** :source:`Lib/email/charset.py`
+
+--------------
 
 This module provides a class :class:`Charset` for representing character sets
 and character set conversions in email messages, as well as a character set
@@ -101,9 +104,10 @@ Import this class from the :mod:`email.charset` module.
       returns the string ``base64`` if *body_encoding* is ``BASE64``, and
       returns the string ``7bit`` otherwise.
 
+
    .. XXX to_splittable and from_splittable are not there anymore!
 
-   .. method to_splittable(s)
+   .. to_splittable(s)
 
       Convert a possibly multibyte string to a safely splittable format. *s* is
       the string to split.
@@ -118,7 +122,7 @@ Import this class from the :mod:`email.charset` module.
       the Unicode replacement character ``'U+FFFD'``.
 
 
-   .. method from_splittable(ustr[, to_output])
+   .. from_splittable(ustr[, to_output])
 
       Convert a splittable string back into an encoded string.  *ustr* is a
       Unicode string to "unsplit".
index f53d34b..cd63728 100644 (file)
@@ -7,6 +7,10 @@
 .. moduleauthor:: R. David Murray <rdmurray@bitdance.com>
 .. sectionauthor:: R. David Murray <rdmurray@bitdance.com>
 
+.. versionadded:: 3.4
+   as a :term:`provisional module <provisional package>`.
+
+**Source code:** :source:`Lib/email/contentmanager.py`
 
 .. note::
 
@@ -15,8 +19,7 @@
    changes (up to and including removal of the module) may occur if deemed
    necessary by the core developers.
 
-.. versionadded:: 3.4
-   as a :term:`provisional module <provisional package>`.
+--------------
 
 The :mod:`~email.message` module provides a class that can represent an
 arbitrary email message.  That basic message model has a useful and flexible
index 916ba5d..9d7f9bf 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.encoders
    :synopsis: Encoders for email message payloads.
 
+**Source code:** :source:`Lib/email/encoders.py`
+
+--------------
 
 When creating :class:`~email.message.Message` objects from scratch, you often
 need to encode the payloads for transport through compliant mail servers. This
index 294e3ed..8470783 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.errors
    :synopsis: The exception classes used by the email package.
 
+**Source code:** :source:`Lib/email/errors.py`
+
+--------------
 
 The following exception classes are defined in the :mod:`email.errors` module:
 
index 48d41e1..d596ed8 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.generator
    :synopsis: Generate flat text email messages from a message structure.
 
+**Source code:** :source:`Lib/email/generator.py`
+
+--------------
 
 One of the most common tasks is to generate the flat text of the email message
 represented by a message object structure.  You will need to do this if you want
@@ -43,7 +46,7 @@ Here are the public methods of the :class:`Generator` class, imported from the
    followed by a space at the beginning of the line.  This is the only guaranteed
    portable way to avoid having such lines be mistaken for a Unix mailbox format
    envelope header separator (see `WHY THE CONTENT-LENGTH FORMAT IS BAD
-   <http://www.jwz.org/doc/content-length.html>`_ for details).  *mangle_from_*
+   <https://www.jwz.org/doc/content-length.html>`_ for details).  *mangle_from_*
    defaults to ``True``, but you might want to set this to ``False`` if you are not
    writing Unix mailbox format files.
 
@@ -123,7 +126,7 @@ formatted string representation of a message object.  For more detail, see
    i.e. ``From`` followed by a space at the beginning of the line.  This is the
    only guaranteed portable way to avoid having such lines be mistaken for a
    Unix mailbox format envelope header separator (see `WHY THE CONTENT-LENGTH
-   FORMAT IS BAD <http://www.jwz.org/doc/content-length.html>`_ for details).
+   FORMAT IS BAD <https://www.jwz.org/doc/content-length.html>`_ for details).
    *mangle_from_* defaults to ``True``, but you might want to set this to
    ``False`` if you are not writing Unix mailbox format files.
 
index 346d23f..e94837c 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.header
    :synopsis: Representing non-ASCII headers
 
+**Source code:** :source:`Lib/email/header.py`
+
+--------------
 
 :rfc:`2822` is the base standard that describes the format of email messages.
 It derives from the older :rfc:`822` standard which came into widespread use at
index db3aade..0707bd8 100644 (file)
@@ -7,6 +7,10 @@
 .. moduleauthor:: R. David Murray <rdmurray@bitdance.com>
 .. sectionauthor:: R. David Murray <rdmurray@bitdance.com>
 
+.. versionadded:: 3.3
+   as a :term:`provisional module <provisional package>`.
+
+**Source code:** :source:`Lib/email/headerregistry.py`
 
 .. note::
 
@@ -15,8 +19,7 @@
    changes (up to and including removal of the module) may occur if deemed
    necessary by the core developers.
 
-.. versionadded:: 3.3
-   as a :term:`provisional module <provisional package>`.
+--------------
 
 Headers are represented by customized subclasses of :class:`str`.  The
 particular class used to represent a given header is determined by the
@@ -171,7 +174,7 @@ headers.
    :class:`~datetime.datetime` instance.  This means, for example, that
    the following code is valid and does what one would expect::
 
-       msg['Date']  = datetime(2011, 7, 15, 21)
+       msg['Date'] = datetime(2011, 7, 15, 21)
 
    Because this is a naive ``datetime`` it will be interpreted as a UTC
    timestamp, and the resulting value will have a timezone of ``-0000``.  Much
index f92f460..f3e9e18 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.iterators
    :synopsis: Iterate over a  message object tree.
 
+**Source code:** :source:`Lib/email/iterators.py`
+
+--------------
 
 Iterating over a message object tree is fairly easy with the
 :meth:`Message.walk <email.message.Message.walk>` method.  The
index b91f26d..91a694f 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.message
    :synopsis: The base class representing email messages.
 
+**Source code:** :source:`Lib/email/message.py`
+
+--------------
 
 The central class in the :mod:`email` package is the :class:`Message` class,
 imported from the :mod:`email.message` module.  It is the base class for the
index 67d0a67..8297dea 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.mime
    :synopsis: Build MIME messages.
 
+**Source code:** :source:`Lib/email/mime/`
+
+--------------
 
 Ordinarily, you get a message object structure by passing a file or some text to
 a parser, which parses the text and returns the root message object.  However
index 177adc6..93c09ad 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.parser
    :synopsis: Parse flat text email messages to produce a message object structure.
 
+**Source code:** :source:`Lib/email/parser.py`
+
+--------------
 
 Message object structures can be created in one of two ways: they can be created
 from whole cloth by instantiating :class:`~email.message.Message` objects and
index 045b119..47f3212 100644 (file)
@@ -9,6 +9,9 @@
 
 .. versionadded:: 3.3
 
+**Source code:** :source:`Lib/email/policy.py`
+
+--------------
 
 The :mod:`email` package's prime focus is the handling of email messages as
 described by the various email and MIME RFCs.  However, the general format of
index 95c0a2f..e8bb02b 100644 (file)
@@ -4,10 +4,14 @@
 .. module:: email
    :synopsis: Package supporting the parsing, manipulating, and generating
               email messages, including MIME documents.
+
 .. moduleauthor:: Barry A. Warsaw <barry@python.org>
 .. sectionauthor:: Barry A. Warsaw <barry@python.org>
 .. Copyright (C) 2001-2010 Python Software Foundation
 
+**Source code:** :source:`Lib/email/__init__.py`
+
+--------------
 
 The :mod:`email` package is a library for managing email messages, including
 MIME and other :rfc:`2822`\ -based message documents.  It is specifically *not*
index 219e284..5cff746 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: email.utils
    :synopsis: Miscellaneous email package utilities.
 
+**Source code:** :source:`Lib/email/utils.py`
+
+--------------
 
 There are several useful utilities provided in the :mod:`email.utils` module:
 
index d589f1c..6aeeabc 100644 (file)
@@ -7,6 +7,8 @@
 
 .. versionadded:: 3.4
 
+--------------
+
 The :mod:`ensurepip` package provides support for bootstrapping the ``pip``
 installer into an existing Python installation or virtual environment. This
 bootstrapping approach reflects the fact that ``pip`` is an independent
index 81f97b3..60467b4 100644 (file)
@@ -314,8 +314,8 @@ Then::
     >>> str(Mood.funky)
     'my custom str! 1'
 
-The rules for what is allowed are as follows: names that start and end with a
-with a single underscore are reserved by enum and cannot be used; all other
+The rules for what is allowed are as follows: names that start and end with
+a single underscore are reserved by enum and cannot be used; all other
 attributes defined within an enumeration will become members of this
 enumeration, with the exception of special methods (:meth:`__str__`,
 :meth:`__add__`, etc.) and descriptors (methods are also descriptors).
@@ -555,12 +555,12 @@ Some rules:
 3. When another data type is mixed in, the :attr:`value` attribute is *not the
    same* as the enum member itself, although it is equivalent and will compare
    equal.
-4. %-style formatting:  `%s` and `%r` call :class:`Enum`'s :meth:`__str__` and
-   :meth:`__repr__` respectively; other codes (such as `%i` or `%h` for
-   IntEnum) treat the enum member as its mixed-in type.
-5. :meth:`str.__format__` (or :func:`format`) will use the mixed-in
-   type's :meth:`__format__`.  If the :class:`Enum`'s :func:`str` or
-   :func:`repr` is desired use the `!s` or `!r` :class:`str` format codes.
+4. %-style formatting:  `%s` and `%r` call the :class:`Enum` class's
+   :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as
+   `%i` or `%h` for IntEnum) treat the enum member as its mixed-in type.
+5. :meth:`str.format` (or :func:`format`) will use the mixed-in
+   type's :meth:`__format__`.  If the :class:`Enum` class's :func:`str` or
+   :func:`repr` is desired, use the `!s` or `!r` format codes.
 
 
 Interesting examples
index 22a5cbc..1cbd51c 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: errno
    :synopsis: Standard errno system symbols.
 
+----------------
 
 This module makes available standard ``errno`` system symbols. The value of each
 symbol is the corresponding integer value. The names and descriptions are
index ba6122e..5a71933 100644 (file)
@@ -288,7 +288,7 @@ The following exceptions are the exceptions that are usually raised.
 
    .. versionchanged:: 3.3
       :exc:`EnvironmentError`, :exc:`IOError`, :exc:`WindowsError`,
-      :exc:`VMSError`, :exc:`socket.error`, :exc:`select.error` and
+      :exc:`socket.error`, :exc:`select.error` and
       :exc:`mmap.error` have been merged into :exc:`OSError`, and the
       constructor may return a subclass.
 
index 3a5badd..deedea1 100644 (file)
@@ -6,6 +6,8 @@
 
 .. versionadded:: 3.3
 
+----------------
+
 This module contains functions to dump Python tracebacks explicitly, on a fault,
 after a timeout, or on a user signal. Call :func:`faulthandler.enable` to
 install fault handlers for the :const:`SIGSEGV`, :const:`SIGFPE`,
index f8bb834..88112f6 100644 (file)
@@ -4,15 +4,19 @@
 .. module:: fcntl
    :platform: Unix
    :synopsis: The fcntl() and ioctl() system calls.
-.. sectionauthor:: Jaap Vermeulen
 
+.. sectionauthor:: Jaap Vermeulen
 
 .. index::
    pair: UNIX; file control
    pair: UNIX; I/O control
 
+----------------
+
 This module performs file control and I/O control on file descriptors. It is an
-interface to the :c:func:`fcntl` and :c:func:`ioctl` Unix routines.
+interface to the :c:func:`fcntl` and :c:func:`ioctl` Unix routines.  For a
+complete description of these calls, see :manpage:`fcntl(2)` and
+:manpage:`ioctl(2)` Unix manual pages.
 
 All functions in this module take a file descriptor *fd* as their first
 argument.  This can be an integer file descriptor, such as returned by
@@ -83,7 +87,7 @@ The module defines the following functions:
    buffer 1024 bytes long which is then passed to :func:`ioctl` and copied back
    into the supplied buffer.
 
-   If the :c:func:`ioctl` fails, an :exc:`IOError` exception is raised.
+   If the :c:func:`ioctl` fails, an :exc:`OSError` exception is raised.
 
    An example::
 
@@ -106,7 +110,7 @@ The module defines the following functions:
    :manpage:`flock(2)` for details.  (On some systems, this function is emulated
    using :c:func:`fcntl`.)
 
-   If the :c:func:`flock` fails, an :exc:`IOError` exception is raised.
+   If the :c:func:`flock` fails, an :exc:`OSError` exception is raised.
 
 
 .. function:: lockf(fd, cmd, len=0, start=0, whence=0)
index 06d3f21..31b9b4a 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: filecmp
    :synopsis: Compare files efficiently.
+
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
 **Source code:** :source:`Lib/filecmp.py`
index ee06830..aa4c529 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: fileinput
    :synopsis: Loop over standard input or a list of files.
+
 .. moduleauthor:: Guido van Rossum <guido@python.org>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
@@ -71,6 +72,9 @@ The following function is the primary interface of this module:
    .. versionchanged:: 3.2
       Can be used as a context manager.
 
+   .. versionchanged:: 3.5.2
+      The *bufsize* parameter is no longer used.
+
 
 The following functions use the global state created by :func:`fileinput.input`;
 if there is no active state, :exc:`RuntimeError` is raised.
@@ -161,7 +165,10 @@ available for subclassing as well:
       Can be used as a context manager.
 
    .. deprecated:: 3.4
-        The ``'rU'`` and ``'U'`` modes.
+      The ``'rU'`` and ``'U'`` modes.
+
+   .. versionchanged:: 3.5.2
+      The *bufsize* parameter is no longer used.
 
 
 **Optional in-place filtering:** if the keyword argument ``inplace=True`` is
@@ -190,7 +197,7 @@ The two following opening hooks are provided by this module:
 
 .. function:: hook_encoded(encoding)
 
-   Returns a hook which opens each file with :func:`codecs.open`, using the given
+   Returns a hook which opens each file with :func:`open`, using the given
    *encoding* to read the file.
 
    Usage example: ``fi =
index 68b437f..85ac484 100644 (file)
@@ -4,13 +4,12 @@
 .. module:: fnmatch
    :synopsis: Unix shell style filename pattern matching.
 
+**Source code:** :source:`Lib/fnmatch.py`
 
 .. index:: single: filenames; wildcard expansion
 
 .. index:: module: re
 
-**Source code:** :source:`Lib/fnmatch.py`
-
 --------------
 
 This module provides support for Unix shell-style wildcards, which are *not* the
index 8e8e201..6c10ac6 100644 (file)
@@ -8,6 +8,7 @@
 .. deprecated:: 3.4
    Due to lack of usage, the formatter module has been deprecated.
 
+--------------
 
 This module supports two interface definitions, each with multiple
 implementations: The *formatter* interface, and the *writer* interface which is
index fb15f69..e4b528c 100644 (file)
@@ -4,10 +4,10 @@
 .. module:: fpectl
    :platform: Unix
    :synopsis: Provide control for floating point exception handling.
+
 .. moduleauthor:: Lee Busby <busby1@llnl.gov>
 .. sectionauthor:: Lee Busby <busby1@llnl.gov>
 
-
 .. note::
 
    The :mod:`fpectl` module is not built by default, and its usage is discouraged
@@ -16,6 +16,8 @@
 
 .. index:: single: IEEE-754
 
+--------------
+
 Most computers carry out floating point operations in conformance with the
 so-called IEEE-754 standard. On any real computer, some floating point
 operations produce results that cannot be expressed as a normal floating point
index d24f80a..b5a818e 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: fractions
    :synopsis: Rational numbers.
+
 .. moduleauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
 .. sectionauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
 
index f06e678..233e11f 100644 (file)
@@ -4,19 +4,18 @@
 .. module:: ftplib
    :synopsis: FTP protocol client (requires sockets).
 
+**Source code:** :source:`Lib/ftplib.py`
 
 .. index::
    pair: FTP; protocol
    single: FTP; ftplib (standard module)
 
-**Source code:** :source:`Lib/ftplib.py`
-
 --------------
 
 This module defines the class :class:`FTP` and a few related items. The
 :class:`FTP` class implements the client side of the FTP protocol.  You can use
 this to write Python programs that perform a variety of automated FTP jobs, such
-as mirroring other ftp servers.  It is also used by the module
+as mirroring other FTP servers.  It is also used by the module
 :mod:`urllib.request` to handle URLs that use FTP.  For more information on FTP
 (File Transfer Protocol), see Internet :rfc:`959`.
 
@@ -148,12 +147,6 @@ The module defines the following items:
       typically used by FTP clients to load user authentication information
       before prompting the user.
 
-   .. index:: single: ftpmirror.py
-
-   The file :file:`Tools/scripts/ftpmirror.py` in the Python source distribution is
-   a script that can mirror FTP sites, or portions thereof, using the :mod:`ftplib`
-   module. It can be used as an extended example that applies this module.
-
 
 .. _ftp-objects:
 
@@ -314,7 +307,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
 
 .. method:: FTP.mlsd(path="", facts=[])
 
-   List a directory in a standardized format by using MLSD command
+   List a directory in a standardized format by using ``MLSD`` command
    (:rfc:`3659`).  If *path* is omitted the current directory is assumed.
    *facts* is a list of strings representing the type of information desired
    (e.g. ``["type", "size", "perm"]``).  Return a generator object yielding a
@@ -333,7 +326,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
    directory).  Multiple arguments can be used to pass non-standard options to
    the ``NLST`` command.
 
-   .. deprecated:: 3.3 use :meth:`mlsd` instead.
+   .. note:: If your server supports the command, :meth:`mlsd` offers a better API.
 
 
 .. method:: FTP.dir(argument[, ...])
@@ -345,7 +338,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
    as a *callback* function as for :meth:`retrlines`; the default prints to
    ``sys.stdout``.  This method returns ``None``.
 
-   .. deprecated:: 3.3 use :meth:`mlsd` instead.
+   .. note:: If your server supports the command, :meth:`mlsd` offers a better API.
 
 
 .. method:: FTP.rename(fromname, toname)
index c8de062..c3563f3 100644 (file)
@@ -158,7 +158,7 @@ are always available.  They are listed here in alphabetical order.
 
    Return the string representing a character whose Unicode code point is the
    integer *i*.  For example, ``chr(97)`` returns the string ``'a'``, while
-   ``chr(957)`` returns the string ``'ν'``. This is the inverse of :func:`ord`.
+   ``chr(8364)`` returns the string ``'€'``. This is the inverse of :func:`ord`.
 
    The valid range for the argument is from 0 through 1,114,111 (0x10FFFF in
    base 16).  :exc:`ValueError` will be raised if *i* is outside that range.
@@ -230,7 +230,7 @@ are always available.  They are listed here in alphabetical order.
    or ``2`` (docstrings are removed too).
 
    This function raises :exc:`SyntaxError` if the compiled source is invalid,
-   and :exc:`TypeError` if the source contains null bytes.
+   and :exc:`ValueError` if the source contains null bytes.
 
    If you want to parse Python code into its AST representation, see
    :func:`ast.parse`.
@@ -246,6 +246,10 @@ are always available.  They are listed here in alphabetical order.
       Allowed use of Windows and Mac newlines.  Also input in ``'exec'`` mode
       does not have to end in a newline anymore.  Added the *optimize* parameter.
 
+   .. versionchanged:: 3.5
+      Previously, :exc:`TypeError` was raised when null bytes were encountered
+      in *source*.
+
 
 .. class:: complex([real[, imag]])
 
@@ -1070,13 +1074,15 @@ are always available.  They are listed here in alphabetical order.
       exception, the function now retries the system call instead of raising an
       :exc:`InterruptedError` exception (see :pep:`475` for the rationale).
 
+   .. versionchanged:: 3.5
+      The ``'namereplace'`` error handler was added.
 
 .. function:: ord(c)
 
    Given a string representing one Unicode character, return an integer
    representing the Unicode code point of that character.  For example,
-   ``ord('a')`` returns the integer ``97`` and ``ord('ν')`` returns ``957``.
-   This is the inverse of :func:`chr`.
+   ``ord('a')`` returns the integer ``97`` and ``ord('€')`` (Euro sign)
+   returns ``8364``.  This is the inverse of :func:`chr`.
 
 
 .. function:: pow(x, y[, z])
@@ -1306,8 +1312,7 @@ are always available.  They are listed here in alphabetical order.
    compare equal --- this is helpful for sorting in multiple passes (for
    example, sort by department, then by salary grade).
 
-   For sorting examples and a brief sorting tutorial, see `Sorting HowTo
-   <https://wiki.python.org/moin/HowTo/Sorting/>`_\.
+   For sorting examples and a brief sorting tutorial, see :ref:`sortinghowto`.
 
 .. function:: staticmethod(function)
 
@@ -1415,7 +1420,7 @@ are always available.  They are listed here in alphabetical order.
 
    For practical suggestions on how to design cooperative classes using
    :func:`super`, see `guide to using super()
-   <http://rhettinger.wordpress.com/2011/05/26/super-considered-super/>`_.
+   <https://rhettinger.wordpress.com/2011/05/26/super-considered-super/>`_.
 
 
 .. _func-tuple:
@@ -1444,8 +1449,9 @@ are always available.  They are listed here in alphabetical order.
    class name and becomes the :attr:`~class.__name__` attribute; the *bases*
    tuple itemizes the base classes and becomes the :attr:`~class.__bases__`
    attribute; and the *dict* dictionary is the namespace containing definitions
-   for class body and becomes the :attr:`~object.__dict__` attribute.  For
-   example, the following two statements create identical :class:`type` objects:
+   for class body and is copied to a standard dictionary to become the
+   :attr:`~object.__dict__` attribute.  For example, the following two
+   statements create identical :class:`type` objects:
 
       >>> class X:
       ...     a = 1
index 46aa887..abdd66f 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: functools
    :synopsis: Higher-order functions and operations on callable objects.
+
 .. moduleauthor:: Peter Harris <scav@blueyonder.co.uk>
 .. moduleauthor:: Raymond Hettinger <python@rcn.com>
 .. moduleauthor:: Nick Coghlan <ncoghlan@gmail.com>
@@ -73,7 +74,7 @@ The :mod:`functools` module defines the following functions:
    bypassing the cache, or for rewrapping the function with a different cache.
 
    An `LRU (least recently used) cache
-   <http://en.wikipedia.org/wiki/Cache_algorithms#Examples>`_ works
+   <https://en.wikipedia.org/wiki/Cache_algorithms#Examples>`_ works
    best when the most recent calls are the best predictors of upcoming calls (for
    example, the most popular articles on a news server tend to change each day).
    The cache's size limit assures that the cache does not grow without bound on
@@ -99,9 +100,9 @@ The :mod:`functools` module defines the following functions:
         CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
 
    Example of efficiently computing
-   `Fibonacci numbers <http://en.wikipedia.org/wiki/Fibonacci_number>`_
+   `Fibonacci numbers <https://en.wikipedia.org/wiki/Fibonacci_number>`_
    using a cache to implement a
-   `dynamic programming <http://en.wikipedia.org/wiki/Dynamic_programming>`_
+   `dynamic programming <https://en.wikipedia.org/wiki/Dynamic_programming>`_
    technique::
 
         @lru_cache(maxsize=None)
@@ -176,7 +177,7 @@ The :mod:`functools` module defines the following functions:
           def newfunc(*fargs, **fkeywords):
               newkeywords = keywords.copy()
               newkeywords.update(fkeywords)
-              return func(*(args + fargs), **newkeywords)
+              return func(*args, *fargs, **newkeywords)
           newfunc.func = func
           newfunc.args = args
           newfunc.keywords = keywords
@@ -375,10 +376,10 @@ The :mod:`functools` module defines the following functions:
    assigned directly to the matching attributes on the wrapper function and which
    attributes of the wrapper function are updated with the corresponding attributes
    from the original function. The default values for these arguments are the
-   module level constants *WRAPPER_ASSIGNMENTS* (which assigns to the wrapper
-   function's *__name__*, *__module__*, *__annotations__* and *__doc__*, the
-   documentation string) and *WRAPPER_UPDATES* (which updates the wrapper
-   function's *__dict__*, i.e. the instance dictionary).
+   module level constants ``WRAPPER_ASSIGNMENTS`` (which assigns to the wrapper
+   function's ``__module__``, ``__name__``, ``__qualname__``, ``__annotations__``
+   and ``__doc__``, the documentation string) and ``WRAPPER_UPDATES`` (which
+   updates the wrapper function's ``__dict__``, i.e. the instance dictionary).
 
    To allow access to the original function for introspection and other purposes
    (e.g. bypassing a caching decorator such as :func:`lru_cache`), this function
index d11c2e1..4af16a9 100644 (file)
@@ -3,9 +3,11 @@
 
 .. module:: gc
    :synopsis: Interface to the cycle-detecting garbage collector.
+
 .. moduleauthor:: Neil Schemenauer <nas@arctrix.com>
 .. sectionauthor:: Neil Schemenauer <nas@arctrix.com>
 
+--------------
 
 This module provides an interface to the optional garbage collector.  It
 provides the ability to disable the collector, tune the collection frequency,
index f9a1e53..336deab 100644 (file)
@@ -7,8 +7,6 @@
 
 **Source code:** :source:`Lib/getopt.py`
 
---------------
-
 .. note::
 
    The :mod:`getopt` module is a parser for command line options whose API is
@@ -17,6 +15,8 @@
    less code and get better help and error messages should consider using the
    :mod:`argparse` module instead.
 
+--------------
+
 This module helps scripts to parse the command line arguments in ``sys.argv``.
 It supports the same conventions as the Unix :c:func:`getopt` function (including
 the special meanings of arguments of the form '``-``' and '``--``').  Long
@@ -124,7 +124,7 @@ In a script, typical usage is something like this::
            opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
        except getopt.GetoptError as err:
            # print help information and exit:
-           print(err) # will print something like "option -a not recognized"
+           print(err)  # will print something like "option -a not recognized"
            usage()
            sys.exit(2)
        output = None
index 211563e..5eb9f04 100644 (file)
@@ -3,10 +3,15 @@
 
 .. module:: getpass
    :synopsis: Portable reading of passwords and retrieval of the userid.
+
 .. moduleauthor:: Piers Lauder <piers@cs.su.oz.au>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. Windows (& Mac?) support by Guido van Rossum.
 
+**Source code:** :source:`Lib/getpass.py`
+
+--------------
+
 The :mod:`getpass` module provides two functions:
 
 
@@ -23,8 +28,6 @@ The :mod:`getpass` module provides two functions:
    a warning message to *stream* and reading from ``sys.stdin`` and
    issuing a :exc:`GetPassWarning`.
 
-   Availability: Macintosh, Unix, Windows.
-
    .. note::
       If you call getpass from within IDLE, the input may be done in the
       terminal you launched IDLE from rather than the idle window itself.
@@ -36,7 +39,7 @@ The :mod:`getpass` module provides two functions:
 
 .. function:: getuser()
 
-   Return the "login name" of the user. Availability: Unix, Windows.
+   Return the "login name" of the user.
 
    This function checks the environment variables :envvar:`LOGNAME`,
    :envvar:`USER`, :envvar:`LNAME` and :envvar:`USERNAME`, in order, and returns
index 514cc5a..ea439b5 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: gettext
    :synopsis: Multilingual internationalization services.
+
 .. moduleauthor:: Barry A. Warsaw <barry@python.org>
 .. sectionauthor:: Barry A. Warsaw <barry@python.org>
 
index 4c01bf6..328eef3 100644 (file)
@@ -4,11 +4,10 @@
 .. module:: glob
    :synopsis: Unix shell style pathname pattern expansion.
 
+**Source code:** :source:`Lib/glob.py`
 
 .. index:: single: filenames; pathname expansion
 
-**Source code:** :source:`Lib/glob.py`
-
 --------------
 
 The :mod:`glob` module finds all the pathnames matching a specified pattern
index 8882140..a30e622 100644 (file)
@@ -5,6 +5,7 @@
    :platform: Unix
    :synopsis: The group database (getgrnam() and friends).
 
+--------------
 
 This module provides access to the Unix group database. It is available on all
 Unix versions.
index 769f96f..30be335 100644 (file)
@@ -3,16 +3,16 @@
 
 .. module:: hashlib
    :synopsis: Secure hash and message digest algorithms.
+
 .. moduleauthor:: Gregory P. Smith <greg@krypto.org>
 .. sectionauthor:: Gregory P. Smith <greg@krypto.org>
 
+**Source code:** :source:`Lib/hashlib.py`
 
 .. index::
    single: message digest, MD5
    single: secure hash algorithm, SHA1, SHA224, SHA256, SHA384, SHA512
 
-**Source code:** :source:`Lib/hashlib.py`
-
 --------------
 
 This module implements a common interface to many different secure hash and
@@ -41,7 +41,7 @@ Hash algorithms
 There is one constructor method named for each type of :dfn:`hash`.  All return
 a hash object with the same simple interface. For example: use :func:`sha1` to
 create a SHA1 hash object. You can now feed this object with :term:`bytes-like
-object`\ s (normally :class:`bytes`) using the :meth:`update` method.
+objects <bytes-like object>` (normally :class:`bytes`) using the :meth:`update` method.
 At any point you can ask it for the :dfn:`digest` of the
 concatenation of the data fed to it so far using the :meth:`digest` or
 :meth:`hexdigest` methods.
@@ -185,22 +185,23 @@ brute-force attacks. A good password hashing function must be tunable, slow, and
 include a `salt <https://en.wikipedia.org/wiki/Salt_%28cryptography%29>`_.
 
 
-.. function:: pbkdf2_hmac(name, password, salt, rounds, dklen=None)
+.. function:: pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)
 
    The function provides PKCS#5 password-based key derivation function 2. It
    uses HMAC as pseudorandom function.
 
-   The string *name* is the desired name of the hash digest algorithm for
+   The string *hash_name* is the desired name of the hash digest algorithm for
    HMAC, e.g. 'sha1' or 'sha256'. *password* and *salt* are interpreted as
    buffers of bytes. Applications and libraries should limit *password* to
-   a sensible value (e.g. 1024). *salt* should be about 16 or more bytes from
+   a sensible length (e.g. 1024). *salt* should be about 16 or more bytes from
    a proper source, e.g. :func:`os.urandom`.
 
-   The number of *rounds* should be chosen based on the hash algorithm and
-   computing power. As of 2013, at least 100,000 rounds of SHA-256 is suggested.
+   The number of *iterations* should be chosen based on the hash algorithm and
+   computing power. As of 2013, at least 100,000 iterations of SHA-256 are
+   suggested.
 
    *dklen* is the length of the derived key. If *dklen* is ``None`` then the
-   digest size of the hash algorithm *name* is used, e.g. 64 for SHA-512.
+   digest size of the hash algorithm *hash_name* is used, e.g. 64 for SHA-512.
 
    >>> import hashlib, binascii
    >>> dk = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000)
@@ -231,5 +232,5 @@ include a `salt <https://en.wikipedia.org/wiki/Salt_%28cryptography%29>`_.
       Wikipedia article with information on which algorithms have known issues and
       what that means regarding their use.
 
-   http://www.ietf.org/rfc/rfc2898.txt
+   https://www.ietf.org/rfc/rfc2898.txt
       PKCS #5: Password-Based Cryptography Specification Version 2.0
index 9fbbcc6..7e33e74 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: heapq
    :synopsis: Heap queue algorithm (a.k.a. priority queue).
+
 .. moduleauthor:: Kevin O'Connor
 .. sectionauthor:: Guido van Rossum <guido@python.org>
 .. sectionauthor:: François Pinard
@@ -132,7 +133,7 @@ the iterable into an actual heap.
 Basic Examples
 --------------
 
-A `heapsort <http://en.wikipedia.org/wiki/Heapsort>`_ can be implemented by
+A `heapsort <https://en.wikipedia.org/wiki/Heapsort>`_ can be implemented by
 pushing all values onto a heap and then popping off the smallest values one at a
 time::
 
@@ -163,7 +164,7 @@ Heap elements can be tuples.  This is useful for assigning comparison values
 Priority Queue Implementation Notes
 -----------------------------------
 
-A `priority queue <http://en.wikipedia.org/wiki/Priority_queue>`_ is common use
+A `priority queue <https://en.wikipedia.org/wiki/Priority_queue>`_ is common use
 for a heap, and it presents several implementation challenges:
 
 * Sort stability:  how do you get two tasks with equal priorities to be returned
@@ -242,7 +243,7 @@ for a tournament.  The numbers below are *k*, not ``a[k]``::
 
    15 16   17 18   19 20   21 22   23 24   25 26   27 28   29 30
 
-In the tree above, each cell *k* is topping ``2*k+1`` and ``2*k+2``. In an usual
+In the tree above, each cell *k* is topping ``2*k+1`` and ``2*k+2``. In a usual
 binary tournament we see in sports, each cell is the winner over the two cells
 it tops, and we can trace the winner down the tree to see all opponents s/he
 had.  However, in many computer applications of such tournaments, we do not need
index 1446da6..bb44866 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: hmac
    :synopsis: Keyed-Hashing for Message Authentication (HMAC) implementation
+
 .. moduleauthor:: Gerhard Häring <ghaering@users.sourceforge.net>
 .. sectionauthor:: Gerhard Häring <ghaering@users.sourceforge.net>
 
index e10e46e..067e1b1 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: html.entities
    :synopsis: Definitions of HTML general entities.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
 **Source code:** :source:`Lib/html/entities.py`
@@ -43,4 +44,4 @@ This module defines four dictionaries, :data:`html5`,
 
 .. rubric:: Footnotes
 
-.. [#] See http://www.w3.org/TR/html5/syntax.html#named-character-references
+.. [#] See https://www.w3.org/TR/html5/syntax.html#named-character-references
index 824995e..16abb40 100644 (file)
@@ -4,13 +4,12 @@
 .. module:: html.parser
    :synopsis: A simple parser that can handle HTML and XHTML.
 
+**Source code:** :source:`Lib/html/parser.py`
 
 .. index::
    single: HTML
    single: XHTML
 
-**Source code:** :source:`Lib/html/parser.py`
-
 --------------
 
 This module defines a class :class:`HTMLParser` which serves as the basis for
@@ -51,8 +50,10 @@ as they are encountered::
    class MyHTMLParser(HTMLParser):
        def handle_starttag(self, tag, attrs):
            print("Encountered a start tag:", tag)
+
        def handle_endtag(self, tag):
            print("Encountered an end tag :", tag)
+
        def handle_data(self, data):
            print("Encountered some data  :", data)
 
@@ -131,8 +132,8 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`):
    and quotes in the *value* have been removed, and character and entity references
    have been replaced.
 
-   For instance, for the tag ``<A HREF="http://www.cwi.nl/">``, this method
-   would be called as ``handle_starttag('a', [('href', 'http://www.cwi.nl/')])``.
+   For instance, for the tag ``<A HREF="https://www.cwi.nl/">``, this method
+   would be called as ``handle_starttag('a', [('href', 'https://www.cwi.nl/')])``.
 
    All entity references from :mod:`html.entities` are replaced in the attribute
    values.
@@ -237,21 +238,27 @@ examples::
            print("Start tag:", tag)
            for attr in attrs:
                print("     attr:", attr)
+
        def handle_endtag(self, tag):
            print("End tag  :", tag)
+
        def handle_data(self, data):
            print("Data     :", data)
+
        def handle_comment(self, data):
            print("Comment  :", data)
+
        def handle_entityref(self, name):
            c = chr(name2codepoint[name])
            print("Named ent:", c)
+
        def handle_charref(self, name):
            if name.startswith('x'):
                c = chr(int(name[1:], 16))
            else:
                c = chr(int(name))
            print("Num ent  :", c)
+
        def handle_decl(self, data):
            print("Decl     :", data)
 
@@ -283,7 +290,7 @@ further parsing::
         attr: ('type', 'text/css')
    Data     : #python { color: green }
    End tag  : style
-   >>>
+
    >>> parser.feed('<script type="text/javascript">'
    ...             'alert("<strong>hello!</strong>");</script>')
    Start tag: script
index d57649c..8954648 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: http.client
    :synopsis: HTTP and HTTPS protocol client (requires sockets).
 
+**Source code:** :source:`Lib/http/client.py`
 
 .. index::
    pair: HTTP; protocol
@@ -11,8 +12,6 @@
 
 .. index:: module: urllib.request
 
-**Source code:** :source:`Lib/http/client.py`
-
 --------------
 
 This module defines classes which implement the client side of the HTTP and
@@ -21,8 +20,8 @@ HTTPS protocols.  It is normally not used directly --- the module
 
 .. seealso::
 
-    The `Requests package <http://requests.readthedocs.org/>`_
-    is recommended for a higher-level http client interface.
+    The `Requests package <https://requests.readthedocs.org/>`_
+    is recommended for a higher-level HTTP client interface.
 
 .. note::
 
@@ -362,6 +361,10 @@ server.  It provides access to the request headers and the entity
 body.  The response is an iterable object and can be used in a with
 statement.
 
+.. versionchanged:: 3.5
+   The :class:`io.BufferedIOBase` interface is now implemented and
+   all of its reader operations are supported.
+
 
 .. method:: HTTPResponse.read([amt])
 
@@ -437,7 +440,7 @@ Here is an example session that uses the ``GET`` method::
    >>> conn.request("GET", "/")
    >>> r1 = conn.getresponse()
    >>> while not r1.closed:
-   ...     print(r1.read(200)) # 200 bytes
+   ...     print(r1.read(200))  # 200 bytes
    b'<!doctype html>\n<!--[if"...
    ...
    >>> # Example of an invalid request
index ca68aac..5370601 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: http.cookiejar
    :synopsis: Classes for automatic handling of HTTP cookies.
+
 .. moduleauthor:: John J. Lee <jjl@pobox.com>
 .. sectionauthor:: John J. Lee <jjl@pobox.com>
 
@@ -115,7 +116,7 @@ The following classes are provided:
       :mod:`http.cookiejar` and :mod:`http.cookies` modules do not depend on each
       other.
 
-   http://curl.haxx.se/rfc/cookie_spec.html
+   https://curl.haxx.se/rfc/cookie_spec.html
       The specification of the original Netscape cookie protocol.  Though this is
       still the dominant protocol, the 'Netscape cookie protocol' implemented by all
       the major browsers (and :mod:`http.cookiejar`) only bears a passing resemblance to
index c2bb80d..4b45d4b 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: http.cookies
    :synopsis: Support for HTTP state management (cookies).
+
 .. moduleauthor:: Timothy O'Malley <timo@alum.mit.edu>
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
@@ -141,7 +142,7 @@ Morsel Objects
    in HTTP requests, and is not accessible through JavaScript. This is intended
    to mitigate some forms of cross-site scripting.
 
-   The keys are case-insensitive.
+   The keys are case-insensitive and their default value is ``''``.
 
    .. versionchanged:: 3.5
       :meth:`~Morsel.__eq__` now takes :attr:`~Morsel.key` and :attr:`~Morsel.value`
index b6f2c58..be661c5 100644 (file)
@@ -4,11 +4,13 @@
 .. module:: http
    :synopsis: HTTP status codes and messages
 
+**Source code:** :source:`Lib/http/__init__.py`
+
 .. index::
    pair: HTTP; protocol
    single: HTTP; http (standard module)
 
-**Source code:** :source:`Lib/http/__init__.py`
+--------------
 
 :mod:`http` is a package that collects several modules for working with the
 HyperText Transfer Protocol:
@@ -51,7 +53,7 @@ HTTP status codes
 -----------------
 
 Supported,
-`IANA-registered <http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>`_
+`IANA-registered <https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>`_
 status codes available in :class:`http.HTTPStatus` are:
 
 ======= =================================== ==================================================================
index 0bde35b..16c4fac 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: http.server
    :synopsis: HTTP server and request handlers.
 
+**Source code:** :source:`Lib/http/server.py`
 
 .. index::
    pair: WWW; server
@@ -11,8 +12,6 @@
    single: URL
    single: httpd
 
-**Source code:** :source:`Lib/http/server.py`
-
 --------------
 
 This module defines classes for implementing HTTP servers (Web servers).
@@ -97,7 +96,6 @@ of which this module provides three different variants:
       :mod:`http.client` is used to parse the headers and it requires that the
       HTTP request provide a valid :rfc:`2822` style header.
 
-
    .. attribute:: rfile
 
       Contains an input stream, positioned at the start of the optional input
@@ -109,7 +107,7 @@ of which this module provides three different variants:
       client. Proper adherence to the HTTP protocol must be used when writing to
       this stream.
 
-   :class:`BaseHTTPRequestHandler` has the following class variables:
+   :class:`BaseHTTPRequestHandler` has the following attributes:
 
    .. attribute:: server_version
 
@@ -125,13 +123,10 @@ of which this module provides three different variants:
 
    .. attribute:: error_message_format
 
-      Specifies a format string for building an error response to the client. It
-      uses parenthesized, keyed format specifiers, so the format operand must be
-      a dictionary. The *code* key should be an integer, specifying the numeric
-      HTTP error code value. *message* should be a string containing a
-      (detailed) error message of what occurred, and *explain* should be an
-      explanation of the error code number. Default *message* and *explain*
-      values can found in the :attr:`responses` class variable.
+      Specifies a format string that should be used by :meth:`send_error` method
+      for building an error response to the client. The string is filled by
+      default with variables from :attr:`responses` based on the status code
+      that passed to :meth:`send_error`.
 
    .. attribute:: error_content_type
 
@@ -154,11 +149,11 @@ of which this module provides three different variants:
 
    .. attribute:: responses
 
-      This variable contains a mapping of error code integers to two-element tuples
+      This attribute contains a mapping of error code integers to two-element tuples
       containing a short and long message. For example, ``{code: (shortmessage,
       longmessage)}``. The *shortmessage* is usually used as the *message* key in an
-      error response, and *longmessage* as the *explain* key (see the
-      :attr:`error_message_format` class variable).
+      error response, and *longmessage* as the *explain* key.  It is used by
+      :meth:`send_response_only` and :meth:`send_error` methods.
 
    A :class:`BaseHTTPRequestHandler` instance has the following methods:
 
@@ -191,17 +186,18 @@ of which this module provides three different variants:
       specifies the HTTP error code, with *message* as an optional, short, human
       readable description of the error.  The *explain* argument can be used to
       provide more detailed information about the error; it will be formatted
-      using the :attr:`error_message_format` class variable and emitted, after
+      using the :attr:`error_message_format` attribute and emitted, after
       a complete set of headers, as the response body.  The :attr:`responses`
-      class variable holds the default values for *message* and *explain* that
+      attribute holds the default values for *message* and *explain* that
       will be used if no value is provided; for unknown codes the default value
-      for both is the string ``???``.
+      for both is the string ``???``. The body will be empty if the method is
+      HEAD or the response code is one of the following: ``1xx``,
+      ``204 No Content``, ``205 Reset Content``, ``304 Not Modified``.
 
       .. versionchanged:: 3.4
          The error response includes a Content-Length header.
          Added the *explain* argument.
 
-
    .. method:: send_response(code, message=None)
 
       Adds a response header to the headers buffer and logs the accepted
@@ -217,7 +213,6 @@ of which this module provides three different variants:
          Headers are stored to an internal buffer and :meth:`end_headers`
          needs to be called explicitly.
 
-
    .. method:: send_header(keyword, value)
 
       Adds the HTTP header to an internal buffer which will be written to the
@@ -229,7 +224,6 @@ of which this module provides three different variants:
       .. versionchanged:: 3.2
          Headers are stored in an internal buffer.
 
-
    .. method:: send_response_only(code, message=None)
 
       Sends the response header only, used for the purposes when ``100
@@ -279,7 +273,7 @@ of which this module provides three different variants:
    .. method:: version_string()
 
       Returns the server software's version string. This is a combination of the
-      :attr:`server_version` and :attr:`sys_version` class variables.
+      :attr:`server_version` and :attr:`sys_version` attributes.
 
    .. method:: date_time_string(timestamp=None)
 
index 4384d56..9ca92ce 100644 (file)
@@ -3,12 +3,16 @@
 IDLE
 ====
 
+.. moduleauthor:: Guido van Rossum <guido@python.org>
+
+**Source code:** :source:`Lib/idlelib/`
+
 .. index::
    single: IDLE
    single: Python Editor
    single: Integrated Development Environment
 
-.. moduleauthor:: Guido van Rossum <guido@python.org>
+--------------
 
 IDLE is Python's Integrated Development and Learning Environment.
 
@@ -128,7 +132,7 @@ Find Selection
    Search for the currently selected string, if there is one.
 
 Find in Files...
-   Open a file search dialog.  Put results in an new output window.
+   Open a file search dialog.  Put results in a new output window.
 
 Replace...
    Open a search-and-replace dialog.
@@ -550,14 +554,16 @@ IDLE-console differences
 
 As much as possible, the result of executing Python code with IDLE is the
 same as executing the same code in a console window.  However, the different
-interface and operation occasionally affects results.
-
-For instance, IDLE normally executes user code in a separate process from
-the IDLE GUI itself.  The IDLE versions of sys.stdin, .stdout, and .stderr in the
-execution process get input from and send output to the GUI process,
-which keeps control of the keyboard and screen.  This is normally transparent,
-but code that access these object will see different attribute values.
-Also, functions that directly access the keyboard and screen will not work.
+interface and operation occasionally affects visible results.  For instance,
+``sys.modules`` starts with more entries.
+
+IDLE also replaces ``sys.stdin``, ``sys.stdout``, and ``sys.stderr`` with
+objects that get input from and send output to the Shell window.
+When this window has the focus, it controls the keyboard and screen.
+This is normally transparent, but functions that directly access the keyboard
+and screen will not work.  If ``sys`` is reset with ``importlib.reload(sys)``,
+IDLE's changes are lost and things li ke ``input``, ``raw_input``, and
+``print`` will not work correctly.
 
 With IDLE's Shell, one enters, edits, and recalls complete statements.
 Some consoles only work with a single physical line at a time.
index 15b0932..c25e7d8 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: imaplib
    :synopsis: IMAP4 protocol client (requires sockets).
+
 .. moduleauthor:: Piers Lauder <piers@communitysolutions.com.au>
 .. sectionauthor:: Piers Lauder <piers@communitysolutions.com.au>
 .. revised by ESR, January 2000
 .. changes for IMAP4_stream by Piers Lauder <piers@communitysolutions.com.au>,
    November 2002
 
+**Source code:** :source:`Lib/imaplib.py`
 
 .. index::
    pair: IMAP4; protocol
    pair: IMAP4_SSL; protocol
    pair: IMAP4_stream; protocol
 
-**Source code:** :source:`Lib/imaplib.py`
-
 --------------
 
 This module defines three classes, :class:`IMAP4`, :class:`IMAP4_SSL` and
@@ -157,7 +157,7 @@ example of usage.
 
    Documents describing the protocol, and sources and binaries  for servers
    implementing it, can all be found at the University of Washington's *IMAP
-   Information Center* (http://www.washington.edu/imap/).
+   Information Center* (https://www.washington.edu/imap/).
 
 
 .. _imap4-objects:
index 68a6b68..9828ba6 100644 (file)
@@ -5,11 +5,15 @@
    :synopsis: Access the implementation of the import statement.
    :deprecated:
 
+**Source code:** :source:`Lib/imp.py`
+
 .. deprecated:: 3.4
    The :mod:`imp` package is pending deprecation in favor of :mod:`importlib`.
 
 .. index:: statement: import
 
+--------------
+
 This module provides an interface to the mechanisms used to implement the
 :keyword:`import` statement.  It defines the following constants and functions:
 
index da61353..3302446 100644 (file)
@@ -9,6 +9,9 @@
 
 .. versionadded:: 3.1
 
+**Source code:** :source:`Lib/importlib/__init__.py`
+
+--------------
 
 Introduction
 ------------
@@ -52,6 +55,9 @@ generically as an :term:`importer`) to participate in the import process.
     :pep:`366`
         Main module explicit relative imports
 
+    :pep:`420`
+        Implicit namespace packages
+
     :pep:`451`
         A ModuleSpec Type for the Import System
 
@@ -230,7 +236,7 @@ ABC hierarchy::
    .. deprecated:: 3.3
       Use :class:`MetaPathFinder` or :class:`PathEntryFinder` instead.
 
-   .. method:: find_module(fullname, path=None)
+   .. abstractmethod:: find_module(fullname, path=None)
 
       An abstact method for finding a :term:`loader` for the specified
       module.  Originally specified in :pep:`302`, this method was meant
@@ -453,7 +459,7 @@ ABC hierarchy::
     :pep:`302` protocol for loading arbitrary resources from the storage
     back-end.
 
-    .. method:: get_data(path)
+    .. abstractmethod:: get_data(path)
 
         An abstract method to return the bytes for the data located at *path*.
         Loaders that have a file-like storage back-end
@@ -489,7 +495,7 @@ ABC hierarchy::
         .. versionchanged:: 3.4
            No longer abstract and a concrete implementation is provided.
 
-    .. method:: get_source(fullname)
+    .. abstractmethod:: get_source(fullname)
 
         An abstract method to return the source of a module. It is returned as
         a text string using :term:`universal newlines`, translating all
@@ -546,7 +552,7 @@ ABC hierarchy::
     when implemented, helps a module to be executed as a script. The ABC
     represents an optional :pep:`302` protocol.
 
-    .. method:: get_filename(fullname)
+    .. abstractmethod:: get_filename(fullname)
 
         An abstract method that is to return the value of :attr:`__file__` for
         the specified module. If no path is available, :exc:`ImportError` is
@@ -586,11 +592,11 @@ ABC hierarchy::
       .. deprecated:: 3.4
          Use :meth:`Loader.exec_module` instead.
 
-   .. method:: get_filename(fullname)
+   .. abstractmethod:: get_filename(fullname)
 
       Returns :attr:`path`.
 
-   .. method:: get_data(path)
+   .. abstractmethod:: get_data(path)
 
       Reads *path* as a binary file and returns the bytes from it.
 
@@ -1113,7 +1119,7 @@ an :term:`importer`.
 
    .. versionadded:: 3.4
 
-   .. versionchanged ::3.5
+   .. versionchanged:: 3.5
       The *optimization* parameter was added and the *debug_override* parameter
       was deprecated.
 
@@ -1273,7 +1279,8 @@ an :term:`importer`.
    :meth:`~importlib.abc.Loader.exec_module` as control over what module type
    is used for the module is required. For those same reasons, the loader's
    :meth:`~importlib.abc.Loader.create_module` method will be ignored (i.e., the
-   loader's method should only return ``None``). Finally,
+   loader's method should only return ``None``; this excludes
+   :class:`BuiltinImporter` and :class:`ExtensionFileLoader`). Finally,
    modules which substitute the object placed into :attr:`sys.modules` will
    not work as there is no way to properly replace the module references
    throughout the interpreter safely; :exc:`ValueError` is raised if such a
@@ -1298,4 +1305,4 @@ an :term:`importer`.
         suffixes = importlib.machinery.SOURCE_SUFFIXES
         loader = importlib.machinery.SourceFileLoader
         lazy_loader = importlib.util.LazyLoader.factory(loader)
-        finder = importlib.machinery.FileFinder(path, [(lazy_loader, suffixes)])
+        finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))
index 23e559c..b28d0f9 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: inspect
    :synopsis: Extract information and source code from live objects.
+
 .. moduleauthor:: Ka-Ping Yee <ping@lfw.org>
 .. sectionauthor:: Ka-Ping Yee <ping@lfw.org>
 
@@ -489,8 +490,12 @@ Retrieving source code
 .. function:: cleandoc(doc)
 
    Clean up indentation from docstrings that are indented to line up with blocks
-   of code.  Any whitespace that can be uniformly removed from the second line
-   onwards is removed.  Also, all tabs are expanded to spaces.
+   of code.
+
+   All leading whitespace is removed from the first line.  Any leading whitespace
+   that can be uniformly removed from the second line onwards is removed.  Empty
+   lines at the beginning and end are subsequently removed.  Also, all tabs are
+   expanded to spaces.
 
 
 .. _inspect-signature-object:
@@ -787,7 +792,7 @@ function.
    functions::
 
       def test(a, *, b):
-         ...
+          ...
 
       sig = signature(test)
       ba = sig.bind(10, b=20)
@@ -829,8 +834,7 @@ Classes and functions
    .. deprecated:: 3.0
       Use :func:`signature` and
       :ref:`Signature Object <inspect-signature-object>`, which provide a
-      better introspecting API for callables.  This function will be removed
-      in Python 3.6.
+      better introspecting API for callables.
 
 
 .. function:: getfullargspec(func)
index cb3e9ed..23df18f 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: io
    :synopsis: Core tools for working with streams.
+
 .. moduleauthor:: Guido van Rossum <guido@python.org>
 .. moduleauthor:: Mike Verdone <mike.verdone@gmail.com>
 .. moduleauthor:: Mark Russell <mark.russell@zen.co.uk>
 .. moduleauthor:: Benjamin Peterson <benjamin@python.org>
 .. sectionauthor:: Benjamin Peterson <benjamin@python.org>
 
+**Source code:** :source:`Lib/io.py`
+
+--------------
+
 .. _io-overview:
 
 Overview
@@ -66,7 +71,8 @@ The text stream API is described in detail in the documentation of
 Binary I/O
 ^^^^^^^^^^
 
-Binary I/O (also called *buffered I/O*) expects and produces :class:`bytes`
+Binary I/O (also called *buffered I/O*) expects
+:term:`bytes-like objects <bytes-like object>` and produces :class:`bytes`
 objects.  No encoding, decoding, or newline translation is performed.  This
 category of streams can be used for all kinds of non-text data, and also when
 manual control over the handling of text data is desired.
@@ -130,7 +136,7 @@ High-level Module Interface
 In-memory streams
 ^^^^^^^^^^^^^^^^^
 
-It is also possible to use a :class:`str` or :class:`bytes`-like object as a
+It is also possible to use a :class:`str` or :term:`bytes-like object` as a
 file for both reading and writing.  For strings :class:`StringIO` can be used
 like a file opened in text mode.  :class:`BytesIO` can be used like a file
 opened in binary mode.  Both provide full read-write capabilities with random
@@ -227,9 +233,10 @@ I/O Base Classes
    when operations they do not support are called.
 
    The basic type used for binary data read from or written to a file is
-   :class:`bytes`.  :class:`bytearray`\s are accepted too, and in some cases
-   (such as :meth:`readinto`) required.  Text I/O classes work with
-   :class:`str` data.
+   :class:`bytes`.  Other :term:`bytes-like objects <bytes-like object>` are
+   accepted as method arguments too.  In some cases, such as
+   :meth:`~RawIOBase.readinto`, a writable object such as :class:`bytearray`
+   is required.  Text I/O classes work with :class:`str` data.
 
    Note that calling any method (even inquiries) on a closed stream is
    undefined.  Implementations may raise :exc:`ValueError` in this case.
@@ -393,18 +400,22 @@ I/O Base Classes
 
    .. method:: readinto(b)
 
-      Read up to ``len(b)`` bytes into :class:`bytearray` *b* and return the
+      Read bytes into a pre-allocated, writable
+      :term:`bytes-like object` *b*, and return the
       number of bytes read.  If the object is in non-blocking mode and no bytes
       are available, ``None`` is returned.
 
    .. method:: write(b)
 
-      Write the given :class:`bytes` or :class:`bytearray` object, *b*, to the
-      underlying raw stream and return the number of bytes written.  This can
-      be less than ``len(b)``, depending on specifics of the underlying raw
+      Write the given :term:`bytes-like object`, *b*, to the
+      underlying raw stream, and return the number of
+      bytes written.  This can be less than the length of *b* in
+      bytes, depending on specifics of the underlying raw
       stream, and especially if it is in non-blocking mode.  ``None`` is
       returned if the raw stream is set not to block and no single byte could
-      be readily written to it.
+      be readily written to it.  The caller may release or mutate *b* after
+      this method returns, so the implementation should only access *b*
+      during the method call.
 
 
 .. class:: BufferedIOBase
@@ -476,8 +487,8 @@ I/O Base Classes
 
    .. method:: readinto(b)
 
-      Read up to ``len(b)`` bytes into bytearray *b* and return the number of
-      bytes read.
+      Read bytes into a pre-allocated, writable
+      :term:`bytes-like object` *b* and return the number of bytes read.
 
       Like :meth:`read`, multiple reads may be issued to the underlying raw
       stream, unless the latter is interactive.
@@ -487,7 +498,8 @@ I/O Base Classes
 
    .. method:: readinto1(b)
 
-      Read up to ``len(b)`` bytes into bytearray *b*, using at most one call to
+      Read bytes into a pre-allocated, writable
+      :term:`bytes-like object` *b*, using at most one call to
       the underlying raw stream's :meth:`~RawIOBase.read` (or
       :meth:`~RawIOBase.readinto`) method. Return the number of bytes read.
 
@@ -498,8 +510,8 @@ I/O Base Classes
 
    .. method:: write(b)
 
-      Write the given :class:`bytes` or :class:`bytearray` object, *b* and
-      return the number of bytes written (never less than ``len(b)``, since if
+      Write the given :term:`bytes-like object`, *b*, and return the number
+      of bytes written (always equal to the length of *b* in bytes, since if
       the write fails an :exc:`OSError` will be raised).  Depending on the
       actual implementation, these bytes may be readily written to the
       underlying stream, or held in a buffer for performance and latency
@@ -509,6 +521,9 @@ I/O Base Classes
       data needed to be written to the raw stream but it couldn't accept
       all the data without blocking.
 
+      The caller may release or mutate *b* after this method returns,
+      so the implementation should only access *b* during the method call.
+
 
 Raw File I/O
 ^^^^^^^^^^^^
@@ -584,7 +599,8 @@ than raw I/O does.
    :class:`BufferedIOBase`.  The buffer is discarded when the
    :meth:`~IOBase.close` method is called.
 
-   The argument *initial_bytes* contains optional initial :class:`bytes` data.
+   The optional argument *initial_bytes* is a :term:`bytes-like object` that
+   contains initial data.
 
    :class:`BytesIO` provides or overrides these methods in addition to those
    from :class:`BufferedIOBase` and :class:`IOBase`:
@@ -682,7 +698,7 @@ than raw I/O does.
 
    .. method:: write(b)
 
-      Write the :class:`bytes` or :class:`bytearray` object, *b* and return the
+      Write the :term:`bytes-like object`, *b*, and return the
       number of bytes written.  When in non-blocking mode, a
       :exc:`BlockingIOError` is raised if the buffer needs to be written out but
       the raw stream blocks.
index 90fcc74..23526b6 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: ipaddress
    :synopsis: IPv4/IPv6 manipulation library.
+
 .. moduleauthor:: Peter Moody
 
 **Source code:** :source:`Lib/ipaddress.py`
@@ -198,8 +199,8 @@ write code that handles both IP versions correctly.
       ``True`` if the address is reserved for link-local usage.  See
       :RFC:`3927`.
 
-.. _iana-ipv4-special-registry: http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
-.. _iana-ipv6-special-registry: http://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
+.. _iana-ipv4-special-registry: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
+.. _iana-ipv6-special-registry: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
 
 
 .. class:: IPv6Address(address)
@@ -580,7 +581,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
 
    4. A two-tuple of an address description and a netmask, where the address
       description is either a string, a 128-bits integer, a 16-bytes packed
-      integer, or an existing IPv4Address object; and the netmask is an
+      integer, or an existing IPv6Address object; and the netmask is an
       integer representing the prefix length.
 
    An :exc:`AddressValueError` is raised if *address* is not a valid IPv6
@@ -653,7 +654,7 @@ network.  For iteration, *all* hosts are returned, including unusable hosts
 example::
 
    >>> for addr in IPv4Network('192.0.2.0/28'):
-   ...   addr
+   ...     addr
    ...
    IPv4Address('192.0.2.0')
    IPv4Address('192.0.2.1')
index 8c7592d..dfc1ddc 100644 (file)
@@ -3,14 +3,15 @@
 
 .. module:: itertools
    :synopsis: Functions creating iterators for efficient looping.
+
 .. moduleauthor:: Raymond Hettinger <python@rcn.com>
 .. sectionauthor:: Raymond Hettinger <python@rcn.com>
 
-
 .. testsetup::
 
    from itertools import *
 
+--------------
 
 This module implements a number of :term:`iterator` building blocks inspired
 by constructs from APL, Haskell, and SML.  Each has been recast in a form
@@ -97,7 +98,7 @@ loops that truncate the stream.
     :class:`~fractions.Fraction`.) If the input iterable is empty, the
     output iterable will also be empty.
 
-    Equivalent to::
+    Roughly equivalent to::
 
         def accumulate(iterable, func=operator.add):
             'Return running totals'
@@ -117,7 +118,7 @@ loops that truncate the stream.
     :func:`min` for a running minimum, :func:`max` for a running maximum, or
     :func:`operator.mul` for a running product.  Amortization tables can be
     built by accumulating interest and applying payments.  First-order
-    `recurrence relations <http://en.wikipedia.org/wiki/Recurrence_relation>`_
+    `recurrence relations <https://en.wikipedia.org/wiki/Recurrence_relation>`_
     can be modeled by supplying the initial value in the iterable and using only
     the accumulated total in *func* argument::
 
@@ -132,7 +133,7 @@ loops that truncate the stream.
       >>> list(accumulate(cashflows, lambda bal, pmt: bal*1.05 + pmt))
       [1000, 960.0, 918.0, 873.9000000000001, 827.5950000000001]
 
-      # Chaotic recurrence relation http://en.wikipedia.org/wiki/Logistic_map
+      # Chaotic recurrence relation https://en.wikipedia.org/wiki/Logistic_map
       >>> logistic_map = lambda x, _:  r * x * (1 - x)
       >>> r = 3.8
       >>> x0 = 0.4
@@ -156,7 +157,7 @@ loops that truncate the stream.
    Make an iterator that returns elements from the first iterable until it is
    exhausted, then proceeds to the next iterable, until all of the iterables are
    exhausted.  Used for treating consecutive sequences as a single sequence.
-   Equivalent to::
+   Roughly equivalent to::
 
       def chain(*iterables):
           # chain('ABC', 'DEF') --> A B C D E F
@@ -189,7 +190,7 @@ loops that truncate the stream.
    value.  So if the input elements are unique, there will be no repeat
    values in each combination.
 
-   Equivalent to::
+   Roughly equivalent to::
 
         def combinations(iterable, r):
             # combinations('ABCD', 2) --> AB AC AD BC BD CD
@@ -238,7 +239,7 @@ loops that truncate the stream.
    value.  So if the input elements are unique, the generated combinations
    will also be unique.
 
-   Equivalent to::
+   Roughly equivalent to::
 
         def combinations_with_replacement(iterable, r):
             # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
@@ -278,7 +279,7 @@ loops that truncate the stream.
    Make an iterator that filters elements from *data* returning only those that
    have a corresponding element in *selectors* that evaluates to ``True``.
    Stops when either the *data* or *selectors* iterables has been exhausted.
-   Equivalent to::
+   Roughly equivalent to::
 
        def compress(data, selectors):
            # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
@@ -291,7 +292,7 @@ loops that truncate the stream.
 
    Make an iterator that returns evenly spaced values starting with number *start*. Often
    used as an argument to :func:`map` to generate consecutive data points.
-   Also, used with :func:`zip` to add sequence numbers.  Equivalent to::
+   Also, used with :func:`zip` to add sequence numbers.  Roughly equivalent to::
 
       def count(start=0, step=1):
           # count(10) --> 10 11 12 13 14 ...
@@ -312,7 +313,7 @@ loops that truncate the stream.
 
    Make an iterator returning elements from the iterable and saving a copy of each.
    When the iterable is exhausted, return elements from the saved copy.  Repeats
-   indefinitely.  Equivalent to::
+   indefinitely.  Roughly equivalent to::
 
       def cycle(iterable):
           # cycle('ABCD') --> A B C D A B C D A B C D ...
@@ -333,7 +334,7 @@ loops that truncate the stream.
    Make an iterator that drops elements from the iterable as long as the predicate
    is true; afterwards, returns every element.  Note, the iterator does not produce
    *any* output until the predicate first becomes false, so it may have a lengthy
-   start-up time.  Equivalent to::
+   start-up time.  Roughly equivalent to::
 
       def dropwhile(predicate, iterable):
           # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
@@ -349,7 +350,7 @@ loops that truncate the stream.
 
    Make an iterator that filters elements from iterable returning only those for
    which the predicate is ``False``. If *predicate* is ``None``, return the items
-   that are false. Equivalent to::
+   that are false. Roughly equivalent to::
 
       def filterfalse(predicate, iterable):
           # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
@@ -386,7 +387,7 @@ loops that truncate the stream.
           groups.append(list(g))      # Store group iterator as a list
           uniquekeys.append(k)
 
-   :func:`groupby` is equivalent to::
+   :func:`groupby` is roughly equivalent to::
 
       class groupby:
           # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
@@ -426,7 +427,7 @@ loops that truncate the stream.
    specified position.  Unlike regular slicing, :func:`islice` does not support
    negative values for *start*, *stop*, or *step*.  Can be used to extract related
    fields from data where the internal structure has been flattened (for example, a
-   multi-line report may list a name field on every third line).  Equivalent to::
+   multi-line report may list a name field on every third line).  Roughly equivalent to::
 
       def islice(iterable, *args):
           # islice('ABCDEFG', 2) --> A B
@@ -464,7 +465,7 @@ loops that truncate the stream.
    value.  So if the input elements are unique, there will be no repeat
    values in each permutation.
 
-   Equivalent to::
+   Roughly equivalent to::
 
         def permutations(iterable, r=None):
             # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
@@ -510,7 +511,7 @@ loops that truncate the stream.
 
    Cartesian product of input iterables.
 
-   Equivalent to nested for-loops in a generator expression. For example,
+   Roughly equivalent to nested for-loops in a generator expression. For example,
    ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``.
 
    The nested loops cycle like an odometer with the rightmost element advancing
@@ -522,7 +523,7 @@ loops that truncate the stream.
    repetitions with the optional *repeat* keyword argument.  For example,
    ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``.
 
-   This function is equivalent to the following code, except that the
+   This function is roughly equivalent to the following code, except that the
    actual implementation does not build up intermediate results in memory::
 
        def product(*args, repeat=1):
@@ -541,7 +542,9 @@ loops that truncate the stream.
    Make an iterator that returns *object* over and over again. Runs indefinitely
    unless the *times* argument is specified. Used as argument to :func:`map` for
    invariant parameters to the called function.  Also used with :func:`zip` to
-   create an invariant part of a tuple record.  Equivalent to::
+   create an invariant part of a tuple record.
+
+   Roughly equivalent to::
 
       def repeat(object, times=None):
           # repeat(10, 3) --> 10 10 10
@@ -564,7 +567,7 @@ loops that truncate the stream.
    the iterable.  Used instead of :func:`map` when argument parameters are already
    grouped in tuples from a single iterable (the data has been "pre-zipped").  The
    difference between :func:`map` and :func:`starmap` parallels the distinction
-   between ``function(a,b)`` and ``function(*c)``. Equivalent to::
+   between ``function(a,b)`` and ``function(*c)``. Roughly equivalent to::
 
       def starmap(function, iterable):
           # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
@@ -575,7 +578,7 @@ loops that truncate the stream.
 .. function:: takewhile(predicate, iterable)
 
    Make an iterator that returns elements from the iterable as long as the
-   predicate is true.  Equivalent to::
+   predicate is true.  Roughly equivalent to::
 
       def takewhile(predicate, iterable):
           # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
@@ -588,7 +591,7 @@ loops that truncate the stream.
 
 .. function:: tee(iterable, n=2)
 
-   Return *n* independent iterators from a single iterable.  Equivalent to::
+   Return *n* independent iterators from a single iterable.  Roughly equivalent to::
 
         def tee(iterable, n=2):
             it = iter(iterable)
@@ -619,7 +622,7 @@ loops that truncate the stream.
 
    Make an iterator that aggregates elements from each of the iterables. If the
    iterables are of uneven length, missing values are filled-in with *fillvalue*.
-   Iteration continues until the longest iterable is exhausted.  Equivalent to::
+   Iteration continues until the longest iterable is exhausted.  Roughly equivalent to::
 
       class ZipExhausted(Exception):
           pass
@@ -693,6 +696,11 @@ which incur interpreter overhead.
        "Returns the nth item or a default value"
        return next(islice(iterable, n, None), default)
 
+   def all_equal(iterable):
+       "Returns True if all the elements are equal to each other"
+       g = groupby(iterable)
+       return next(g, True) and not next(g, False)
+
    def quantify(iterable, pred=bool):
        "Count how many times the predicate is true"
        return sum(map(pred, iterable))
@@ -801,7 +809,7 @@ which incur interpreter overhead.
        try:
            if first is not None:
                yield first()            # For database APIs needing an initial cast to db.first()
-           while 1:
+           while True:
                yield func()
        except exception:
            pass
index d62f14b..174e734 100644 (file)
@@ -3,14 +3,19 @@
 
 .. module:: json
    :synopsis: Encode and decode the JSON format.
+
 .. moduleauthor:: Bob Ippolito <bob@redivi.com>
 .. sectionauthor:: Bob Ippolito <bob@redivi.com>
 
+**Source code:** :source:`Lib/json/__init__.py`
+
+--------------
+
 `JSON (JavaScript Object Notation) <http://json.org>`_, specified by
 :rfc:`7159` (which obsoletes :rfc:`4627`) and by
 `ECMA-404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>`_,
 is a lightweight data interchange format inspired by
-`JavaScript <http://en.wikipedia.org/wiki/JavaScript>`_ object literal syntax
+`JavaScript <https://en.wikipedia.org/wiki/JavaScript>`_ object literal syntax
 (although it is not a strict subset of JavaScript [#rfc-errata]_ ).
 
 :mod:`json` exposes an API familiar to users of the standard library
@@ -689,7 +694,7 @@ Command line options
 .. rubric:: Footnotes
 
 .. [#rfc-errata] As noted in `the errata for RFC 7159
-   <http://www.rfc-editor.org/errata_search.php?rfc=7159>`_,
+   <https://www.rfc-editor.org/errata_search.php?rfc=7159>`_,
    JSON permits literal U+2028 (LINE SEPARATOR) and
    U+2029 (PARAGRAPH SEPARATOR) characters in strings, whereas JavaScript
    (as of ECMAScript Edition 5.1) does not.
index 3f14885..ae3de9f 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: linecache
    :synopsis: This module provides random access to individual lines from text files.
+
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
 **Source code:** :source:`Lib/linecache.py`
index 61b79fa..5aaf4a3 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: locale
    :synopsis: Internationalization services.
+
 .. moduleauthor:: Martin von Löwis <martin@v.loewis.de>
 .. sectionauthor:: Martin von Löwis <martin@v.loewis.de>
 
+**Source code:** :source:`Lib/locale.py`
+
+--------------
 
 The :mod:`locale` module opens access to the POSIX locale database and
 functionality. The POSIX locale mechanism allows programmers to deal with
@@ -467,13 +471,13 @@ The :mod:`locale` module defines the following exception and functions:
 Example::
 
    >>> import locale
-   >>> loc = locale.getlocale() # get current locale
+   >>> loc = locale.getlocale()  # get current locale
    # use German locale; name might vary with platform
    >>> locale.setlocale(locale.LC_ALL, 'de_DE')
-   >>> locale.strcoll('f\xe4n', 'foo') # compare a string containing an umlaut
-   >>> locale.setlocale(locale.LC_ALL, '') # use user's preferred locale
-   >>> locale.setlocale(locale.LC_ALL, 'C') # use default (C) locale
-   >>> locale.setlocale(locale.LC_ALL, loc) # restore saved locale
+   >>> locale.strcoll('f\xe4n', 'foo')  # compare a string containing an umlaut
+   >>> locale.setlocale(locale.LC_ALL, '')   # use user's preferred locale
+   >>> locale.setlocale(locale.LC_ALL, 'C')  # use default (C) locale
+   >>> locale.setlocale(locale.LC_ALL, loc)  # restore saved locale
 
 
 Background, details, hints, tips and caveats
index fd6a477..e196724 100644 (file)
@@ -4,10 +4,11 @@
 .. module:: logging.config
    :synopsis: Configuration of the logging module.
 
-
 .. moduleauthor:: Vinay Sajip <vinay_sajip@red-dove.com>
 .. sectionauthor:: Vinay Sajip <vinay_sajip@red-dove.com>
 
+**Source code:** :source:`Lib/logging/config.py`
+
 .. sidebar:: Important
 
    This page contains only reference information. For tutorials,
@@ -17,8 +18,6 @@
    * :ref:`Advanced Tutorial <logging-advanced-tutorial>`
    * :ref:`Logging Cookbook <logging-cookbook>`
 
-**Source code:** :source:`Lib/logging/config.py`
-
 --------------
 
 This section describes the API for configuring the logging module.
index 0edc942..855adab 100644 (file)
@@ -4,10 +4,11 @@
 .. module:: logging.handlers
    :synopsis: Handlers for the logging module.
 
-
 .. moduleauthor:: Vinay Sajip <vinay_sajip@red-dove.com>
 .. sectionauthor:: Vinay Sajip <vinay_sajip@red-dove.com>
 
+**Source code:** :source:`Lib/logging/handlers.py`
+
 .. sidebar:: Important
 
    This page contains only reference information. For tutorials,
@@ -17,8 +18,6 @@
    * :ref:`Advanced Tutorial <logging-advanced-tutorial>`
    * :ref:`Logging Cookbook <logging-cookbook>`
 
-**Source code:** :source:`Lib/logging/handlers.py`
-
 --------------
 
 .. currentmodule:: logging
@@ -544,7 +543,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 (RF 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.
@@ -866,7 +865,7 @@ supports sending logging messages to a Web server, using either ``GET`` or
 
    .. method:: emit(record)
 
-      Sends the record to the Web server as an URL-encoded dictionary. The
+      Sends the record to the Web server as a URL-encoded dictionary. The
       :meth:`mapLogRecord` method is used to convert the record to the
       dictionary to be sent.
 
index bf821ab..72da385 100644 (file)
@@ -4,10 +4,10 @@
 .. module:: logging
    :synopsis: Flexible event logging system for applications.
 
-
 .. moduleauthor:: Vinay Sajip <vinay_sajip@red-dove.com>
 .. sectionauthor:: Vinay Sajip <vinay_sajip@red-dove.com>
 
+**Source code:** :source:`Lib/logging/__init__.py`
 
 .. index:: pair: Errors; logging
 
@@ -20,9 +20,6 @@
    * :ref:`Advanced Tutorial <logging-advanced-tutorial>`
    * :ref:`Logging Cookbook <logging-cookbook>`
 
-
-**Source code:** :source:`Lib/logging/__init__.py`
-
 --------------
 
 This module defines functions and classes which implement a flexible event
@@ -743,7 +740,9 @@ the options available to you.
 | Attribute name | Format                  | Description                                   |
 +================+=========================+===============================================+
 | args           | You shouldn't need to   | The tuple of arguments merged into ``msg`` to |
-|                | format this yourself.   | produce ``message``.                          |
+|                | format this yourself.   | produce ``message``, or a dict whose values   |
+|                |                         | are used for the merge (when there is only one|
+|                |                         | argument, and it is a dictionary).            |
 +----------------+-------------------------+-----------------------------------------------+
 | asctime        | ``%(asctime)s``         | Human-readable time when the                  |
 |                |                         | :class:`LogRecord` was created.  By default   |
@@ -1244,7 +1243,7 @@ with the :mod:`warnings` module.
       The proposal which described this feature for inclusion in the Python standard
       library.
 
-   `Original Python logging package <http://www.red-dove.com/python_logging.html>`_
+   `Original Python logging package <https://www.red-dove.com/python_logging.html>`_
       This is the original source for the :mod:`logging` package.  The version of the
       package available from this site is suitable for use with Python 1.5.2, 2.1.x
       and 2.2.x, which do not include the :mod:`logging` package in the standard
index 0546005..f99c495 100644 (file)
@@ -3,11 +3,15 @@
 
 .. module:: lzma
    :synopsis: A Python wrapper for the liblzma compression library.
+
 .. moduleauthor:: Nadeem Vawda <nadeem.vawda@gmail.com>
 .. sectionauthor:: Nadeem Vawda <nadeem.vawda@gmail.com>
 
 .. versionadded:: 3.3
 
+**Source code:** :source:`Lib/lzma.py`
+
+--------------
 
 This module provides classes and convenience functions for compressing and
 decompressing data using the LZMA compression algorithm. Also included is a file
index b7a5d89..b08bbe0 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: macpath
    :synopsis: Mac OS 9 path manipulation functions.
 
+**Source code:** :source:`Lib/macpath.py`
+
+--------------
 
 This module is the Mac OS 9 (and earlier) implementation of the :mod:`os.path`
 module. It can be used to manipulate old-style Macintosh pathnames on Mac OS X
index d29902d..81244c2 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: mailbox
    :synopsis: Manipulate mailboxes in various formats
+
 .. moduleauthor:: Gregory K. Johnson <gkj@gregorykjohnson.com>
 .. sectionauthor:: Gregory K. Johnson <gkj@gregorykjohnson.com>
 
+**Source code:** :source:`Lib/mailbox.py`
+
+--------------
 
 This module defines two classes, :class:`Mailbox` and :class:`Message`, for
 accessing and manipulating on-disk mailboxes and the messages they contain.
@@ -422,7 +426,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF.
    `maildir man page from qmail <http://www.qmail.org/man/man5/maildir.html>`_
       The original specification of the format.
 
-   `Using maildir format <http://cr.yp.to/proto/maildir.html>`_
+   `Using maildir format <https://cr.yp.to/proto/maildir.html>`_
       Notes on Maildir by its inventor. Includes an updated name-creation scheme and
       details on "info" semantics.
 
@@ -484,7 +488,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF.
    `mbox man page from tin <http://www.tin.org/bin/man.cgi?section=5&topic=mbox>`_
       Another specification of the format, with details on locking.
 
-   `Configuring Netscape Mail on Unix: Why The Content-Length Format is Bad <http://www.jwz.org/doc/content-length.html>`_
+   `Configuring Netscape Mail on Unix: Why The Content-Length Format is Bad <https://www.jwz.org/doc/content-length.html>`_
       An argument for using the original mbox format rather than a variation.
 
    `"mbox" is a family of several mutually incompatible mailbox formats <http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/mail-mbox-formats.html>`_
@@ -690,10 +694,10 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF.
 
 .. seealso::
 
-   `Format of Version 5 Babyl Files <http://quimby.gnus.org/notes/BABYL>`_
+   `Format of Version 5 Babyl Files <https://quimby.gnus.org/notes/BABYL>`_
       A specification of the Babyl format.
 
-   `Reading Mail with Rmail <http://www.gnu.org/software/emacs/manual/html_node/emacs/Rmail.html>`_
+   `Reading Mail with Rmail <https://www.gnu.org/software/emacs/manual/html_node/emacs/Rmail.html>`_
       The Rmail manual, with some information on Babyl semantics.
 
 
@@ -744,7 +748,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF.
    `mmdf man page from tin <http://www.tin.org/bin/man.cgi?section=5&topic=mmdf>`_
       A specification of MMDF format from the documentation of tin, a newsreader.
 
-   `MMDF <http://en.wikipedia.org/wiki/MMDF>`_
+   `MMDF <https://en.wikipedia.org/wiki/MMDF>`_
       A Wikipedia article describing the Multichannel Memorandum Distribution
       Facility.
 
index 8115e42..896afd1 100644 (file)
@@ -70,7 +70,7 @@ standard.  However, mailcap files are supported on most Unix systems.
 An example usage::
 
    >>> import mailcap
-   >>> d=mailcap.getcaps()
+   >>> d = mailcap.getcaps()
    >>> mailcap.findmatch(d, 'video/mpeg', filename='tmp1223')
    ('xmpeg tmp1223', {'view': 'xmpeg %s'})
 
index af43944..1ffc6ef 100644 (file)
@@ -5,6 +5,7 @@
    :synopsis: Convert Python objects to streams of bytes and back (with different
               constraints).
 
+--------------
 
 This module contains functions that can read and write Python values in a binary
 format.  The format is specific to Python, but independent of machine
@@ -16,7 +17,6 @@ rarely does). [#]_
 .. index::
    module: pickle
    module: shelve
-   object: code
 
 This is not a general "persistence" module.  For general persistence and
 transfer of Python objects through RPC calls, see the modules :mod:`pickle` and
@@ -34,13 +34,15 @@ supports a substantially wider range of objects than marshal.
    maliciously constructed data.  Never unmarshal data received from an
    untrusted or unauthenticated source.
 
+.. index:: object; code, code object
+
 Not all Python object types are supported; in general, only objects whose value
 is independent from a particular invocation of Python can be written and read by
 this module.  The following types are supported: booleans, integers, floating
 point numbers, complex numbers, strings, bytes, bytearrays, tuples, lists, sets,
 frozensets, dictionaries, and code objects, where it should be understood that
 tuples, lists, sets, frozensets and dictionaries are only supported as long as
-the values contained therein are themselves supported.
+the values contained therein are themselves supported.  The
 singletons :const:`None`, :const:`Ellipsis` and :exc:`StopIteration` can also be
 marshalled and unmarshalled.
 For format *version* lower than 3, recursive lists, sets and dictionaries cannot
index 244663e..3fdea18 100644 (file)
@@ -8,6 +8,8 @@
 
    from math import fsum
 
+--------------
+
 This module is always available.  It provides access to the mathematical
 functions defined by the C standard.
 
@@ -97,7 +99,7 @@ Number-theoretic and representation functions
 
    For further discussion and two alternative approaches, see the `ASPN cookbook
    recipes for accurate floating point summation
-   <http://code.activestate.com/recipes/393090/>`_\.
+   <https://code.activestate.com/recipes/393090/>`_\.
 
 
 .. function:: gcd(a, b)
@@ -204,7 +206,7 @@ Power and logarithmic functions
 
    Return ``e**x - 1``.  For small floats *x*, the subtraction in ``exp(x) - 1``
    can result in a `significant loss of precision
-   <http://en.wikipedia.org/wiki/Loss_of_significance>`_\; the :func:`expm1`
+   <https://en.wikipedia.org/wiki/Loss_of_significance>`_\; the :func:`expm1`
    function provides a way to compute this quantity to full precision::
 
       >>> from math import exp, expm1
@@ -332,7 +334,7 @@ Angular conversion
 Hyperbolic functions
 --------------------
 
-`Hyperbolic functions <http://en.wikipedia.org/wiki/Hyperbolic_function>`_
+`Hyperbolic functions <https://en.wikipedia.org/wiki/Hyperbolic_function>`_
 are analogs of trigonometric functions that are based on hyperbolas
 instead of circles.
 
@@ -371,12 +373,12 @@ Special functions
 
 .. function:: erf(x)
 
-   Return the `error function <http://en.wikipedia.org/wiki/Error_function>`_ at
+   Return the `error function <https://en.wikipedia.org/wiki/Error_function>`_ at
    *x*.
 
    The :func:`erf` function can be used to compute traditional statistical
    functions such as the `cumulative standard normal distribution
-   <http://en.wikipedia.org/wiki/Normal_distribution#Cumulative_distribution_function>`_::
+   <https://en.wikipedia.org/wiki/Normal_distribution#Cumulative_distribution_function>`_::
 
      def phi(x):
          'Cumulative distribution function for the standard normal distribution'
@@ -388,17 +390,17 @@ Special functions
 .. function:: erfc(x)
 
    Return the complementary error function at *x*.  The `complementary error
-   function <http://en.wikipedia.org/wiki/Error_function>`_ is defined as
+   function <https://en.wikipedia.org/wiki/Error_function>`_ is defined as
    ``1.0 - erf(x)``.  It is used for large values of *x* where a subtraction
    from one would cause a `loss of significance
-   <http://en.wikipedia.org/wiki/Loss_of_significance>`_\.
+   <https://en.wikipedia.org/wiki/Loss_of_significance>`_\.
 
    .. versionadded:: 3.2
 
 
 .. function:: gamma(x)
 
-   Return the `Gamma function <http://en.wikipedia.org/wiki/Gamma_function>`_ at
+   Return the `Gamma function <https://en.wikipedia.org/wiki/Gamma_function>`_ at
    *x*.
 
    .. versionadded:: 3.2
index 8739ea3..464248c 100644 (file)
@@ -3,13 +3,13 @@
 
 .. module:: mimetypes
    :synopsis: Mapping of filename extensions to MIME types.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
+**Source code:** :source:`Lib/mimetypes.py`
 
 .. index:: pair: MIME; content type
 
-**Source code:** :source:`Lib/mimetypes.py`
-
 --------------
 
 The :mod:`mimetypes` module converts between a filename or URL and the MIME type
@@ -44,7 +44,7 @@ the information :func:`init` sets up.
 
    The optional *strict* argument is a flag specifying whether the list of known MIME types
    is limited to only the official types `registered with IANA
-   <http://www.iana.org/assignments/media-types/media-types.xhtml>`_.
+   <https://www.iana.org/assignments/media-types/media-types.xhtml>`_.
    When *strict* is ``True`` (the default), only the IANA types are supported; when
    *strict* is ``False``, some additional non-standard but commonly used MIME types
    are also recognized.
index b74a823..8f53833 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: mmap
    :synopsis: Interface to memory-mapped files for Unix and Windows.
 
+--------------
 
 Memory-mapped file objects behave like both :class:`bytearray` and like
 :term:`file objects <file object>`.  You can use mmap objects in most places
@@ -127,7 +128,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
       import mmap
 
       with mmap.mmap(-1, 13) as mm:
-          mm.write("Hello world!")
+          mm.write(b"Hello world!")
 
    .. versionadded:: 3.2
       Context manager support.
@@ -144,7 +145,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
 
       pid = os.fork()
 
-      if pid == 0: # In a child process
+      if pid == 0:  # In a child process
           mm.seek(0)
           print(mm.readline())
 
@@ -174,7 +175,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
       Optional arguments *start* and *end* are interpreted as in slice notation.
       Returns ``-1`` on failure.
 
-      .. versionchanged: 3.5
+      .. versionchanged:: 3.5
          Writable :term:`bytes-like object` is now accepted.
 
 
@@ -237,7 +238,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
       Optional arguments *start* and *end* are interpreted as in slice notation.
       Returns ``-1`` on failure.
 
-      .. versionchanged: 3.5
+      .. versionchanged:: 3.5
          Writable :term:`bytes-like object` is now accepted.
 
 
@@ -267,7 +268,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
       were written. If the mmap was created with :const:`ACCESS_READ`, then
       writing to it will raise a :exc:`TypeError` exception.
 
-      .. versionchanged: 3.5
+      .. versionchanged:: 3.5
          Writable :term:`bytes-like object` is now accepted.
 
 
index e84a496..7b39ce7 100644 (file)
@@ -1,12 +1,11 @@
 :mod:`modulefinder` --- Find modules used by a script
 =====================================================
 
-.. sectionauthor:: A.M. Kuchling <amk@amk.ca>
-
-
 .. module:: modulefinder
    :synopsis: Find modules used by a script.
 
+.. sectionauthor:: A.M. Kuchling <amk@amk.ca>
+
 **Source code:** :source:`Lib/modulefinder.py`
 
 --------------
index 4145c8e..0a42032 100644 (file)
@@ -4,12 +4,16 @@
 .. module:: msilib
    :platform: Windows
    :synopsis: Creation of Microsoft Installer files, and CAB files.
+
 .. moduleauthor:: Martin v. Löwis <martin@v.loewis.de>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
 
+**Source code:** :source:`Lib/msilib/__init__.py`
 
 .. index:: single: msi
 
+--------------
+
 The :mod:`msilib` supports the creation of Microsoft Installer (``.msi``) files.
 Because these files often contain an embedded "cabinet" file (``.cab``), it also
 exposes an API to create CAB files. Support for reading ``.cab`` files is
@@ -120,9 +124,9 @@ structures.
 
 .. seealso::
 
-   `FCICreateFile <http://msdn.microsoft.com/library?url=/library/en-us/devnotes/winprog/fcicreate.asp>`_
-   `UuidCreate <http://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidcreate.asp>`_
-   `UuidToString <http://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidtostring.asp>`_
+   `FCICreateFile <https://msdn.microsoft.com/library?url=/library/en-us/devnotes/winprog/fcicreate.asp>`_
+   `UuidCreate <https://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidcreate.asp>`_
+   `UuidToString <https://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidtostring.asp>`_
 
 .. _database-objects:
 
@@ -151,9 +155,9 @@ Database Objects
 
 .. seealso::
 
-   `MSIDatabaseOpenView <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabaseopenview.asp>`_
-   `MSIDatabaseCommit <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabasecommit.asp>`_
-   `MSIGetSummaryInformation <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msigetsummaryinformation.asp>`_
+   `MSIDatabaseOpenView <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabaseopenview.asp>`_
+   `MSIDatabaseCommit <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabasecommit.asp>`_
+   `MSIGetSummaryInformation <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msigetsummaryinformation.asp>`_
 
 .. _view-objects:
 
@@ -199,11 +203,11 @@ View Objects
 
 .. seealso::
 
-   `MsiViewExecute <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewexecute.asp>`_
-   `MSIViewGetColumnInfo <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp>`_
-   `MsiViewFetch <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewfetch.asp>`_
-   `MsiViewModify <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewmodify.asp>`_
-   `MsiViewClose <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewclose.asp>`_
+   `MsiViewExecute <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewexecute.asp>`_
+   `MSIViewGetColumnInfo <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp>`_
+   `MsiViewFetch <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewfetch.asp>`_
+   `MsiViewModify <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewmodify.asp>`_
+   `MsiViewClose <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewclose.asp>`_
 
 .. _summary-objects:
 
@@ -243,10 +247,10 @@ Summary Information Objects
 
 .. seealso::
 
-   `MsiSummaryInfoGetProperty <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp>`_
-   `MsiSummaryInfoGetPropertyCount <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp>`_
-   `MsiSummaryInfoSetProperty <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp>`_
-   `MsiSummaryInfoPersist <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfopersist.asp>`_
+   `MsiSummaryInfoGetProperty <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp>`_
+   `MsiSummaryInfoGetPropertyCount <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp>`_
+   `MsiSummaryInfoSetProperty <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp>`_
+   `MsiSummaryInfoPersist <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfopersist.asp>`_
 
 .. _record-objects:
 
@@ -297,11 +301,11 @@ Record Objects
 
 .. seealso::
 
-   `MsiRecordGetFieldCount <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp>`_
-   `MsiRecordSetString <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstring.asp>`_
-   `MsiRecordSetStream <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstream.asp>`_
-   `MsiRecordSetInteger <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetinteger.asp>`_
-   `MsiRecordClear <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordclear.asp>`_
+   `MsiRecordGetFieldCount <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp>`_
+   `MsiRecordSetString <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstring.asp>`_
+   `MsiRecordSetStream <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstream.asp>`_
+   `MsiRecordSetInteger <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetinteger.asp>`_
+   `MsiRecordClear <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordclear.asp>`_
 
 .. _msi-errors:
 
@@ -393,10 +397,10 @@ Directory Objects
 
 .. seealso::
 
-   `Directory Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/directory_table.asp>`_
-   `File Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/file_table.asp>`_
-   `Component Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/component_table.asp>`_
-   `FeatureComponents Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/featurecomponents_table.asp>`_
+   `Directory Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/directory_table.asp>`_
+   `File Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/file_table.asp>`_
+   `Component Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/component_table.asp>`_
+   `FeatureComponents Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/featurecomponents_table.asp>`_
 
 .. _features:
 
@@ -421,7 +425,7 @@ Features
 
 .. seealso::
 
-   `Feature Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/feature_table.asp>`_
+   `Feature Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/feature_table.asp>`_
 
 .. _msi-gui:
 
@@ -516,13 +520,13 @@ for installing Python packages.
 
 .. seealso::
 
-   `Dialog Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/dialog_table.asp>`_
-   `Control Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/control_table.asp>`_
-   `Control Types <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controls.asp>`_
-   `ControlCondition Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlcondition_table.asp>`_
-   `ControlEvent Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlevent_table.asp>`_
-   `EventMapping Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/eventmapping_table.asp>`_
-   `RadioButton Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/radiobutton_table.asp>`_
+   `Dialog Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/dialog_table.asp>`_
+   `Control Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/control_table.asp>`_
+   `Control Types <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controls.asp>`_
+   `ControlCondition Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlcondition_table.asp>`_
+   `ControlEvent Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlevent_table.asp>`_
+   `EventMapping Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/eventmapping_table.asp>`_
+   `RadioButton Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/radiobutton_table.asp>`_
 
 .. _msi-tables:
 
index fadaf05..b334eeb 100644 (file)
@@ -4,8 +4,10 @@
 .. module:: msvcrt
    :platform: Windows
    :synopsis: Miscellaneous useful routines from the MS VC++ runtime.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
+--------------
 
 These functions provide access to some useful capabilities on Windows platforms.
 Some higher-level modules use these functions to build the  Windows
index 8575fb5..c5c092c 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: multiprocessing
    :synopsis: Process-based parallelism.
 
+**Source code:** :source:`Lib/multiprocessing/`
+
+--------------
 
 Introduction
 ------------
@@ -316,7 +319,7 @@ However, if you really do need to use some shared data then
    proxies.
 
    A manager returned by :func:`Manager` will support types
-   :class:`list`, :class:`dict`, :class:`Namespace`, :class:`Lock`,
+   :class:`list`, :class:`dict`, :class:`~managers.Namespace`, :class:`Lock`,
    :class:`RLock`, :class:`Semaphore`, :class:`BoundedSemaphore`,
    :class:`Condition`, :class:`Event`, :class:`Barrier`,
    :class:`Queue`, :class:`Value` and :class:`Array`.  For example, ::
@@ -361,8 +364,9 @@ processes in a few different ways.
 
 For example::
 
-   from multiprocessing import Pool
-   from time import sleep
+   from multiprocessing import Pool, TimeoutError
+   import time
+   import os
 
    def f(x):
        return x*x
@@ -378,15 +382,29 @@ For example::
            for i in pool.imap_unordered(f, range(10)):
                print(i)
 
-           # evaluate "f(10)" asynchronously
-           res = pool.apply_async(f, [10])
-           print(res.get(timeout=1))             # prints "100"
+           # evaluate "f(20)" asynchronously
+           res = pool.apply_async(f, (20,))      # runs in *only* one process
+           print(res.get(timeout=1))             # prints "400"
+
+           # evaluate "os.getpid()" asynchronously
+           res = pool.apply_async(os.getpid, ()) # runs in *only* one process
+           print(res.get(timeout=1))             # prints the PID of that process
+
+           # launching multiple evaluations asynchronously *may* use more processes
+           multiple_results = [pool.apply_async(os.getpid, ()) for i in range(4)]
+           print([res.get(timeout=1) for res in multiple_results])
 
-           # make worker sleep for 10 secs
-           res = pool.apply_async(sleep, [10])
-           print(res.get(timeout=1))             # raises multiprocessing.TimeoutError
+           # make a single worker sleep for 10 secs
+           res = pool.apply_async(time.sleep, (10,))
+           try:
+               print(res.get(timeout=1))
+           except TimeoutError:
+               print("We lacked patience and got a multiprocessing.TimeoutError")
+
+           print("For the moment, the pool remains available for more work")
 
        # exiting the 'with'-block has stopped the pool
+       print("Now the pool is closed and no longer available")
 
 Note that the methods of a pool should only ever be used by the
 process which created it.
@@ -901,8 +919,10 @@ Miscellaneous
    If the ``freeze_support()`` line is omitted then trying to run the frozen
    executable will raise :exc:`RuntimeError`.
 
-   If the module is being run normally by the Python interpreter then
-   :func:`freeze_support` has no effect.
+   Calling ``freeze_support()`` has no effect when invoked on any operating
+   system other than Windows.  In addition, if the module is being run
+   normally by the Python interpreter on Windows (the program has not been
+   frozen), then ``freeze_support()`` has no effect.
 
 .. function:: get_all_start_methods()
 
@@ -1745,24 +1765,26 @@ their parent process exits.  The manager classes are defined in the
          lproxy[0] = d
 
 
-Namespace objects
->>>>>>>>>>>>>>>>>
+.. class:: Namespace
 
-A namespace object has no public methods, but does have writable attributes.
-Its representation shows the values of its attributes.
+   A type that can register with :class:`SyncManager`.
 
-However, when using a proxy for a namespace object, an attribute beginning with
-``'_'`` will be an attribute of the proxy and not an attribute of the referent:
+   A namespace object has no public methods, but does have writable attributes.
+   Its representation shows the values of its attributes.
 
-.. doctest::
+   However, when using a proxy for a namespace object, an attribute beginning
+   with ``'_'`` will be an attribute of the proxy and not an attribute of the
+   referent:
+
+   .. doctest::
 
-   >>> manager = multiprocessing.Manager()
-   >>> Global = manager.Namespace()
-   >>> Global.x = 10
-   >>> Global.y = 'hello'
-   >>> Global._z = 12.3    # this is an attribute of the proxy
-   >>> print(Global)
-   Namespace(x=10, y='hello')
+    >>> manager = multiprocessing.Manager()
+    >>> Global = manager.Namespace()
+    >>> Global.x = 10
+    >>> Global.y = 'hello'
+    >>> Global._z = 12.3    # this is an attribute of the proxy
+    >>> print(Global)
+    Namespace(x=10, y='hello')
 
 
 Customized managers
@@ -2167,13 +2189,14 @@ with the :class:`Pool` class.
 The following example demonstrates the use of a pool::
 
    from multiprocessing import Pool
+   import time
 
    def f(x):
        return x*x
 
    if __name__ == '__main__':
        with Pool(processes=4) as pool:         # start 4 worker processes
-           result = pool.apply_async(f, (10,)) # evaluate "f(10)" asynchronously
+           result = pool.apply_async(f, (10,)) # evaluate "f(10)" asynchronously in a single process
            print(result.get(timeout=1))        # prints "100" unless your computer is *very* slow
 
            print(pool.map(f, range(10)))       # prints "[0, 1, 4,..., 81]"
@@ -2183,9 +2206,8 @@ The following example demonstrates the use of a pool::
            print(next(it))                     # prints "1"
            print(it.next(timeout=1))           # prints "4" unless your computer is *very* slow
 
-           import time
            result = pool.apply_async(time.sleep, (10,))
-           print(result.get(timeout=1))        # raises TimeoutError
+           print(result.get(timeout=1))        # raises multiprocessing.TimeoutError
 
 
 .. _multiprocessing-listeners-clients:
@@ -2459,7 +2481,7 @@ the connection.)
 
 If authentication is requested but no authentication key is specified then the
 return value of ``current_process().authkey`` is used (see
-:class:`~multiprocessing.Process`).  This value will automatically inherited by
+:class:`~multiprocessing.Process`).  This value will be automatically inherited by
 any :class:`~multiprocessing.Process` object that the current process creates.
 This means that (by default) all processes of a multi-process program will share
 a single authentication key which can be used when setting up connections
@@ -2644,8 +2666,8 @@ Explicitly pass resources to child processes
             ... do something using "lock" ...
 
         if __name__ == '__main__':
-           lock = Lock()
-           for i in range(10):
+            lock = Lock()
+            for i in range(10):
                 Process(target=f).start()
 
     should be rewritten as ::
@@ -2656,8 +2678,8 @@ Explicitly pass resources to child processes
             ... do something using "l" ...
 
         if __name__ == '__main__':
-           lock = Lock()
-           for i in range(10):
+            lock = Lock()
+            for i in range(10):
                 Process(target=f, args=(lock,)).start()
 
 Beware of replacing :data:`sys.stdin` with a "file like object"
@@ -2670,7 +2692,7 @@ Beware of replacing :data:`sys.stdin` with a "file like object"
     in issues with processes-in-processes. This has been changed to::
 
         sys.stdin.close()
-        sys.stdin = open(os.devnull)
+        sys.stdin = open(os.open(os.devnull, os.O_RDONLY), closefd=False)
 
     Which solves the fundamental issue of processes colliding with each other
     resulting in a bad file descriptor error, but introduces a potential danger
index 23ffed6..cdc2616 100644 (file)
@@ -4,6 +4,7 @@
 
 .. module:: netrc
    :synopsis: Loading of .netrc files.
+
 .. moduleauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
 .. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
 
index ade2a7a..10c67cb 100644 (file)
@@ -5,9 +5,11 @@
 .. module:: nis
    :platform: Unix
    :synopsis: Interface to Sun's NIS (Yellow Pages) library.
+
 .. moduleauthor:: Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
+--------------
 
 The :mod:`nis` module gives a thin wrapper around the NIS library, useful for
 central administration of several hosts.
@@ -26,7 +28,7 @@ The :mod:`nis` module defines the following functions:
 
    Note that *mapname* is first checked if it is an alias to another name.
 
-   The *domain* argument allows to override the NIS domain used for the lookup. If
+   The *domain* argument allows overriding the NIS domain used for the lookup. If
    unspecified, lookup is in the default NIS domain.
 
 
@@ -38,7 +40,7 @@ The :mod:`nis` module defines the following functions:
 
    Note that *mapname* is first checked if it is an alias to another name.
 
-   The *domain* argument allows to override the NIS domain used for the lookup. If
+   The *domain* argument allows overriding the NIS domain used for the lookup. If
    unspecified, lookup is in the default NIS domain.
 
 
@@ -46,7 +48,7 @@ The :mod:`nis` module defines the following functions:
 
    Return a list of all valid maps.
 
-   The *domain* argument allows to override the NIS domain used for the lookup. If
+   The *domain* argument allows overriding the NIS domain used for the lookup. If
    unspecified, lookup is in the default NIS domain.
 
 
index 9fb1b45..9790e3a 100644 (file)
@@ -4,13 +4,12 @@
 .. module:: nntplib
    :synopsis: NNTP protocol client (requires sockets).
 
+**Source code:** :source:`Lib/nntplib.py`
 
 .. index::
    pair: NNTP; protocol
    single: Network News Transfer Protocol
 
-**Source code:** :source:`Lib/nntplib.py`
-
 --------------
 
 This module defines the class :class:`NNTP` which implements the client side of
index 8ab07d0..1b59495 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: numbers
    :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.).
 
+**Source code:** :source:`Lib/numbers.py`
+
+--------------
 
 The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric
 :term:`abstract base classes <abstract base class>` which progressively define
@@ -35,7 +38,7 @@ The numeric tower
 
       Abstract. Retrieves the imaginary component of this number.
 
-   .. method:: conjugate()
+   .. abstractmethod:: conjugate()
 
       Abstract. Returns the complex conjugate. For example, ``(1+3j).conjugate()
       == (1-3j)``.
index c01e63b..8121b48 100644 (file)
@@ -3,16 +3,16 @@
 
 .. module:: operator
    :synopsis: Functions corresponding to the standard operators.
+
 .. sectionauthor:: Skip Montanaro <skip@automatrix.com>
 
+**Source code:** :source:`Lib/operator.py`
 
 .. testsetup::
 
    import operator
    from operator import itemgetter, iadd
 
-**Source code:** :source:`Lib/operator.py`
-
 --------------
 
 The :mod:`operator` module exports a set of efficient functions corresponding to
index 160c29d..9a4ba4e 100644 (file)
@@ -4,15 +4,16 @@
 .. module:: optparse
    :synopsis: Command-line option parsing library.
    :deprecated:
+
 .. moduleauthor:: Greg Ward <gward@python.net>
 .. sectionauthor:: Greg Ward <gward@python.net>
 
+**Source code:** :source:`Lib/optparse.py`
+
 .. deprecated:: 3.2
    The :mod:`optparse` module is deprecated and will not be developed further;
    development will continue with the :mod:`argparse` module.
 
-**Source code:** :source:`Lib/optparse.py`
-
 --------------
 
 :mod:`optparse` is a more convenient, flexible, and powerful library for parsing
@@ -25,7 +26,7 @@ GNU/POSIX syntax, and additionally generates usage and help messages for you.
 Here's an example of using :mod:`optparse` in a simple script::
 
    from optparse import OptionParser
-   [...]
+   ...
    parser = OptionParser()
    parser.add_option("-f", "--file", dest="filename",
                      help="write report to FILE", metavar="FILE")
@@ -252,7 +253,7 @@ First, you need to import the OptionParser class; then, early in the main
 program, create an OptionParser instance::
 
    from optparse import OptionParser
-   [...]
+   ...
    parser = OptionParser()
 
 Then you can start defining options.  The basic syntax is::
@@ -718,7 +719,7 @@ you can call :func:`OptionParser.error` to signal an application-defined error
 condition::
 
    (options, args) = parser.parse_args()
-   [...]
+   ...
    if options.a and options.b:
        parser.error("options -a and -b are mutually exclusive")
 
@@ -758,7 +759,7 @@ Putting it all together
 Here's what :mod:`optparse`\ -based scripts usually look like::
 
    from optparse import OptionParser
-   [...]
+   ...
    def main():
        usage = "usage: %prog [options] arg"
        parser = OptionParser(usage)
@@ -768,13 +769,13 @@ Here's what :mod:`optparse`\ -based scripts usually look like::
                          action="store_true", dest="verbose")
        parser.add_option("-q", "--quiet",
                          action="store_false", dest="verbose")
-       [...]
+       ...
        (options, args) = parser.parse_args()
        if len(args) != 1:
            parser.error("incorrect number of arguments")
        if options.verbose:
            print("reading %s..." % options.filename)
-       [...]
+       ...
 
    if __name__ == "__main__":
        main()
@@ -1409,7 +1410,7 @@ If you're not careful, it's easy to define options with conflicting option
 strings::
 
    parser.add_option("-n", "--dry-run", ...)
-   [...]
+   ...
    parser.add_option("-n", "--noisy", ...)
 
 (This is particularly true if you've defined your own OptionParser subclass with
@@ -1450,7 +1451,7 @@ that option.  If the user asks for help, the help message will reflect that::
 
    Options:
      --dry-run     do no harm
-     [...]
+     ...
      -n, --noisy   be noisy
 
 It's possible to whittle away the option strings for a previously-added option
@@ -1465,7 +1466,7 @@ At this point, the original ``-n``/``--dry-run`` option is no longer
 accessible, so :mod:`optparse` removes it, leaving this help text::
 
    Options:
-     [...]
+     ...
      -n, --noisy   be noisy
      --dry-run     new dry-run option
 
@@ -1701,7 +1702,7 @@ seen, but blow up if it comes after ``-b`` in the command-line.  ::
        if parser.values.b:
            raise OptionValueError("can't use -a after -b")
        parser.values.a = 1
-   [...]
+   ...
    parser.add_option("-a", action="callback", callback=check_order)
    parser.add_option("-b", action="store_true", dest="b")
 
@@ -1719,7 +1720,7 @@ message and the flag that it sets must be generalized.  ::
        if parser.values.b:
            raise OptionValueError("can't use %s after -b" % opt_str)
        setattr(parser.values, option.dest, 1)
-   [...]
+   ...
    parser.add_option("-a", action="callback", callback=check_order, dest='a')
    parser.add_option("-b", action="store_true", dest="b")
    parser.add_option("-c", action="callback", callback=check_order, dest='c')
@@ -1739,7 +1740,7 @@ should not be called when the moon is full, all you have to do is this::
            raise OptionValueError("%s option invalid when moon is full"
                                   % opt_str)
        setattr(parser.values, option.dest, 1)
-   [...]
+   ...
    parser.add_option("--foo",
                      action="callback", callback=check_moon, dest="foo")
 
@@ -1762,7 +1763,7 @@ Here's an example that just emulates the standard ``"store"`` action::
 
    def store_value(option, opt_str, value, parser):
        setattr(parser.values, option.dest, value)
-   [...]
+   ...
    parser.add_option("--foo",
                      action="callback", callback=store_value,
                      type="int", nargs=3, dest="foo")
@@ -1824,9 +1825,9 @@ arguments::
         del parser.rargs[:len(value)]
         setattr(parser.values, option.dest, value)
 
-   [...]
-   parser.add_option("-c", "--callback", dest="vararg_attr",
-                     action="callback", callback=vararg_callback)
+    ...
+    parser.add_option("-c", "--callback", dest="vararg_attr",
+                      action="callback", callback=vararg_callback)
 
 
 .. _optparse-extending-optparse:
index 4b4e0b4..bf0dfac 100644 (file)
@@ -4,8 +4,14 @@
 .. module:: os.path
    :synopsis: Operations on pathnames.
 
+**Source code:** :source:`Lib/posixpath.py` (for POSIX),
+:source:`Lib/ntpath.py` (for Windows NT),
+and :source:`Lib/macpath.py` (for Macintosh)
+
 .. index:: single: path; operations
 
+--------------
+
 This module implements some useful functions on pathnames. To read or
 write files see :func:`open`, and for accessing the filesystem see the
 :mod:`os` module. The path parameters can be passed as either strings,
@@ -214,7 +220,7 @@ the :mod:`glob` module.)
 .. function:: islink(path)
 
    Return ``True`` if *path* refers to a directory entry that is a symbolic link.
-   Always ``False`` if symbolic links are not supported by the python runtime.
+   Always ``False`` if symbolic links are not supported by the Python runtime.
 
 
 .. function:: ismount(path)
index 0cc9d9c..743efb6 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: os
    :synopsis: Miscellaneous operating system interfaces.
 
+**Source code:** :source:`Lib/os.py`
+
+--------------
 
 This module provides a portable way of using operating system dependent
 functionality.  If you just want to read or write a file see :func:`open`, if
@@ -894,7 +897,7 @@ The following constants are options for the *flags* parameter to the
 :func:`~os.open` function.  They can be combined using the bitwise OR operator
 ``|``.  Some of them are not available on all platforms.  For descriptions of
 their availability and use, consult the :manpage:`open(2)` manual page on Unix
-or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windows.
+or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windows.
 
 
 .. data:: O_RDONLY
@@ -1623,9 +1626,15 @@ features:
 
    Create a directory named *path* with numeric mode *mode*.
 
+   If the directory already exists, :exc:`FileExistsError` is raised.
+
+   .. _mkdir_modebits:
+
    On some systems, *mode* is ignored.  Where it is used, the current umask
-   value is first masked out.  If the directory already exists, :exc:`OSError`
-   is raised.
+   value is first masked out.  If bits other than the last 9 (i.e. the last 3
+   digits of the octal representation of the *mode*) are set, their meaning is
+   platform-dependent.  On some platforms, they are ignored and you should call
+   :func:`chmod` explicitly to set them.
 
    This function can also support :ref:`paths relative to directory descriptors
    <dir_fd>`.
@@ -1646,8 +1655,8 @@ features:
    Recursive directory creation function.  Like :func:`mkdir`, but makes all
    intermediate-level directories needed to contain the leaf directory.
 
-   The default *mode* is ``0o777`` (octal).  On some systems, *mode* is
-   ignored.  Where it is used, the current umask value is first masked out.
+   The *mode* parameter is passed to :func:`mkdir`; see :ref:`the mkdir()
+   description <mkdir_modebits>` for how it is interpreted.
 
    If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if the
    target directory already exists.
@@ -1762,7 +1771,7 @@ features:
    ``os.path.join(os.path.dirname(path), result)``.
 
    If the *path* is a string object, the result will also be a string object,
-   and the call may raise an UnicodeDecodeError. If the *path* is a bytes
+   and the call may raise a UnicodeDecodeError. If the *path* is a bytes
    object, the result will be a bytes object.
 
    This function can also support :ref:`paths relative to directory descriptors
@@ -1789,7 +1798,7 @@ features:
    be raised; on Unix, the directory entry is removed but the storage allocated
    to the file is not made available until the original file is no longer in use.
 
-   This function is identical to :func:`unlink`.
+   This function is semantically identical to :func:`unlink`.
 
    .. versionadded:: 3.3
       The *dir_fd* argument.
@@ -1907,9 +1916,9 @@ features:
       and
       `readdir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_
       functions. On Windows, it uses the Win32
-      `FindFirstFileW <http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx>`_
+      `FindFirstFileW <https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx>`_
       and
-      `FindNextFileW <http://msdn.microsoft.com/en-us/library/windows/desktop/aa364428(v=vs.85).aspx>`_
+      `FindNextFileW <https://msdn.microsoft.com/en-us/library/windows/desktop/aa364428(v=vs.85).aspx>`_
       functions.
 
    .. versionadded:: 3.5
@@ -1960,62 +1969,65 @@ features:
 
       Return the inode number of the entry.
 
-      The result is cached on the ``DirEntry`` object, use ``os.stat(entry.path,
+      The result is cached on the ``DirEntry`` object. Use ``os.stat(entry.path,
       follow_symlinks=False).st_ino`` to fetch up-to-date information.
 
-      On Unix, no system call is required.
+      On the first, uncached call, a system call is required on Windows but
+      not on Unix.
 
    .. method:: is_dir(\*, follow_symlinks=True)
 
-      If *follow_symlinks* is ``True`` (the default), return ``True`` if the
-      entry is a directory or a symbolic link pointing to a directory;
-      return ``False`` if it is or points to any other kind of file, or if it
-      doesn't exist anymore.
+      Return ``True`` if this entry is a directory or a symbolic link pointing
+      to a directory; return ``False`` if the entry is or points to any other
+      kind of file, or if it doesn't exist anymore.
 
       If *follow_symlinks* is ``False``, return ``True`` only if this entry
-      is a directory; return ``False`` if it is any other kind of file
-      or if it doesn't exist anymore.
+      is a directory (without following symlinks); return ``False`` if the
+      entry is any other kind of file or if it doesn't exist anymore.
 
-      The result is cached on the ``DirEntry`` object. Call :func:`os.stat`
-      along with :func:`stat.S_ISDIR` to fetch up-to-date information.
+      The result is cached on the ``DirEntry`` object, with a separate cache
+      for *follow_symlinks* ``True`` and ``False``. Call :func:`os.stat` along
+      with :func:`stat.S_ISDIR` to fetch up-to-date information.
+
+      On the first, uncached call, no system call is required in most cases.
+      Specifically, for non-symlinks, neither Windows or Unix require a system
+      call, except on certain Unix file systems, such as network file systems,
+      that return ``dirent.d_type == DT_UNKNOWN``. If the entry is a symlink,
+      a system call will be required to follow the symlink unless
+      *follow_symlinks* is ``False``.
 
       This method can raise :exc:`OSError`, such as :exc:`PermissionError`,
       but :exc:`FileNotFoundError` is caught and not raised.
 
-      In most cases, no system call is required.
-
    .. method:: is_file(\*, follow_symlinks=True)
 
-      If *follow_symlinks* is ``True`` (the default), return ``True`` if the
-      entry is a file or a symbolic link pointing to a file; return ``False``
-      if it is or points to a directory or other non-file entry, or if it
-      doesn't exist anymore.
+      Return ``True`` if this entry is a file or a symbolic link pointing to a
+      file; return ``False`` if the entry is or points to a directory or other
+      non-file entry, or if it doesn't exist anymore.
 
       If *follow_symlinks* is ``False``, return ``True`` only if this entry
-      is a file; return ``False`` if it is a directory or other non-file entry,
-      or if it doesn't exist anymore.
-
-      The result is cached on the ``DirEntry`` object. Call :func:`os.stat`
-      along with :func:`stat.S_ISREG` to fetch up-to-date information.
+      is a file (without following symlinks); return ``False`` if the entry is
+      a directory or other non-file entry, or if it doesn't exist anymore.
 
-      This method can raise :exc:`OSError`, such as :exc:`PermissionError`,
-      but :exc:`FileNotFoundError` is caught and not raised.
-
-      In most cases, no system call is required.
+      The result is cached on the ``DirEntry`` object. Caching, system calls
+      made, and exceptions raised are as per :func:`~DirEntry.is_dir`.
 
    .. method:: is_symlink()
 
       Return ``True`` if this entry is a symbolic link (even if broken);
-      return ``False`` if it points to a directory or any kind of file,
+      return ``False`` if the entry points to a directory or any kind of file,
       or if it doesn't exist anymore.
 
       The result is cached on the ``DirEntry`` object. Call
       :func:`os.path.islink` to fetch up-to-date information.
 
-      The method can raise :exc:`OSError`, such as :exc:`PermissionError`,
-      but :exc:`FileNotFoundError` is caught and not raised.
+      On the first, uncached call, no system call is required in most cases.
+      Specifically, neither Windows or Unix require a system call, except on
+      certain Unix file systems, such as network file systems, that return
+      ``dirent.d_type == DT_UNKNOWN``.
 
-      In most cases, no system call is required.
+      This method can raise :exc:`OSError`, such as :exc:`PermissionError`,
+      but :exc:`FileNotFoundError` is caught and not raised.
 
    .. method:: stat(\*, follow_symlinks=True)
 
@@ -2023,17 +2035,23 @@ features:
       follows symbolic links by default; to stat a symbolic link add the
       ``follow_symlinks=False`` argument.
 
-      On Unix, this method always requires a system call. On Windows,
-      ``DirEntry.stat()`` requires a system call only if the
-      entry is a symbolic link, and ``DirEntry.stat(follow_symlinks=False)``
-      never requires a system call.
+      On Unix, this method always requires a system call. On Windows, it
+      only requires a system call if *follow_symlinks* is ``True`` and the
+      entry is a symbolic link.
 
       On Windows, the ``st_ino``, ``st_dev`` and ``st_nlink`` attributes of the
       :class:`stat_result` are always set to zero. Call :func:`os.stat` to
       get these attributes.
 
-      The result is cached on the ``DirEntry`` object. Call :func:`os.stat`
-      to fetch up-to-date information.
+      The result is cached on the ``DirEntry`` object, with a separate cache
+      for *follow_symlinks* ``True`` and ``False``. Call :func:`os.stat` to
+      fetch up-to-date information.
+
+   Note that there is a nice correspondence between several attributes
+   and methods of ``DirEntry`` and of :class:`pathlib.Path`.  In
+   particular, the ``name`` and ``path`` attributes have the same
+   meaning, as do the ``is_dir()``, ``is_file()``, ``is_symlink()``
+   and ``stat()`` methods.
 
    .. versionadded:: 3.5
 
@@ -2452,10 +2470,10 @@ features:
 
 .. function:: unlink(path, *, dir_fd=None)
 
-   Remove (delete) the file *path*.  This function is identical to
-   :func:`remove`; the ``unlink`` name is its traditional Unix
-   name.  Please see the documentation for :func:`remove` for
-   further information.
+   Remove (delete) the file *path*.  This function is semantically
+   identical to :func:`remove`; the ``unlink`` name is its
+   traditional Unix name.  Please see the documentation for
+   :func:`remove` for further information.
 
    .. versionadded:: 3.3
       The *dir_fd* parameter.
@@ -3477,7 +3495,7 @@ operating system.
 
 .. data:: SCHED_RESET_ON_FORK
 
-   This flag can OR'ed with any other scheduling policy. When a process with
+   This flag can be OR'ed with any other scheduling policy. When a process with
    this flag set forks, its child's scheduling policy and priority are reset to
    the default.
 
@@ -3724,14 +3742,21 @@ Miscellaneous Functions
 
    This function returns random bytes from an OS-specific randomness source.  The
    returned data should be unpredictable enough for cryptographic applications,
-   though its exact quality depends on the OS implementation.  On a Unix-like
-   system this will query ``/dev/urandom``, and on Windows it will use
-   ``CryptGenRandom()``.  If a randomness source is not found,
+   though its exact quality depends on the OS implementation.
+
+   On Linux, ``getrandom()`` syscall is used if available and the urandom
+   entropy pool is initialized (``getrandom()`` does not block).
+   On a Unix-like system this will query ``/dev/urandom``. On Windows, it
+   will use ``CryptGenRandom()``.  If a randomness source is not found,
    :exc:`NotImplementedError` will be raised.
 
    For an easy-to-use interface to the random number generator
    provided by your platform, please see :class:`random.SystemRandom`.
 
+   .. versionchanged:: 3.5.2
+      On Linux, if ``getrandom()`` blocks (the urandom entropy pool is not
+      initialized yet), fall back on reading ``/dev/urandom``.
+
    .. versionchanged:: 3.5
       On Linux 3.17 and newer, the ``getrandom()`` syscall is now used
       when available.  On OpenBSD 5.6 and newer, the C ``getentropy()``
index c60d596..ec40c0b 100644 (file)
@@ -5,6 +5,7 @@
    :platform: Linux, FreeBSD
    :synopsis: Access to OSS-compatible audio devices.
 
+--------------
 
 This module allows you to access the OSS (Open Sound System) audio interface.
 OSS is available for a wide range of open-source and commercial Unices, and is
@@ -155,7 +156,7 @@ and (read-only) attributes:
    data may not be written
    ---see :meth:`writeall`.
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Writable :term:`bytes-like object` is now accepted.
 
 
@@ -169,7 +170,7 @@ and (read-only) attributes:
    no return value, since the amount of data written is always equal to the
    amount of data supplied.
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Writable :term:`bytes-like object` is now accepted.
 
 
index 43721b2..ee1ce50 100644 (file)
@@ -8,40 +8,40 @@ available for Python:
 
 .. seealso::
 
-   `PyGObject <https://live.gnome.org/PyGObject>`_
+   `PyGObject <https://wiki.gnome.org/Projects/PyGObject>`_
       provides introspection bindings for C libraries using
       `GObject <https://developer.gnome.org/gobject/stable/>`_.  One of
       these libraries is the `GTK+ 3 <http://www.gtk.org/>`_ widget set.
       GTK+ comes with many more widgets than Tkinter provides.  An online
-      `Python GTK+ 3 Tutorial <http://python-gtk-3-tutorial.readthedocs.org/en/latest/>`_
+      `Python GTK+ 3 Tutorial <https://python-gtk-3-tutorial.readthedocs.org/en/latest/>`_
       is available.
 
       `PyGTK <http://www.pygtk.org/>`_ provides bindings for an older version
       of the library, GTK+ 2.  It provides an object oriented interface that
       is slightly higher level than the C one.  There are also bindings to
-      `GNOME <http://www.gnome.org>`_.  An online `tutorial
+      `GNOME <https://www.gnome.org/>`_.  An online `tutorial
       <http://www.pygtk.org/pygtk2tutorial/index.html>`_ is available.
 
-   `PyQt <http://www.riverbankcomputing.co.uk/software/pyqt/intro>`_
+   `PyQt <https://riverbankcomputing.com/software/pyqt/intro>`_
       PyQt is a :program:`sip`\ -wrapped binding to the Qt toolkit.  Qt is an
       extensive C++ GUI application development framework that is
       available for Unix, Windows and Mac OS X. :program:`sip` is a tool
       for generating bindings for C++ libraries as Python classes, and
       is specifically designed for Python. The *PyQt3* bindings have a
       book, `GUI Programming with Python: QT Edition
-      <http://www.commandprompt.com/community/pyqt/>`_ by Boudewijn
+      <https://www.commandprompt.com/community/pyqt/>`_ by Boudewijn
       Rempt. The *PyQt4* bindings also have a book, `Rapid GUI Programming
-      with Python and Qt <http://www.qtrac.eu/pyqtbook.html>`_, by Mark
+      with Python and Qt <https://www.qtrac.eu/pyqtbook.html>`_, by Mark
       Summerfield.
 
-   `PySide <http://qt-project.org/wiki/PySide>`_
+   `PySide <https://wiki.qt.io/PySide>`_
       is a newer binding to the Qt toolkit, provided by Nokia.
       Compared to PyQt, its licensing scheme is friendlier to non-open source
       applications.
 
    `wxPython <http://www.wxpython.org>`_
       wxPython is a cross-platform GUI toolkit for Python that is built around
-      the popular `wxWidgets <http://www.wxwidgets.org/>`_ (formerly wxWindows)
+      the popular `wxWidgets <https://www.wxwidgets.org/>`_ (formerly wxWindows)
       C++ toolkit.  It provides a native look and feel for applications on
       Windows, Mac OS X, and Unix systems by using each platform's native
       widgets where ever possible, (GTK+ on Unix-like systems).  In addition to
@@ -50,7 +50,7 @@ available for Python:
       low-level device context drawing, drag and drop, system clipboard access,
       an XML-based resource format and more, including an ever growing library
       of user-contributed modules.  wxPython has a book, `wxPython in Action
-      <http://www.manning.com/rappin/>`_, by Noel Rappin and
+      <https://www.manning.com/books/wxpython-in-action>`_, by Noel Rappin and
       Robin Dunn.
 
 PyGTK, PyQt, and wxPython, all have a modern look and feel and more
index 3e1e31b..c3b699a 100644 (file)
@@ -3,10 +3,10 @@
 
 .. module:: parser
    :synopsis: Access parse trees for Python source code.
+
 .. moduleauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
-
 .. Copyright 1995 Virginia Polytechnic Institute and State University and Fred
    L. Drake, Jr.  This copyright notice must be distributed on all copies, but
    this document otherwise may be distributed as part of the Python
@@ -16,6 +16,8 @@
 
 .. index:: single: parsing; Python source code
 
+--------------
+
 The :mod:`parser` module provides an interface to Python's internal parser and
 byte-code compiler.  The primary purpose for this interface is to allow Python
 code to edit the parse tree of a Python expression and create executable code
index 2f06544..f803fb6 100644 (file)
@@ -5,9 +5,13 @@
 .. module:: pathlib
    :synopsis: Object-oriented filesystem paths
 
+.. versionadded:: 3.4
+
+**Source code:** :source:`Lib/pathlib.py`
+
 .. index:: single: path; operations
 
-.. versionadded:: 3.4
+--------------
 
 This module offers classes representing filesystem paths with semantics
 appropriate for different operating systems.  Path classes are divided
index c144db6..4520a9b 100644 (file)
@@ -8,10 +8,10 @@
 
 **Source code:** :source:`Lib/pdb.py`
 
---------------
-
 .. index:: single: debugging
 
+--------------
+
 The module :mod:`pdb` defines an interactive source code debugger for Python
 programs.  It supports setting (conditional) breakpoints and single stepping at
 the source line level, inspection of stack frames, source code listing, and
index 7e09b03..0d64191 100644 (file)
@@ -1,6 +1,14 @@
 :mod:`pickle` --- Python object serialization
 =============================================
 
+.. module:: pickle
+   :synopsis: Convert Python objects to streams of bytes and back.
+
+.. sectionauthor:: Jim Kerr <jbkerr@sr.hp.com>.
+.. sectionauthor:: Barry Warsaw <barry@python.org>
+
+**Source code:** :source:`Lib/pickle.py`
+
 .. index::
    single: persistence
    pair: persistent; objects
@@ -9,11 +17,7 @@
    pair: flattening; objects
    pair: pickling; objects
 
-.. module:: pickle
-   :synopsis: Convert Python objects to streams of bytes and back.
-.. sectionauthor:: Jim Kerr <jbkerr@sr.hp.com>.
-.. sectionauthor:: Barry Warsaw <barry@python.org>
-
+--------------
 
 The :mod:`pickle` module implements binary protocols for serializing and
 de-serializing a Python object structure.  *"Pickling"* is the process
index 69e891d..0a22da1 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: pipes
    :platform: Unix
    :synopsis: A Python interface to Unix shell pipelines.
+
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
 **Source code:** :source:`Lib/pipes.py`
index 5d3295d..26c5ac0 100644 (file)
@@ -140,7 +140,7 @@ support.
 .. function:: iter_modules(path=None, prefix='')
 
    Yields ``(module_finder, name, ispkg)`` for all submodules on *path*, or, if
-   path is ``None``, all top-level modules on ``sys.path``.
+   *path* is ``None``, all top-level modules on ``sys.path``.
 
    *path* should be either ``None`` or a list of paths to look for modules in.
 
@@ -161,7 +161,7 @@ support.
 .. function:: walk_packages(path=None, prefix='', onerror=None)
 
    Yields ``(module_finder, name, ispkg)`` for all modules recursively on
-   *path*, or, if path is ``None``, all accessible modules.
+   *path*, or, if *path* is ``None``, all accessible modules.
 
    *path* should be either ``None`` or a list of paths to look for modules in.
 
index e679317..eea0abb 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: platform
    :synopsis: Retrieves as much platform identifying data as possible.
+
 .. moduleauthor:: Marc-André Lemburg <mal@egenix.com>
 .. sectionauthor:: Bjorn Pettersen <bpettersen@corp.fairisaac.com>
 
index 2c1f3dd..9ba2266 100644 (file)
@@ -3,16 +3,17 @@
 
 .. module:: plistlib
    :synopsis: Generate and parse Mac OS X plist files.
+
 .. moduleauthor:: Jack Jansen
 .. sectionauthor:: Georg Brandl <georg@python.org>
 .. (harvested from docstrings in the original file)
 
+**Source code:** :source:`Lib/plistlib.py`
+
 .. index::
    pair: plist; file
    single: property list
 
-**Source code:** :source:`Lib/plistlib.py`
-
 --------------
 
 This module provides an interface for reading and writing the "property list"
index 8468f4c..ffabc32 100644 (file)
@@ -3,13 +3,14 @@
 
 .. module:: poplib
    :synopsis: POP3 protocol client (requires sockets).
+
 .. sectionauthor:: Andrew T. Csillag
 .. revised by ESR, January 2000
 
-.. index:: pair: POP3; protocol
-
 **Source code:** :source:`Lib/poplib.py`
 
+.. index:: pair: POP3; protocol
+
 --------------
 
 This module defines a class, :class:`POP3`, which encapsulates a connection to a
index 06bab04..9cbc550 100644 (file)
@@ -5,6 +5,7 @@
    :platform: Unix
    :synopsis: The most common POSIX system calls (normally used via module os).
 
+--------------
 
 This module provides access to operating system functionality that is
 standardized by the C Standard and the POSIX standard (a thinly disguised Unix
index 0b44dc8..65d94fe 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: pprint
    :synopsis: Data pretty printer.
+
 .. moduleauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
@@ -197,7 +198,7 @@ are converted to strings.  The default implementation uses the internals of the
    the current presentation context (direct and indirect containers for *object*
    that are affecting the presentation) as the keys; if an object needs to be
    presented which is already represented in *context*, the third return value
-   should be ``True``.  Recursive calls to the :meth:`format` method should add
+   should be ``True``.  Recursive calls to the :meth:`.format` method should add
    additional entries for containers to this dictionary.  The third argument,
    *maxlevels*, gives the requested limit to recursion; this will be ``0`` if there
    is no requested limit.  This argument should be passed unmodified to recursive
index b8a3897..0ab7660 100644 (file)
@@ -4,9 +4,13 @@
 .. module:: pty
    :platform: Linux
    :synopsis: Pseudo-Terminal Handling for Linux.
+
 .. moduleauthor:: Steen Lumholt
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
+**Source code:** :source:`Lib/pty.py`
+
+--------------
 
 The :mod:`pty` module defines operations for handling the pseudo-terminal
 concept: starting another process and being able to write to and read from its
index 2c17d9e..03ebb02 100644 (file)
@@ -5,6 +5,7 @@
    :platform: Unix
    :synopsis: The password database (getpwnam() and friends).
 
+--------------
 
 This module provides access to the Unix user account and password database.  It
 is available on all Unix versions.
index 97f2b20..65f76b8 100644 (file)
@@ -3,13 +3,14 @@
 
 .. module:: py_compile
    :synopsis: Generate byte-code files from Python source files.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. documentation based on module docstrings
 
-.. index:: pair: file; byte-code
-
 **Source code:** :source:`Lib/py_compile.py`
 
+.. index:: pair: file; byte-code
+
 --------------
 
 The :mod:`py_compile` module provides a function to generate a byte-code file
index 13eaabf..3284271 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: pyclbr
    :synopsis: Supports information extraction for a Python class browser.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
 **Source code:** :source:`Lib/pyclbr.py`
index b5e3233..f1bfab9 100644 (file)
@@ -3,17 +3,17 @@
 
 .. module:: pydoc
    :synopsis: Documentation generator and online help system.
+
 .. moduleauthor:: Ka-Ping Yee <ping@lfw.org>
 .. sectionauthor:: Ka-Ping Yee <ping@lfw.org>
 
+**Source code:** :source:`Lib/pydoc.py`
 
 .. index::
    single: documentation; generation
    single: documentation; online
    single: help; online
 
-**Source code:** :source:`Lib/pydoc.py`
-
 --------------
 
 The :mod:`pydoc` module automatically generates documentation from Python
index 620ffb1..29c9f34 100644 (file)
@@ -3,8 +3,10 @@
 
 .. module:: xml.parsers.expat
    :synopsis: An interface to the Expat non-validating XML parser.
+
 .. moduleauthor:: Paul Prescod <paul@prescod.net>
 
+--------------
 
 .. Markup notes:
 
@@ -570,9 +572,9 @@ Content Model Descriptions
 
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
-Content modules are described using nested tuples.  Each tuple contains four
+Content models are described using nested tuples.  Each tuple contains four
 values: the type, the quantifier, the name, and a tuple of children.  Children
-are simply additional content module descriptions.
+are simply additional content model descriptions.
 
 The values of the first two fields are constants defined in the
 :mod:`xml.parsers.expat.model` module.  These constants can be collected in two
@@ -867,6 +869,6 @@ The ``errors`` module has the following attributes:
 
 .. [#] The encoding string included in XML output should conform to the
    appropriate standards. For example, "UTF-8" is valid, but "UTF8" is
-   not. See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl
-   and http://www.iana.org/assignments/character-sets/character-sets.xhtml.
+   not. See https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl
+   and https://www.iana.org/assignments/character-sets/character-sets.xhtml.
 
index 3a74cf8..3c31125 100644 (file)
@@ -4,13 +4,12 @@
 .. module:: quopri
    :synopsis: Encode and decode files using the MIME quoted-printable encoding.
 
+**Source code:** :source:`Lib/quopri.py`
 
 .. index::
    pair: quoted-printable; encoding
    single: MIME; quoted-printable encoding
 
-**Source code:** :source:`Lib/quopri.py`
-
 --------------
 
 This module performs quoted-printable transport encoding and decoding, as
index f8b7727..df502a0 100644 (file)
@@ -20,7 +20,7 @@ On the real line, there are functions to compute uniform, normal (Gaussian),
 lognormal, negative exponential, gamma, and beta distributions. For generating
 distributions of angles, the von Mises distribution is available.
 
-Almost all module functions depend on the basic function :func:`random`, which
+Almost all module functions depend on the basic function :func:`.random`, which
 generates a random float uniformly in the semi-open range [0.0, 1.0).  Python
 uses the Mersenne Twister as the core generator.  It produces 53-bit precision
 floats and has a period of 2\*\*19937-1.  The underlying implementation in C is
@@ -34,9 +34,9 @@ instance of the :class:`random.Random` class.  You can instantiate your own
 instances of :class:`Random` to get generators that don't share state.
 
 Class :class:`Random` can also be subclassed if you want to use a different
-basic generator of your own devising: in that case, override the :meth:`random`,
-:meth:`seed`, :meth:`getstate`, and :meth:`setstate` methods.
-Optionally, a new generator can supply a :meth:`getrandbits` method --- this
+basic generator of your own devising: in that case, override the :meth:`~Random.random`,
+:meth:`~Random.seed`, :meth:`~Random.getstate`, and :meth:`~Random.setstate` methods.
+Optionally, a new generator can supply a :meth:`~Random.getrandbits` method --- this
 allows :meth:`randrange` to produce selections over an arbitrarily large range.
 
 The :mod:`random` module also provides the :class:`SystemRandom` class which
@@ -125,7 +125,7 @@ Functions for sequences:
 
    Shuffle the sequence *x* in place. The optional argument *random* is a
    0-argument function returning a random float in [0.0, 1.0); by default, this is
-   the function :func:`random`.
+   the function :func:`.random`.
 
    Note that for even rather small ``len(x)``, the total number of permutations of
    *x* is larger than the period of most random number generators; this implies
@@ -267,7 +267,7 @@ Alternative Generator:
 
 
    `Complementary-Multiply-with-Carry recipe
-   <http://code.activestate.com/recipes/576707/>`_ for a compatible alternative
+   <https://code.activestate.com/recipes/576707/>`_ for a compatible alternative
    random number generator with a long period and comparatively simple update
    operations.
 
@@ -285,7 +285,7 @@ change across Python versions, but two aspects are guaranteed not to change:
 * If a new seeding method is added, then a backward compatible seeder will be
   offered.
 
-* The generator's :meth:`random` method will continue to produce the same
+* The generator's :meth:`~Random.random` method will continue to produce the same
   sequence when the compatible seeder is given the same seed.
 
 .. _random-examples:
index a9f8161..18d5596 100644 (file)
@@ -3,16 +3,20 @@
 
 .. module:: re
    :synopsis: Regular expression operations.
+
 .. moduleauthor:: Fredrik Lundh <fredrik@pythonware.com>
 .. sectionauthor:: Andrew M. Kuchling <amk@amk.ca>
 
+**Source code:** :source:`Lib/re.py`
+
+--------------
 
 This module provides regular expression matching operations similar to
 those found in Perl.
 
 Both patterns and strings to be searched can be Unicode strings as well as
 8-bit strings. However, Unicode strings and 8-bit strings cannot be mixed:
-that is, you cannot match an Unicode string with a byte pattern or
+that is, you cannot match a Unicode string with a byte pattern or
 vice-versa; similarly, when asking for a substitution, the replacement
 string must be of the same type as both the pattern and the search string.
 
@@ -113,11 +117,11 @@ The special characters are:
 ``*?``, ``+?``, ``??``
    The ``'*'``, ``'+'``, and ``'?'`` qualifiers are all :dfn:`greedy`; they match
    as much text as possible.  Sometimes this behaviour isn't desired; if the RE
-   ``<.*>`` is matched against ``'<H1>title</H1>'``, it will match the entire
-   string, and not just ``'<H1>'``.  Adding ``'?'`` after the qualifier makes it
+   ``<.*>`` is matched against ``<a> b <c>``, it will match the entire
+   string, and not just ``<a>``.  Adding ``?`` after the qualifier makes it
    perform the match in :dfn:`non-greedy` or :dfn:`minimal` fashion; as *few*
-   characters as possible will be matched.  Using ``.*?`` in the previous
-   expression will match only ``'<H1>'``.
+   characters as possible will be matched.  Using the RE ``<.*?>`` will match
+   only ``<a>``.
 
 ``{m}``
    Specifies that exactly *m* copies of the previous RE should be matched; fewer
@@ -297,7 +301,7 @@ The special characters are:
       >>> m.group(0)
       'egg'
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Added support for group references of fixed length.
 
 ``(?<!...)``
@@ -811,8 +815,8 @@ attributes:
 
 .. method:: regex.search(string[, pos[, endpos]])
 
-   Scan through *string* looking for a location where this regular expression
-   produces a match, and return a corresponding :ref:`match object
+   Scan through *string* looking for the first location where this regular
+   expression produces a match, and return a corresponding :ref:`match object
    <match-objects>`.  Return ``None`` if no position in the string matches the
    pattern; note that this is different from finding a zero-length match at some
    point in the string.
@@ -1234,15 +1238,15 @@ does by default).
 
 For example::
 
-   >>> re.match("c", "abcdef")  # No match
-   >>> re.search("c", "abcdef") # Match
+   >>> re.match("c", "abcdef")    # No match
+   >>> re.search("c", "abcdef")   # Match
    <_sre.SRE_Match object; span=(2, 3), match='c'>
 
 Regular expressions beginning with ``'^'`` can be used with :func:`search` to
 restrict the match at the beginning of the string::
 
-   >>> re.match("c", "abcdef")  # No match
-   >>> re.search("^c", "abcdef") # No match
+   >>> re.match("c", "abcdef")    # No match
+   >>> re.search("^c", "abcdef")  # No match
    >>> re.search("^a", "abcdef")  # Match
    <_sre.SRE_Match object; span=(0, 1), match='a'>
 
@@ -1323,9 +1327,9 @@ a function to "munge" text, or randomize the order of all the characters
 in each word of a sentence except for the first and last characters::
 
    >>> def repl(m):
-   ...   inner_word = list(m.group(2))
-   ...   random.shuffle(inner_word)
-   ...   return m.group(1) + "".join(inner_word) + m.group(3)
+   ...     inner_word = list(m.group(2))
+   ...     random.shuffle(inner_word)
+   ...     return m.group(1) + "".join(inner_word) + m.group(3)
    >>> text = "Professor Abdolmalek, please report your absences promptly."
    >>> re.sub(r"(\w)(\w+)(\w)", repl, text)
    'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
@@ -1389,7 +1393,7 @@ functionally identical:
 Writing a Tokenizer
 ^^^^^^^^^^^^^^^^^^^
 
-A `tokenizer or scanner <http://en.wikipedia.org/wiki/Lexical_analysis>`_
+A `tokenizer or scanner <https://en.wikipedia.org/wiki/Lexical_analysis>`_
 analyzes a string to categorize groups of characters.  This is a useful first
 step in writing a compiler or interpreter.
 
@@ -1405,14 +1409,14 @@ successive matches::
     def tokenize(code):
         keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
         token_specification = [
-            ('NUMBER',  r'\d+(\.\d*)?'), # Integer or decimal number
-            ('ASSIGN',  r':='),          # Assignment operator
-            ('END',     r';'),           # Statement terminator
-            ('ID',      r'[A-Za-z]+'),   # Identifiers
-            ('OP',      r'[+\-*/]'),     # Arithmetic operators
-            ('NEWLINE', r'\n'),          # Line endings
-            ('SKIP',    r'[ \t]+'),      # Skip over spaces and tabs
-            ('MISMATCH',r'.'),           # Any other character
+            ('NUMBER',  r'\d+(\.\d*)?'),  # Integer or decimal number
+            ('ASSIGN',  r':='),           # Assignment operator
+            ('END',     r';'),            # Statement terminator
+            ('ID',      r'[A-Za-z]+'),    # Identifiers
+            ('OP',      r'[+\-*/]'),      # Arithmetic operators
+            ('NEWLINE', r'\n'),           # Line endings
+            ('SKIP',    r'[ \t]+'),       # Skip over spaces and tabs
+            ('MISMATCH',r'.'),            # Any other character
         ]
         tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
         line_num = 1
index b3d765c..e17e69c 100644 (file)
 .. module:: readline
    :platform: Unix
    :synopsis: GNU readline support for Python.
+
 .. sectionauthor:: Skip Montanaro <skip@pobox.com>
 
+--------------
 
 The :mod:`readline` module defines a number of functions to facilitate
 completion and reading/writing of history files from the Python interpreter.
-This module can be used directly or via the :mod:`rlcompleter` module.  Settings
+This module can be used directly, or via the :mod:`rlcompleter` module, which
+supports completion of Python identifiers at the interactive prompt.  Settings
 made using  this module affect the behaviour of both the interpreter's
 interactive prompt  and the prompts offered by the built-in :func:`input`
 function.
 
 .. note::
 
-  On MacOS X the :mod:`readline` module can be implemented using
+  The underlying Readline library API may be implemented by
   the ``libedit`` library instead of GNU readline.
+  On MacOS X the :mod:`readline` module detects which library is being used
+  at run time.
 
   The configuration file for ``libedit`` is different from that
   of GNU readline. If you programmatically load configuration strings
   you can check for the text "libedit" in :const:`readline.__doc__`
   to differentiate between GNU readline and libedit.
 
+Readline keybindings may be configured via an initialization file, typically
+``.inputrc`` in your home directory.  See `Readline Init File
+<https://cnswww.cns.cwru.edu/php/chet/readline/rluserman.html#SEC9>`_
+in the GNU Readline manual for information about the format and
+allowable constructs of that file, and the capabilities of the
+Readline library in general.
+
+
+Init file
+---------
 
-The :mod:`readline` module defines the following functions:
+The following functions relate to the init file and user configuration:
 
 
 .. function:: parse_and_bind(string)
 
-   Parse and execute single line of a readline init file.
+   Execute the init line provided in the *string* argument. This calls
+   :c:func:`rl_parse_and_bind` in the underlying library.
+
+
+.. function:: read_init_file([filename])
+
+   Execute a readline initialization file. The default filename is the last filename
+   used. This calls :c:func:`rl_read_init_file` in the underlying library.
+
+
+Line buffer
+-----------
+
+The following functions operate on the line buffer:
 
 
 .. function:: get_line_buffer()
 
-   Return the current contents of the line buffer.
+   Return the current contents of the line buffer (:c:data:`rl_line_buffer`
+   in the underlying library).
 
 
 .. function:: insert_text(string)
 
-   Insert text into the command line.
+   Insert text into the line buffer at the cursor position.  This calls
+   :c:func:`rl_insert_text` in the underlying library, but ignores
+   the return value.
 
 
-.. function:: read_init_file([filename])
+.. function:: redisplay()
+
+   Change what's displayed on the screen to reflect the current contents of the
+   line buffer.  This calls :c:func:`rl_redisplay` in the underlying library.
 
-   Parse a readline initialization file. The default filename is the last filename
-   used.
+
+History file
+------------
+
+The following functions operate on a history file:
 
 
 .. function:: read_history_file([filename])
 
-   Load a readline history file. The default filename is :file:`~/.history`.
+   Load a readline history file, and append it to the history list.
+   The default filename is :file:`~/.history`.  This calls
+   :c:func:`read_history` in the underlying library.
 
 
 .. function:: write_history_file([filename])
 
-   Save a readline history file. The default filename is :file:`~/.history`.
+   Save the history list to a readline history file, overwriting any
+   existing file.  The default filename is :file:`~/.history`.  This calls
+   :c:func:`write_history` in the underlying library.
 
 
 .. function:: append_history_file(nelements[, filename])
 
-   Append the last *nelements* of history to a file.  The default filename is
-   :file:`~/.history`.  The file must already exist.
+   Append the last *nelements* items of history to a file.  The default filename is
+   :file:`~/.history`.  The file must already exist.  This calls
+   :c:func:`append_history` in the underlying library.
 
    .. versionadded:: 3.5
 
 
-.. function:: clear_history()
+.. function:: get_history_length()
+              set_history_length(length)
 
-   Clear the current history.  (Note: this function is not available if the
-   installed version of GNU readline doesn't support it.)
+   Set or return the desired number of lines to save in the history file.
+   The :func:`write_history_file` function uses this value to truncate
+   the history file, by calling :c:func:`history_truncate_file` in
+   the underlying library.  Negative values imply
+   unlimited history file size.
 
 
-.. function:: get_history_length()
+History list
+------------
 
-   Return the desired length of the history file.  Negative values imply unlimited
-   history file size.
+The following functions operate on a global history list:
 
 
-.. function:: set_history_length(length)
+.. function:: clear_history()
 
-   Set the number of lines to save in the history file. :func:`write_history_file`
-   uses this value to truncate the history file when saving.  Negative values imply
-   unlimited history file size.
+   Clear the current history.  This calls :c:func:`clear_history` in the
+   underlying library.  The Python function only exists if Python was
+   compiled for a version of the library that supports it.
 
 
 .. function:: get_current_history_length()
 
-   Return the number of lines currently in the history.  (This is different from
+   Return the number of items currently in the history.  (This is different from
    :func:`get_history_length`, which returns the maximum number of lines that will
    be written to a history file.)
 
 
 .. function:: get_history_item(index)
 
-   Return the current contents of history item at *index*.
+   Return the current contents of history item at *index*.  The item index
+   is one-based.  This calls :c:func:`history_get` in the underlying library.
 
 
 .. function:: remove_history_item(pos)
 
    Remove history item specified by its position from the history.
+   The position is zero-based.  This calls :c:func:`remove_history` in
+   the underlying library.
 
 
 .. function:: replace_history_item(pos, line)
 
-   Replace history item specified by its position with the given line.
+   Replace history item specified by its position with *line*.
+   The position is zero-based.  This calls :c:func:`replace_history_entry`
+   in the underlying library.
 
 
-.. function:: redisplay()
+.. function:: add_history(line)
 
-   Change what's displayed on the screen to reflect the current contents of the
-   line buffer.
+   Append *line* to the history buffer, as if it was the last line typed.
+   This calls :c:func:`add_history` in the underlying library.
+
+
+Startup hooks
+-------------
 
 
 .. function:: set_startup_hook([function])
 
-   Set or remove the startup_hook function.  If *function* is specified, it will be
-   used as the new startup_hook function; if omitted or ``None``, any hook function
-   already installed is removed.  The startup_hook function is called with no
+   Set or remove the function invoked by the :c:data:`rl_startup_hook`
+   callback of the underlying library.  If *function* is specified, it will
+   be used as the new hook function; if omitted or ``None``, any function
+   already installed is removed.  The hook is called with no
    arguments just before readline prints the first prompt.
 
 
 .. function:: set_pre_input_hook([function])
 
-   Set or remove the pre_input_hook function.  If *function* is specified, it will
-   be used as the new pre_input_hook function; if omitted or ``None``, any hook
-   function already installed is removed.  The pre_input_hook function is called
+   Set or remove the function invoked by the :c:data:`rl_pre_input_hook`
+   callback of the underlying library.  If *function* is specified, it will
+   be used as the new hook function; if omitted or ``None``, any
+   function already installed is removed.  The hook is called
    with no arguments after the first prompt has been printed and just before
    readline starts reading input characters.
 
 
+Completion
+----------
+
+The following functions relate to implementing a custom word completion
+function.  This is typically operated by the Tab key, and can suggest and
+automatically complete a word being typed.  By default, Readline is set up
+to be used by :mod:`rlcompleter` to complete Python identifiers for
+the interactive interpreter.  If the :mod:`readline` module is to be used
+with a custom completer, a different set of word delimiters should be set.
+
+
 .. function:: set_completer([function])
 
    Set or remove the completer function.  If *function* is specified, it will be
@@ -140,6 +208,12 @@ The :mod:`readline` module defines the following functions:
    returns a non-string value.  It should return the next possible completion
    starting with *text*.
 
+   The installed completer function is invoked by the *entry_func* callback
+   passed to :c:func:`rl_completion_matches` in the underlying library.
+   The *text* string comes from the first parameter to the
+   :c:data:`rl_attempted_completion_function` callback of the
+   underlying library.
+
 
 .. function:: get_completer()
 
@@ -148,27 +222,27 @@ The :mod:`readline` module defines the following functions:
 
 .. function:: get_completion_type()
 
-   Get the type of completion being attempted.
+   Get the type of completion being attempted.  This returns the
+   :c:data:`rl_completion_type` variable in the underlying library as
+   an integer.
 
 
 .. function:: get_begidx()
+              get_endidx()
 
-   Get the beginning index of the readline tab-completion scope.
-
-
-.. function:: get_endidx()
-
-   Get the ending index of the readline tab-completion scope.
+   Get the beginning or ending index of the completion scope.
+   These indexes are the *start* and *end* arguments passed to the
+   :c:data:`rl_attempted_completion_function` callback of the
+   underlying library.
 
 
 .. function:: set_completer_delims(string)
+              get_completer_delims()
 
-   Set the readline word delimiters for tab-completion.
-
-
-.. function:: get_completer_delims()
-
-   Get the readline word delimiters for tab-completion.
+   Set or get the word delimiters for completion.  These determine the
+   start of the word to be considered for completion (the completion scope).
+   These functions access the :c:data:`rl_completer_word_break_characters`
+   variable in the underlying library.
 
 
 .. function:: set_completion_display_matches_hook([function])
@@ -176,21 +250,13 @@ The :mod:`readline` module defines the following functions:
    Set or remove the completion display function.  If *function* is
    specified, it will be used as the new completion display function;
    if omitted or ``None``, any completion display function already
-   installed is removed.  The completion display function is called as
+   installed is removed.  This sets or clears the
+   :c:data:`rl_completion_display_matches_hook` callback in the
+   underlying library.  The completion display function is called as
    ``function(substitution, [matches], longest_match_length)`` once
    each time matches need to be displayed.
 
 
-.. function:: add_history(line)
-
-   Append a line to the history buffer, as if it was the last line typed.
-
-.. seealso::
-
-   Module :mod:`rlcompleter`
-      Completion of Python identifiers at the interactive prompt.
-
-
 .. _readline-example:
 
 Example
@@ -209,6 +275,8 @@ from the user's :envvar:`PYTHONSTARTUP` file. ::
    histfile = os.path.join(os.path.expanduser("~"), ".python_history")
    try:
        readline.read_history_file(histfile)
+       # default history len is -1 (infinite), which may grow unruly
+       readline.set_history_length(1000)
    except FileNotFoundError:
        pass
 
@@ -234,6 +302,7 @@ sessions, by only appending the new history. ::
 
    def save(prev_h_len, histfile):
        new_h_len = readline.get_history_length()
+       readline.set_history_length(1000)
        readline.append_history_file(new_h_len - prev_h_len, histfile)
    atexit.register(save, h_len, histfile)
 
@@ -261,4 +330,5 @@ support history save/restore. ::
                atexit.register(self.save_history, histfile)
 
        def save_history(self, histfile):
+           readline.set_history_length(1000)
            readline.write_history_file(histfile)
index ee9a10d..0905b98 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: reprlib
    :synopsis: Alternate repr() implementation with size limits.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
 **Source code:** :source:`Lib/reprlib.py`
index a7b229e..b213793 100644 (file)
@@ -4,9 +4,11 @@
 .. module:: resource
    :platform: Unix
    :synopsis: An interface to provide resource usage information on the current process.
+
 .. moduleauthor:: Jeremy Hylton <jeremy@alum.mit.edu>
 .. sectionauthor:: Jeremy Hylton <jeremy@alum.mit.edu>
 
+--------------
 
 This module provides basic mechanisms for measuring and controlling system
 resources utilized by a program.
index 9ed01c7..40b09ce 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: rlcompleter
    :synopsis: Python identifier completion, suitable for the GNU readline library.
+
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
 **Source code:** :source:`Lib/rlcompleter.py`
index 7293f15..af35e81 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: runpy
    :synopsis: Locate and run Python modules without importing them first.
+
 .. moduleauthor:: Nick Coghlan <ncoghlan@gmail.com>
 
 **Source code:** :source:`Lib/runpy.py`
@@ -36,7 +37,8 @@ The :mod:`runpy` module provides two functions:
    import mechanism (refer to :pep:`302` for details) and then executed in a
    fresh module namespace.
 
-   If the supplied module name refers to a package rather than a normal
+   The *mod_name* argument should be an absolute module name.
+   If the module name refers to a package rather than a normal
    module, then that package is imported and the ``__main__`` submodule within
    that package is then executed and the resulting module globals dictionary
    returned.
index 26f59c5..4d4a616 100644 (file)
@@ -3,12 +3,13 @@
 
 .. module:: sched
    :synopsis: General purpose event scheduler.
-.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
-.. index:: single: event scheduling
+.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
 **Source code:** :source:`Lib/sched.py`
 
+.. index:: single: event scheduling
+
 --------------
 
 The :mod:`sched` module defines a class which implements a general purpose event
index a62dc84..6cec9f7 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: select
    :synopsis: Wait for I/O completion on multiple streams.
 
+--------------
 
 This module provides access to the :c:func:`select` and :c:func:`poll` functions
 available in most operating systems, :c:func:`devpoll` available on
@@ -472,7 +473,7 @@ Kqueue Objects
 Kevent Objects
 --------------
 
-http://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
+https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
 
 .. attribute:: kevent.ident
 
index 56cfc6b..44b27f3 100644 (file)
@@ -6,6 +6,9 @@
 
 .. versionadded:: 3.4
 
+**Source code:** :source:`Lib/selectors.py`
+
+--------------
 
 Introduction
 ------------
@@ -99,7 +102,7 @@ constants below:
    :class:`BaseSelector` and its concrete implementations support the
    :term:`context manager` protocol.
 
-   .. method:: register(fileobj, events, data=None)
+   .. abstractmethod:: register(fileobj, events, data=None)
 
       Register a file object for selection, monitoring it for I/O events.
 
@@ -112,7 +115,7 @@ constants below:
       :exc:`ValueError` in case of invalid event mask or file descriptor, or
       :exc:`KeyError` if the file object is already registered.
 
-   .. method:: unregister(fileobj)
+   .. abstractmethod:: unregister(fileobj)
 
       Unregister a file object from selection, removing it from monitoring. A
       file object shall be unregistered prior to being closed.
@@ -136,7 +139,7 @@ constants below:
       :exc:`ValueError` in case of invalid event mask or file descriptor, or
       :exc:`KeyError` if the file object is not registered.
 
-   .. method:: select(timeout=None)
+   .. abstractmethod:: select(timeout=None)
 
       Wait until some registered file objects become ready, or the timeout
       expires.
@@ -179,7 +182,7 @@ constants below:
       This returns the :class:`SelectorKey` instance associated to this file
       object, or raises :exc:`KeyError` if the file object is not registered.
 
-   .. method:: get_map()
+   .. abstractmethod:: get_map()
 
       Return a mapping of file objects to selector keys.
 
index 22e202d..1ec158e 100644 (file)
@@ -4,11 +4,10 @@
 .. module:: shelve
    :synopsis: Python object persistence.
 
+**Source code:** :source:`Lib/shelve.py`
 
 .. index:: module: pickle
 
-**Source code:** :source:`Lib/shelve.py`
-
 --------------
 
 A "shelf" is a persistent, dictionary-like object.  The difference with "dbm"
@@ -76,7 +75,7 @@ Two additional methods are supported:
 
 .. seealso::
 
-   `Persistent dictionary recipe <http://code.activestate.com/recipes/576642/>`_
+   `Persistent dictionary recipe <https://code.activestate.com/recipes/576642/>`_
    with widely supported storage formats and having the speed of native
    dictionaries.
 
@@ -137,7 +136,7 @@ Restrictions
    A subclass of :class:`Shelf` which exposes :meth:`first`, :meth:`!next`,
    :meth:`previous`, :meth:`last` and :meth:`set_location` which are available
    in the third-party :mod:`bsddb` module from `pybsddb
-   <http://www.jcea.es/programacion/pybsddb.htm>`_ but not in other database
+   <https://www.jcea.es/programacion/pybsddb.htm>`_ but not in other database
    modules.  The *dict* object passed to the constructor must support those
    methods.  This is generally accomplished by calling one of
    :func:`bsddb.hashopen`, :func:`bsddb.btopen` or :func:`bsddb.rnopen`.  The
@@ -165,32 +164,33 @@ object)::
 
    import shelve
 
-   d = shelve.open(filename) # open -- file may get suffix added by low-level
-                             # library
+   d = shelve.open(filename)  # open -- file may get suffix added by low-level
+                              # library
+
+   d[key] = data              # store data at key (overwrites old data if
+                              # using an existing key)
+   data = d[key]              # retrieve a COPY of data at key (raise KeyError
+                              # if no such key)
+   del d[key]                 # delete data stored at key (raises KeyError
+                              # if no such key)
 
-   d[key] = data   # store data at key (overwrites old data if
-                   # using an existing key)
-   data = d[key]   # retrieve a COPY of data at key (raise KeyError if no
-                   # such key)
-   del d[key]      # delete data stored at key (raises KeyError
-                   # if no such key)
-   flag = key in d        # true if the key exists
-   klist = list(d.keys()) # a list of all existing keys (slow!)
+   flag = key in d            # true if the key exists
+   klist = list(d.keys())     # a list of all existing keys (slow!)
 
    # as d was opened WITHOUT writeback=True, beware:
-   d['xx'] = [0, 1, 2]    # this works as expected, but...
-   d['xx'].append(3)      # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!
+   d['xx'] = [0, 1, 2]        # this works as expected, but...
+   d['xx'].append(3)          # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!
 
    # having opened d without writeback=True, you need to code carefully:
-   temp = d['xx']      # extracts the copy
-   temp.append(5)      # mutates the copy
-   d['xx'] = temp      # stores the copy right back, to persist it
+   temp = d['xx']             # extracts the copy
+   temp.append(5)             # mutates the copy
+   d['xx'] = temp             # stores the copy right back, to persist it
 
    # or, d=shelve.open(filename,writeback=True) would let you just code
    # d['xx'].append(5) and have it work as expected, BUT it would also
    # consume more memory and make the d.close() operation slower.
 
-   d.close()       # close it
+   d.close()                  # close it
 
 
 .. seealso::
index e40a10d..e81f982 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: shlex
    :synopsis: Simple lexical analysis for Unix shell-like languages.
+
 .. moduleauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
 .. moduleauthor:: Gustavo Niemeyer <niemeyer@conectiva.com>
 .. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
@@ -244,7 +245,8 @@ variables which either control lexical analysis or can be used for debugging:
    This attribute is ``None`` by default.  If you assign a string to it, that
    string will be recognized as a lexical-level inclusion request similar to the
    ``source`` keyword in various shells.  That is, the immediately following token
-   will opened as a filename and input taken from that stream until EOF, at which
+   will be opened as a filename and input will
+   be taken from that stream until EOF, at which
    point the :meth:`~io.IOBase.close` method of that stream will be called and
    the input source will again become the original input stream.  Source
    requests may be stacked any number of levels deep.
index 904627f..e9ba4e6 100644 (file)
@@ -3,15 +3,16 @@
 
 .. module:: shutil
    :synopsis: High-level file operations, including copying.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. partly based on the docstrings
 
+**Source code:** :source:`Lib/shutil.py`
+
 .. index::
    single: file; copying
    single: copying files
 
-**Source code:** :source:`Lib/shutil.py`
-
 --------------
 
 The :mod:`shutil` module offers a number of high-level operations on files and
@@ -342,7 +343,7 @@ Directory and files operations
    Return the path to an executable which would be run if the given *cmd* was
    called.  If no *cmd* would be called, return ``None``.
 
-   *mode* is a permission mask passed to :func:`os.access`, by default
+   *mode* is a permission mask passed to :func:`os.access`, by default
    determining if the file exists and executable.
 
    When no *path* is specified, the results of :func:`os.environ` are used,
index 8f814df..61252ce 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: signal
    :synopsis: Set handlers for asynchronous events.
 
+--------------
 
 This module provides mechanisms to use signal handlers in Python.
 
@@ -11,7 +12,7 @@ This module provides mechanisms to use signal handlers in Python.
 General rules
 -------------
 
-The :func:`signal.signal` function allows to define custom handlers to be
+The :func:`signal.signal` function allows defining custom handlers to be
 executed when a signal is received.  A small number of default handlers are
 installed: :const:`SIGPIPE` is ignored (so write errors on pipes and sockets
 can be reported as ordinary Python exceptions) and :const:`SIGINT` is
@@ -22,9 +23,6 @@ explicitly reset (Python emulates the BSD style interface regardless of the
 underlying implementation), with the exception of the handler for
 :const:`SIGCHLD`, which follows the underlying implementation.
 
-There is no way to "block" signals temporarily from critical sections (since
-this is not supported by all Unix flavors).
-
 
 Execution of Python signal handlers
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -354,6 +352,9 @@ The :mod:`signal` module defines the following functions:
    On Windows, :func:`signal` can only be called with :const:`SIGABRT`,
    :const:`SIGFPE`, :const:`SIGILL`, :const:`SIGINT`, :const:`SIGSEGV`, or
    :const:`SIGTERM`. A :exc:`ValueError` will be raised in any other case.
+   Note that not all systems define the same set of signal names; an
+   :exc:`AttributeError` will be raised if a signal name is not defined as
+   ``SIG*`` module level constant.
 
 
 .. function:: sigpending()
index 43daf79..0a73f5a 100644 (file)
@@ -52,8 +52,7 @@ searched for site-packages; otherwise they won't.
 A path configuration file is a file whose name has the form :file:`{name}.pth`
 and exists in one of the four directories mentioned above; its contents are
 additional items (one per line) to be added to ``sys.path``.  Non-existing items
-are never added to ``sys.path``, and no check is made that the item refers to a
-directory rather than a file.  No item is added to ``sys.path`` more than
+are never added to ``sys.path``.  No item is added to ``sys.path`` more than
 once.  Blank lines and lines beginning with ``#`` are skipped.  Lines starting
 with ``import`` (followed by space or tab) are executed.
 
index 8cbd20d..bdf3805 100644 (file)
@@ -3,15 +3,15 @@
 
 .. module:: smtplib
    :synopsis: SMTP protocol client (requires sockets).
+
 .. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
 
+**Source code:** :source:`Lib/smtplib.py`
 
 .. index::
    pair: SMTP; protocol
    single: Simple Mail Transfer Protocol
 
-**Source code:** :source:`Lib/smtplib.py`
-
 --------------
 
 The :mod:`smtplib` module defines an SMTP client session object that can be used
@@ -33,7 +33,7 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
    *timeout* parameter specifies a timeout in seconds for blocking operations
    like the connection attempt (if not specified, the global default timeout
    setting will be used).  If the timeout expires, :exc:`socket.timeout` is
-   raised.  The optional source_address parameter allows to bind
+   raised.  The optional source_address parameter allows binding
    to some specific source address in a machine with multiple network
    interfaces, and/or to some specific source TCP port. It takes a 2-tuple
    (host, port), for the socket to bind to as its source address before
@@ -76,7 +76,7 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
    *port* is zero, the standard SMTP-over-SSL port (465) is used.  The optional
    arguments *local_hostname*, *timeout* and *source_address* have the same
    meaning as they do in the :class:`SMTP` class.  *context*, also optional,
-   can contain a :class:`~ssl.SSLContext` and allows to configure various
+   can contain a :class:`~ssl.SSLContext` and allows configuring various
    aspects of the secure connection.  Please read :ref:`ssl-security` for
    best practices.
 
index f8b5d8b..6bfa9a9 100644 (file)
@@ -3,15 +3,16 @@
 
 .. module:: sndhdr
    :synopsis: Determine type of a sound file.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. Based on comments in the module source file.
 
+**Source code:** :source:`Lib/sndhdr.py`
+
 .. index::
    single: A-LAW
    single: u-LAW
 
-**Source code:** :source:`Lib/sndhdr.py`
-
 --------------
 
 The :mod:`sndhdr` provides utility functions which attempt to determine the type
index a081756..48311c5 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: socket
    :synopsis: Low-level networking interface.
 
+**Source code:** :source:`Lib/socket.py`
+
+--------------
 
 This module provides access to the BSD *socket* interface. It is available on
 all modern Unix systems, Windows, MacOS, and probably additional platforms.
@@ -57,7 +60,7 @@ created.  Socket addresses are represented as follows:
       Previously, :const:`AF_UNIX` socket paths were assumed to use UTF-8
       encoding.
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Writable :term:`bytes-like object` is now accepted.
 
 - A pair ``(host, port)`` is used for the :const:`AF_INET` address family,
@@ -445,9 +448,6 @@ The following functions all create :ref:`socket objects <socket-objects>`.
    .. versionchanged:: 3.2
       *source_address* was added.
 
-   .. versionchanged:: 3.2
-      support for the :keyword:`with` statement was added.
-
 
 .. function:: fromfd(fd, family, type, proto=0)
 
@@ -568,11 +568,6 @@ The :mod:`socket` module also offers various network-related services:
    Return a string containing the hostname of the machine where  the Python
    interpreter is currently executing.
 
-   If you want to know the current machine's IP address, you may want to use
-   ``gethostbyname(gethostname())``. This operation assumes that there is a
-   valid address-to-host mapping for the host, and the assumption does not
-   always hold.
-
    Note: :func:`gethostname` doesn't always return the fully qualified domain
    name; use :func:`getfqdn` for that.
 
@@ -680,7 +675,7 @@ The :mod:`socket` module also offers various network-related services:
    support IPv6, and :func:`inet_ntop` should be used instead for IPv4/v6 dual
    stack support.
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Writable :term:`bytes-like object` is now accepted.
 
 
@@ -722,7 +717,7 @@ The :mod:`socket` module also offers various network-related services:
    .. versionchanged:: 3.4
       Windows support added
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Writable :term:`bytes-like object` is now accepted.
 
 
@@ -836,6 +831,10 @@ Socket objects have the following methods.  Except for
 :meth:`~socket.makefile`, these correspond to Unix system calls applicable
 to sockets.
 
+.. versionchanged:: 3.2
+   Support for the :term:`context manager` protocol was added.  Exiting the
+   context manager is equivalent to calling :meth:`~socket.close`.
+
 
 .. method:: socket.accept()
 
@@ -931,14 +930,13 @@ to sockets.
 
 .. method:: socket.fileno()
 
-   Return the socket's file descriptor (a small integer).  This is useful with
-   :func:`select.select`.
+   Return the socket's file descriptor (a small integer), or -1 on failure. This
+   is useful with :func:`select.select`.
 
    Under Windows the small integer returned by this method cannot be used where a
    file descriptor can be used (such as :func:`os.fdopen`).  Unix does not have
    this limitation.
 
-
 .. method:: socket.get_inheritable()
 
    Get the :ref:`inheritable flag <fd_inheritance>` of the socket's file
@@ -988,7 +986,7 @@ to sockets.
 
    The :meth:`ioctl` method is a limited interface to the WSAIoctl system
    interface.  Please refer to the `Win32 documentation
-   <http://msdn.microsoft.com/en-us/library/ms741621%28VS.85%29.aspx>`_ for more
+   <https://msdn.microsoft.com/en-us/library/ms741621%28VS.85%29.aspx>`_ for more
    information.
 
    On other platforms, the generic :func:`fcntl.fcntl` and :func:`fcntl.ioctl`
@@ -1011,7 +1009,8 @@ to sockets.
 
    Return a :term:`file object` associated with the socket.  The exact returned
    type depends on the arguments given to :meth:`makefile`.  These arguments are
-   interpreted the same way as by the built-in :func:`open` function.
+   interpreted the same way as by the built-in :func:`open` function, except
+   the only supported *mode* values are ``'r'`` (default), ``'w'`` and ``'b'``.
 
    The socket must be in blocking mode; it can have a timeout, but the file
    object's internal buffer may end up in an inconsistent state if a timeout
@@ -1336,7 +1335,7 @@ to sockets.
    ensure that the bytestring contains the proper bits (see the optional built-in
    module :mod:`struct` for a way to encode C structures as bytestrings).
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Writable :term:`bytes-like object` is now accepted.
 
 
@@ -1461,16 +1460,16 @@ The first two examples support IPv4 only. ::
 
    HOST = ''                 # Symbolic name meaning all available interfaces
    PORT = 50007              # Arbitrary non-privileged port
-   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-   s.bind((HOST, PORT))
-   s.listen(1)
-   conn, addr = s.accept()
-   print('Connected by', addr)
-   while True:
-       data = conn.recv(1024)
-       if not data: break
-       conn.sendall(data)
-   conn.close()
+   with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+       s.bind((HOST, PORT))
+       s.listen(1)
+       conn, addr = s.accept()
+       with conn:
+           print('Connected by', addr)
+           while True:
+               data = conn.recv(1024)
+               if not data: break
+               conn.sendall(data)
 
 ::
 
@@ -1479,11 +1478,10 @@ The first two examples support IPv4 only. ::
 
    HOST = 'daring.cwi.nl'    # The remote host
    PORT = 50007              # The same port as used by the server
-   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-   s.connect((HOST, PORT))
-   s.sendall(b'Hello, world')
-   data = s.recv(1024)
-   s.close()
+   with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+       s.connect((HOST, PORT))
+       s.sendall(b'Hello, world')
+       data = s.recv(1024)
    print('Received', repr(data))
 
 The next two examples are identical to the above two, but support both IPv4 and
@@ -1520,12 +1518,12 @@ sends traffic to the first one connected successfully. ::
        print('could not open socket')
        sys.exit(1)
    conn, addr = s.accept()
-   print('Connected by', addr)
-   while True:
-       data = conn.recv(1024)
-       if not data: break
-       conn.send(data)
-   conn.close()
+   with conn:
+       print('Connected by', addr)
+       while True:
+           data = conn.recv(1024)
+           if not data: break
+           conn.send(data)
 
 ::
 
@@ -1553,9 +1551,9 @@ sends traffic to the first one connected successfully. ::
    if s is None:
        print('could not open socket')
        sys.exit(1)
-   s.sendall(b'Hello, world')
-   data = s.recv(1024)
-   s.close()
+   with s:
+       s.sendall(b'Hello, world')
+       data = s.recv(1024)
    print('Received', repr(data))
 
 
index 18be936..98d2c46 100644 (file)
 
 The :mod:`socketserver` module simplifies the task of writing network servers.
 
-There are four basic server classes: :class:`TCPServer` uses the Internet TCP
-protocol, which provides for continuous streams of data between the client and
-server.  :class:`UDPServer` uses datagrams, which are discrete packets of
-information that may arrive out of order or be lost while in transit.  The more
-infrequently used :class:`UnixStreamServer` and :class:`UnixDatagramServer`
-classes are similar, but use Unix domain sockets; they're not available on
-non-Unix platforms.  For more details on network programming, consult a book
-such as
-W. Richard Steven's UNIX Network Programming or Ralph Davis's Win32 Network
-Programming.
+There are four basic concrete server classes:
+
+
+.. class:: TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)
+
+   This uses the Internet TCP protocol, which provides for
+   continuous streams of data between the client and server.
+   If *bind_and_activate* is true, the constructor automatically attempts to
+   invoke :meth:`~BaseServer.server_bind` and
+   :meth:`~BaseServer.server_activate`.  The other parameters are passed to
+   the :class:`BaseServer` base class.
+
+
+.. class:: UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)
+
+   This uses datagrams, which are discrete packets of information that may
+   arrive out of order or be lost while in transit.  The parameters are
+   the same as for :class:`TCPServer`.
+
+
+.. class:: UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
+           UnixDatagramServer(server_address, RequestHandlerClass, bind_and_activate=True)
+
+   These more infrequently used classes are similar to the TCP and
+   UDP classes, but use Unix domain sockets; they're not available on
+   non-Unix platforms.  The parameters are the same as for
+   :class:`TCPServer`.
+
 
 These four classes process requests :dfn:`synchronously`; each request must be
 completed before the next request can be started.  This isn't suitable if each
@@ -31,10 +49,12 @@ support asynchronous behaviour.
 
 Creating a server requires several steps.  First, you must create a request
 handler class by subclassing the :class:`BaseRequestHandler` class and
-overriding its :meth:`handle` method; this method will process incoming
+overriding its :meth:`~BaseRequestHandler.handle` method;
+this method will process incoming
 requests.  Second, you must instantiate one of the server classes, passing it
 the server's address and the request handler class.  Then call the
-:meth:`handle_request` or :meth:`serve_forever` method of the server object to
+:meth:`~BaseServer.handle_request` or
+:meth:`~BaseServer.serve_forever` method of the server object to
 process one or many requests.  Finally, call :meth:`~BaseServer.server_close`
 to close the socket.
 
@@ -76,18 +96,33 @@ Note that :class:`UnixDatagramServer` derives from :class:`UDPServer`, not from
 stream server is the address family, which is simply repeated in both Unix
 server classes.
 
-Forking and threading versions of each type of server can be created using the
-:class:`ForkingMixIn` and :class:`ThreadingMixIn` mix-in classes.  For instance,
-a threading UDP server class is created as follows::
 
-   class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
+.. class:: ForkingMixIn
+           ThreadingMixIn
+
+   Forking and threading versions of each type of server can be created
+   using these mix-in classes.  For instance, :class:`ThreadingUDPServer`
+   is created as follows::
+
+      class ThreadingUDPServer(ThreadingMixIn, UDPServer):
+          pass
+
+   The mix-in class comes first, since it overrides a method defined in
+   :class:`UDPServer`.  Setting the various attributes also changes the
+   behavior of the underlying server mechanism.
+
+
+.. class:: ForkingTCPServer
+           ForkingUDPServer
+           ThreadingTCPServer
+           ThreadingUDPServer
+
+   These classes are pre-defined using the mix-in classes.
 
-The mix-in class must come first, since it overrides a method defined in
-:class:`UDPServer`.  Setting the various attributes also change the
-behavior of the underlying server mechanism.
 
 To implement a service, you must derive a class from :class:`BaseRequestHandler`
-and redefine its :meth:`handle` method.  You can then run various versions of
+and redefine its :meth:`~BaseRequestHandler.handle` method.
+You can then run various versions of
 the service by combining one of the server classes with your request handler
 class.  The request handler class must be different for datagram or stream
 services.  This can be hidden by using the handler subclasses
@@ -109,7 +144,7 @@ has requested.  Here a threading or forking server is appropriate.
 In some cases, it may be appropriate to process part of a request synchronously,
 but to finish processing in a forked child depending on the request data.  This
 can be implemented by using a synchronous server and doing an explicit fork in
-the request handler class :meth:`handle` method.
+the request handler class :meth:`~BaseRequestHandler.handle` method.
 
 Another approach to handling multiple simultaneous requests in an environment
 that supports neither threads nor :func:`~os.fork` (or where these are too
@@ -127,227 +162,240 @@ connected for a long time (if threads or subprocesses cannot be used).  See
 Server Objects
 --------------
 
-.. class:: BaseServer
+.. class:: BaseServer(server_address, RequestHandlerClass)
 
    This is the superclass of all Server objects in the module.  It defines the
    interface, given below, but does not implement most of the methods, which is
-   done in subclasses.
+   done in subclasses.  The two parameters are stored in the respective
+   :attr:`server_address` and :attr:`RequestHandlerClass` attributes.
+
+
+   .. method:: fileno()
 
+      Return an integer file descriptor for the socket on which the server is
+      listening.  This function is most commonly passed to :mod:`selectors`, to
+      allow monitoring multiple servers in the same process.
 
-.. method:: BaseServer.fileno()
 
-   Return an integer file descriptor for the socket on which the server is
-   listening.  This function is most commonly passed to :mod:`selectors`, to
-   allow monitoring multiple servers in the same process.
+   .. method:: handle_request()
 
+      Process a single request.  This function calls the following methods in
+      order: :meth:`get_request`, :meth:`verify_request`, and
+      :meth:`process_request`.  If the user-provided
+      :meth:`~BaseRequestHandler.handle` method of the
+      handler class raises an exception, the server's :meth:`handle_error` method
+      will be called.  If no request is received within :attr:`timeout`
+      seconds, :meth:`handle_timeout` will be called and :meth:`handle_request`
+      will return.
 
-.. method:: BaseServer.handle_request()
 
-   Process a single request.  This function calls the following methods in
-   order: :meth:`get_request`, :meth:`verify_request`, and
-   :meth:`process_request`.  If the user-provided :meth:`handle` method of the
-   handler class raises an exception, the server's :meth:`handle_error` method
-   will be called.  If no request is received within :attr:`self.timeout`
-   seconds, :meth:`handle_timeout` will be called and :meth:`handle_request`
-   will return.
+   .. method:: serve_forever(poll_interval=0.5)
 
+      Handle requests until an explicit :meth:`shutdown` request.  Poll for
+      shutdown every *poll_interval* seconds.
+      Ignores the :attr:`timeout` attribute.  It
+      also calls :meth:`service_actions`, which may be used by a subclass or mixin
+      to provide actions specific to a given service.  For example, the
+      :class:`ForkingMixIn` class uses :meth:`service_actions` to clean up zombie
+      child processes.
 
-.. method:: BaseServer.serve_forever(poll_interval=0.5)
+      .. versionchanged:: 3.3
+         Added ``service_actions`` call to the ``serve_forever`` method.
 
-   Handle requests until an explicit :meth:`shutdown` request.  Poll for
-   shutdown every *poll_interval* seconds. Ignores :attr:`self.timeout`.  It
-   also calls :meth:`service_actions`, which may be used by a subclass or mixin
-   to provide actions specific to a given service.  For example, the
-   :class:`ForkingMixIn` class uses :meth:`service_actions` to clean up zombie
-   child processes.
 
-   .. versionchanged:: 3.3
-       Added ``service_actions`` call to the ``serve_forever`` method.
+   .. method:: service_actions()
 
+      This is called in the :meth:`serve_forever` loop. This method can be
+      overridden by subclasses or mixin classes to perform actions specific to
+      a given service, such as cleanup actions.
 
-.. method:: BaseServer.service_actions()
+      .. versionadded:: 3.3
 
-   This is called in the :meth:`serve_forever` loop. This method can be
-   overridden by subclasses or mixin classes to perform actions specific to
-   a given service, such as cleanup actions.
+   .. method:: shutdown()
 
-   .. versionadded:: 3.3
+      Tell the :meth:`serve_forever` loop to stop and wait until it does.
 
-.. method:: BaseServer.shutdown()
 
-   Tell the :meth:`serve_forever` loop to stop and wait until it does.
+   .. method:: server_close()
 
+      Clean up the server. May be overridden.
 
-.. method:: BaseServer.server_close()
 
-   Clean up the server. May be overridden.
+   .. attribute:: address_family
 
-   .. versionadded:: 2.6
+      The family of protocols to which the server's socket belongs.
+      Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`.
 
 
-.. attribute:: BaseServer.address_family
+   .. attribute:: RequestHandlerClass
 
-   The family of protocols to which the server's socket belongs.
-   Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`.
+      The user-provided request handler class; an instance of this class is created
+      for each request.
 
 
-.. attribute:: BaseServer.RequestHandlerClass
+   .. attribute:: server_address
 
-   The user-provided request handler class; an instance of this class is created
-   for each request.
+      The address on which the server is listening.  The format of addresses varies
+      depending on the protocol family;
+      see the documentation for the :mod:`socket` module
+      for details.  For Internet protocols, this is a tuple containing a string giving
+      the address, and an integer port number: ``('127.0.0.1', 80)``, for example.
 
 
-.. attribute:: BaseServer.server_address
+   .. attribute:: socket
 
-   The address on which the server is listening.  The format of addresses varies
-   depending on the protocol family; see the documentation for the socket module
-   for details.  For Internet protocols, this is a tuple containing a string giving
-   the address, and an integer port number: ``('127.0.0.1', 80)``, for example.
+      The socket object on which the server will listen for incoming requests.
 
 
-.. attribute:: BaseServer.socket
+   The server classes support the following class variables:
 
-   The socket object on which the server will listen for incoming requests.
+   .. XXX should class variables be covered before instance variables, or vice versa?
 
+   .. attribute:: allow_reuse_address
 
-The server classes support the following class variables:
+      Whether the server will allow the reuse of an address.  This defaults to
+      :const:`False`, and can be set in subclasses to change the policy.
 
-.. XXX should class variables be covered before instance variables, or vice versa?
 
-.. attribute:: BaseServer.allow_reuse_address
+   .. attribute:: request_queue_size
 
-   Whether the server will allow the reuse of an address.  This defaults to
-   :const:`False`, and can be set in subclasses to change the policy.
+      The size of the request queue.  If it takes a long time to process a single
+      request, any requests that arrive while the server is busy are placed into a
+      queue, up to :attr:`request_queue_size` requests.  Once the queue is full,
+      further requests from clients will get a "Connection denied" error.  The default
+      value is usually 5, but this can be overridden by subclasses.
 
 
-.. attribute:: BaseServer.request_queue_size
+   .. attribute:: socket_type
 
-   The size of the request queue.  If it takes a long time to process a single
-   request, any requests that arrive while the server is busy are placed into a
-   queue, up to :attr:`request_queue_size` requests.  Once the queue is full,
-   further requests from clients will get a "Connection denied" error.  The default
-   value is usually 5, but this can be overridden by subclasses.
+      The type of socket used by the server; :const:`socket.SOCK_STREAM` and
+      :const:`socket.SOCK_DGRAM` are two common values.
 
 
-.. attribute:: BaseServer.socket_type
+   .. attribute:: timeout
 
-   The type of socket used by the server; :const:`socket.SOCK_STREAM` and
-   :const:`socket.SOCK_DGRAM` are two common values.
+      Timeout duration, measured in seconds, or :const:`None` if no timeout is
+      desired.  If :meth:`handle_request` receives no incoming requests within the
+      timeout period, the :meth:`handle_timeout` method is called.
 
 
-.. attribute:: BaseServer.timeout
+   There are various server methods that can be overridden by subclasses of base
+   server classes like :class:`TCPServer`; these methods aren't useful to external
+   users of the server object.
 
-   Timeout duration, measured in seconds, or :const:`None` if no timeout is
-   desired.  If :meth:`handle_request` receives no incoming requests within the
-   timeout period, the :meth:`handle_timeout` method is called.
+   .. XXX should the default implementations of these be documented, or should
+      it be assumed that the user will look at socketserver.py?
 
+   .. method:: finish_request()
 
-There are various server methods that can be overridden by subclasses of base
-server classes like :class:`TCPServer`; these methods aren't useful to external
-users of the server object.
+      Actually processes the request by instantiating :attr:`RequestHandlerClass` and
+      calling its :meth:`~BaseRequestHandler.handle` method.
 
-.. XXX should the default implementations of these be documented, or should
-   it be assumed that the user will look at socketserver.py?
 
-.. method:: BaseServer.finish_request()
+   .. method:: get_request()
 
-   Actually processes the request by instantiating :attr:`RequestHandlerClass` and
-   calling its :meth:`handle` method.
+      Must accept a request from the socket, and return a 2-tuple containing the *new*
+      socket object to be used to communicate with the client, and the client's
+      address.
 
 
-.. method:: BaseServer.get_request()
+   .. method:: handle_error(request, client_address)
 
-   Must accept a request from the socket, and return a 2-tuple containing the *new*
-   socket object to be used to communicate with the client, and the client's
-   address.
+      This function is called if the :meth:`~BaseRequestHandler.handle`
+      method of a :attr:`RequestHandlerClass` instance raises
+      an exception.  The default action is to print the traceback to
+      standard output and continue handling further requests.
 
 
-.. method:: BaseServer.handle_error(request, client_address)
+   .. method:: handle_timeout()
 
-   This function is called if the :attr:`RequestHandlerClass`'s :meth:`handle`
-   method raises an exception.  The default action is to print the traceback to
-   standard output and continue handling further requests.
+      This function is called when the :attr:`timeout` attribute has been set to a
+      value other than :const:`None` and the timeout period has passed with no
+      requests being received.  The default action for forking servers is
+      to collect the status of any child processes that have exited, while
+      in threading servers this method does nothing.
 
 
-.. method:: BaseServer.handle_timeout()
+   .. method:: process_request(request, client_address)
 
-   This function is called when the :attr:`timeout` attribute has been set to a
-   value other than :const:`None` and the timeout period has passed with no
-   requests being received.  The default action for forking servers is
-   to collect the status of any child processes that have exited, while
-   in threading servers this method does nothing.
+      Calls :meth:`finish_request` to create an instance of the
+      :attr:`RequestHandlerClass`.  If desired, this function can create a new process
+      or thread to handle the request; the :class:`ForkingMixIn` and
+      :class:`ThreadingMixIn` classes do this.
 
 
-.. method:: BaseServer.process_request(request, client_address)
+   .. Is there any point in documenting the following two functions?
+      What would the purpose of overriding them be: initializing server
+      instance variables, adding new network families?
 
-   Calls :meth:`finish_request` to create an instance of the
-   :attr:`RequestHandlerClass`.  If desired, this function can create a new process
-   or thread to handle the request; the :class:`ForkingMixIn` and
-   :class:`ThreadingMixIn` classes do this.
+   .. method:: server_activate()
 
+      Called by the server's constructor to activate the server.  The default behavior
+      for a TCP server just invokes :meth:`~socket.socket.listen`
+      on the server's socket.  May be overridden.
 
-.. Is there any point in documenting the following two functions?
-   What would the purpose of overriding them be: initializing server
-   instance variables, adding new network families?
 
-.. method:: BaseServer.server_activate()
+   .. method:: server_bind()
 
-   Called by the server's constructor to activate the server.  The default behavior
-   just :meth:`listen`\ s to the server's socket.  May be overridden.
+      Called by the server's constructor to bind the socket to the desired address.
+      May be overridden.
 
 
-.. method:: BaseServer.server_bind()
+   .. method:: verify_request(request, client_address)
 
-   Called by the server's constructor to bind the socket to the desired address.
-   May be overridden.
+      Must return a Boolean value; if the value is :const:`True`, the request will
+      be processed, and if it's :const:`False`, the request will be denied.  This
+      function can be overridden to implement access controls for a server. The
+      default implementation always returns :const:`True`.
 
 
-.. method:: BaseServer.verify_request(request, client_address)
+Request Handler Objects
+-----------------------
 
-   Must return a Boolean value; if the value is :const:`True`, the request will
-   be processed, and if it's :const:`False`, the request will be denied.  This
-   function can be overridden to implement access controls for a server. The
-   default implementation always returns :const:`True`.
+.. class:: BaseRequestHandler
 
+   This is the superclass of all request handler objects.  It defines
+   the interface, given below.  A concrete request handler subclass must
+   define a new :meth:`handle` method, and can override any of
+   the other methods.  A new instance of the subclass is created for each
+   request.
 
-RequestHandler Objects
-----------------------
 
-The request handler class must define a new :meth:`handle` method, and can
-override any of the following methods.  A new instance is created for each
-request.
+   .. method:: setup()
 
+      Called before the :meth:`handle` method to perform any initialization actions
+      required.  The default implementation does nothing.
 
-.. method:: RequestHandler.finish()
 
-   Called after the :meth:`handle` method to perform any clean-up actions
-   required.  The default implementation does nothing.  If :meth:`setup`
-   raises an exception, this function will not be called.
+   .. method:: handle()
 
+      This function must do all the work required to service a request.  The
+      default implementation does nothing.  Several instance attributes are
+      available to it; the request is available as :attr:`self.request`; the client
+      address as :attr:`self.client_address`; and the server instance as
+      :attr:`self.server`, in case it needs access to per-server information.
 
-.. method:: RequestHandler.handle()
+      The type of :attr:`self.request` is different for datagram or stream
+      services.  For stream services, :attr:`self.request` is a socket object; for
+      datagram services, :attr:`self.request` is a pair of string and socket.
 
-   This function must do all the work required to service a request.  The
-   default implementation does nothing.  Several instance attributes are
-   available to it; the request is available as :attr:`self.request`; the client
-   address as :attr:`self.client_address`; and the server instance as
-   :attr:`self.server`, in case it needs access to per-server information.
 
-   The type of :attr:`self.request` is different for datagram or stream
-   services.  For stream services, :attr:`self.request` is a socket object; for
-   datagram services, :attr:`self.request` is a pair of string and socket.
-   However, this can be hidden by using the request handler subclasses
-   :class:`StreamRequestHandler` or :class:`DatagramRequestHandler`, which
-   override the :meth:`setup` and :meth:`finish` methods, and provide
-   :attr:`self.rfile` and :attr:`self.wfile` attributes.  :attr:`self.rfile` and
-   :attr:`self.wfile` can be read or written, respectively, to get the request
-   data or return data to the client.
+   .. method:: finish()
 
+      Called after the :meth:`handle` method to perform any clean-up actions
+      required.  The default implementation does nothing.  If :meth:`setup`
+      raises an exception, this function will not be called.
 
-.. method:: RequestHandler.setup()
 
-   Called before the :meth:`handle` method to perform any initialization actions
-   required.  The default implementation does nothing.
+.. class:: StreamRequestHandler
+           DatagramRequestHandler
+
+   These :class:`BaseRequestHandler` subclasses override the
+   :meth:`~BaseRequestHandler.setup` and :meth:`~BaseRequestHandler.finish`
+   methods, and provide :attr:`self.rfile` and :attr:`self.wfile` attributes.
+   The :attr:`self.rfile` and :attr:`self.wfile` attributes can be
+   read or written, respectively, to get the request data or return data
+   to the client.
 
 
 Examples
@@ -362,7 +410,7 @@ This is the server side::
 
    class MyTCPHandler(socketserver.BaseRequestHandler):
        """
-       The RequestHandler class for our server.
+       The request handler class for our server.
 
        It is instantiated once per connection to the server, and must
        override the handle() method to implement communication to the
@@ -417,17 +465,13 @@ This is the client side::
    data = " ".join(sys.argv[1:])
 
    # Create a socket (SOCK_STREAM means a TCP socket)
-   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
-   try:
+   with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        # Connect to server and send data
        sock.connect((HOST, PORT))
        sock.sendall(bytes(data + "\n", "utf-8"))
 
        # Receive data from the server and shut down
        received = str(sock.recv(1024), "utf-8")
-   finally:
-       sock.close()
 
    print("Sent:     {}".format(data))
    print("Received: {}".format(received))
@@ -526,14 +570,11 @@ An example for the :class:`ThreadingMixIn` class::
        pass
 
    def client(ip, port, message):
-       sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-       sock.connect((ip, port))
-       try:
+       with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
+           sock.connect((ip, port))
            sock.sendall(bytes(message, 'ascii'))
            response = str(sock.recv(1024), 'ascii')
            print("Received: {}".format(response))
-       finally:
-           sock.close()
 
    if __name__ == "__main__":
        # Port 0 means to select an arbitrary unused port
index 58be78f..fd3c9ad 100644 (file)
@@ -5,6 +5,7 @@
    :platform: Unix
    :synopsis: The shadow password database (getspnam() and friends).
 
+--------------
 
 This module provides access to the Unix shadow password database. It is
 available on various Unix versions.
index b14ea72..3bba935 100644 (file)
@@ -3,8 +3,12 @@
 
 .. module:: sqlite3
    :synopsis: A DB-API 2.0 implementation using SQLite 3.x.
+
 .. sectionauthor:: Gerhard Häring <gh@ghaering.de>
 
+**Source code:** :source:`Lib/sqlite3/`
+
+--------------
 
 SQLite is a C library that provides a lightweight disk-based database that
 doesn't require a separate server process and allows accessing the database
@@ -53,7 +57,7 @@ The data you've saved is persistent and is available in subsequent sessions::
 Usually your SQL operations will need to use values from Python variables.  You
 shouldn't assemble your query using Python's string operations because doing so
 is insecure; it makes your program vulnerable to an SQL injection attack
-(see http://xkcd.com/327/ for humorous example of what can go wrong).
+(see https://xkcd.com/327/ for humorous example of what can go wrong).
 
 Instead, use the DB-API's parameter substitution.  Put ``?`` as a placeholder
 wherever you want to use a value, and then provide a tuple of values as the
@@ -99,7 +103,7 @@ This example uses the iterator form::
       The pysqlite web page -- sqlite3 is developed externally under the name
       "pysqlite".
 
-   http://www.sqlite.org
+   https://www.sqlite.org
       The SQLite web page; the documentation describes the syntax and the
       available data types for the supported SQL dialect.
 
@@ -190,6 +194,11 @@ Module functions and constants
    any combination of :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES` to turn
    type detection on.
 
+   By default, *check_same_thread* is :const:`True` and only the creating thread may
+   use the connection. If set :const:`False`, the returned connection may be shared
+   across multiple threads. When using multiple threads with the same connection
+   writing operations should be serialized by the user to avoid data corruption.
+
    By default, the :mod:`sqlite3` module uses its :class:`Connection` class for the
    connect call.  You can, however, subclass the :class:`Connection` class and make
    :func:`connect` use your class instead by providing your class for the *factory*
@@ -209,7 +218,7 @@ Module functions and constants
        db = sqlite3.connect('file:path/to/database?mode=ro', uri=True)
 
    More information about this feature, including a list of recognized options, can
-   be found in the `SQLite URI documentation <http://www.sqlite.org/uri.html>`_.
+   be found in the `SQLite URI documentation <https://www.sqlite.org/uri.html>`_.
 
    .. versionchanged:: 3.4
       Added the *uri* parameter.
@@ -324,8 +333,9 @@ Connection Objects
 
       Creates a user-defined function that you can later use from within SQL
       statements under the function name *name*. *num_params* is the number of
-      parameters the function accepts, and *func* is a Python callable that is called
-      as the SQL function.
+      parameters the function accepts (if *num_params* is -1, the function may
+      take any number of arguments), and *func* is a Python callable that is
+      called as the SQL function.
 
       The function can return any of the types supported by SQLite: bytes, str, int,
       float and None.
@@ -340,7 +350,8 @@ Connection Objects
       Creates a user-defined aggregate function.
 
       The aggregate class must implement a ``step`` method, which accepts the number
-      of parameters *num_params*, and a ``finalize`` method which will return the
+      of parameters *num_params* (if *num_params* is -1, the function may take
+      any number of arguments), and a ``finalize`` method which will return the
       final result of the aggregate.
 
       The ``finalize`` method can return any of the types supported by SQLite:
@@ -495,7 +506,7 @@ Connection Objects
       deleted since the database connection was opened.
 
 
-   .. attribute:: iterdump
+   .. method:: iterdump
 
       Returns an iterator to dump the database in an SQL text format.  Useful when
       saving an in-memory database for later restoration.  This function provides
@@ -505,7 +516,7 @@ Connection Objects
       Example::
 
          # Convert file existing_db.db to SQL dump file dump.sql
-         import sqlite3, os
+         import sqlite3
 
          con = sqlite3.connect('existing_db.db')
          with open('dump.sql', 'w') as f:
@@ -593,6 +604,12 @@ Cursor Objects
       the cursor's arraysize attribute can affect the performance of this operation.
       An empty list is returned when no rows are available.
 
+   .. method:: close()
+
+      Close the cursor now (rather than whenever ``__del__`` is called).
+
+      The cursor will be unusable from this point forward; a ``ProgrammingError``
+      exception will be raised if any operation is attempted with the cursor.
 
    .. attribute:: rowcount
 
@@ -627,6 +644,18 @@ Cursor Objects
 
       It is set for ``SELECT`` statements without any matching rows as well.
 
+   .. attribute:: connection
+
+      This read-only attribute provides the SQLite database :class:`Connection`
+      used by the :class:`Cursor` object.  A :class:`Cursor` object created by
+      calling :meth:`con.cursor() <Connection.cursor>` will have a
+      :attr:`connection` attribute that refers to *con*::
+
+         >>> con = sqlite3.connect(":memory:")
+         >>> cur = con.cursor()
+         >>> cur.connection == con
+         True
+
 .. _sqlite3-row-objects:
 
 Row Objects
index fbb9b28..5792d0d 100644 (file)
@@ -7,13 +7,12 @@
 .. moduleauthor:: Bill Janssen <bill.janssen@gmail.com>
 .. sectionauthor::  Bill Janssen <bill.janssen@gmail.com>
 
+**Source code:** :source:`Lib/ssl.py`
 
 .. index:: single: OpenSSL; (use in module ssl)
 
 .. index:: TLS, SSL, Transport Layer Security, Secure Sockets Layer
 
-**Source code:** :source:`Lib/ssl.py`
-
 --------------
 
 This module provides access to Transport Layer Security (often known as "Secure
@@ -206,7 +205,7 @@ instead.
 
    The *ciphers* parameter sets the available ciphers for this SSL object.
    It should be a string in the `OpenSSL cipher list format
-   <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`_.
+   <https://www.openssl.org/docs/apps/ciphers.html#CIPHER-LIST-FORMAT>`_.
 
    The parameter ``do_handshake_on_connect`` specifies whether to do the SSL
    handshake automatically after doing a :meth:`socket.connect`, or whether the
@@ -296,7 +295,7 @@ Random generation
 
    Read the Wikipedia article, `Cryptographically secure pseudorandom number
    generator (CSPRNG)
-   <http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator>`_,
+   <https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator>`_,
    to get the requirements of a cryptographically generator.
 
    .. versionadded:: 3.3
@@ -344,7 +343,7 @@ Random generation
    string (so you can always use :const:`0.0`).  See :rfc:`1750` for more
    information on sources of entropy.
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Writable :term:`bytes-like object` is now accepted.
 
 Certificate handling
@@ -721,7 +720,7 @@ Constants
 
    Whether the OpenSSL library has built-in support for *Next Protocol
    Negotiation* as described in the `NPN draft specification
-   <http://tools.ietf.org/html/draft-agl-tls-nextprotoneg>`_. When true,
+   <https://tools.ietf.org/html/draft-agl-tls-nextprotoneg>`_. When true,
    you can use the :meth:`SSLContext.set_npn_protocols` method to advertise
    which protocols you want to support.
 
@@ -769,7 +768,7 @@ Constants
           ALERT_DESCRIPTION_*
 
    Alert Descriptions from :rfc:`5246` and others. The `IANA TLS Alert Registry
-   <http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6>`_
+   <https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6>`_
    contains this list and references to the RFCs where their meaning is defined.
 
    Used as the return value of the callback function in
@@ -842,7 +841,7 @@ SSL Sockets
 
 SSL sockets also have the following additional methods and attributes:
 
-.. method:: SSLSocket.read(len=0, buffer=None)
+.. method:: SSLSocket.read(len=1024, buffer=None)
 
    Read up to *len* bytes of data from the SSL socket and return the result as
    a ``bytes`` instance. If *buffer* is specified, then read into the buffer
@@ -1174,7 +1173,7 @@ to speed up repeated connections from the same clients.
    The *capath* string, if present, is
    the path to a directory containing several CA certificates in PEM format,
    following an `OpenSSL specific layout
-   <http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html>`_.
+   <https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html>`_.
 
    The *cadata* object, if present, is either an ASCII string of one or more
    PEM-encoded certificates or a :term:`bytes-like object` of DER-encoded
@@ -1212,7 +1211,7 @@ to speed up repeated connections from the same clients.
 
    Set the available ciphers for sockets created with this context.
    It should be a string in the `OpenSSL cipher list format
-   <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`_.
+   <https://www.openssl.org/docs/apps/ciphers.html#CIPHER-LIST-FORMAT>`_.
    If no cipher can be selected (because compile-time options or other
    configuration forbids use of all the specified ciphers), an
    :class:`SSLError` will be raised.
@@ -1241,7 +1240,7 @@ to speed up repeated connections from the same clients.
    handshake. It should be a list of strings, like ``['http/1.1', 'spdy/2']``,
    ordered by preference. The selection of a protocol will happen during the
    handshake, and will play out according to the `NPN draft specification
-   <http://tools.ietf.org/html/draft-agl-tls-nextprotoneg>`_. After a
+   <https://tools.ietf.org/html/draft-agl-tls-nextprotoneg>`_. After a
    successful handshake, the :meth:`SSLSocket.selected_npn_protocol` method will
    return the agreed-upon protocol.
 
@@ -1369,7 +1368,7 @@ to speed up repeated connections from the same clients.
 
    Get statistics about the SSL sessions created or managed by this context.
    A dictionary is returned which maps the names of each `piece of information
-   <http://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html>`_ to their
+   <https://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html>`_ to their
    numeric values.  For example, here is the total number of hits and misses
    in the session cache since the context was created::
 
@@ -1585,7 +1584,7 @@ should use the following idiom::
    except ImportError:
        pass
    else:
-       ... # do something that requires SSL support
+       ...  # do something that requires SSL support
 
 Client-side operation
 ^^^^^^^^^^^^^^^^^^^^^
@@ -2019,7 +2018,7 @@ enabled when negotiating a SSL session is possible through the
 :meth:`SSLContext.set_ciphers` method.  Starting from Python 3.2.3, the
 ssl module disables certain weak ciphers by default, but you may want
 to further restrict the cipher choice. Be sure to read OpenSSL's documentation
-about the `cipher list format <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`_.
+about the `cipher list format <https://www.openssl.org/docs/apps/ciphers.html#CIPHER-LIST-FORMAT>`_.
 If you want to check which ciphers are enabled by a given cipher list, use the
 ``openssl ciphers`` command on your system.
 
@@ -2040,26 +2039,26 @@ successful call of :func:`~ssl.RAND_add`, :func:`~ssl.RAND_bytes` or
    Class :class:`socket.socket`
        Documentation of underlying :mod:`socket` class
 
-   `SSL/TLS Strong Encryption: An Introduction <http://httpd.apache.org/docs/trunk/en/ssl/ssl_intro.html>`_
+   `SSL/TLS Strong Encryption: An Introduction <https://httpd.apache.org/docs/trunk/en/ssl/ssl_intro.html>`_
        Intro from the Apache webserver documentation
 
-   `RFC 1422: Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management <http://www.ietf.org/rfc/rfc1422>`_
+   `RFC 1422: Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management <https://www.ietf.org/rfc/rfc1422>`_
        Steve Kent
 
-   `RFC 1750: Randomness Recommendations for Security <http://www.ietf.org/rfc/rfc1750>`_
+   `RFC 1750: Randomness Recommendations for Security <https://www.ietf.org/rfc/rfc1750>`_
        D. Eastlake et. al.
 
-   `RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile <http://www.ietf.org/rfc/rfc3280>`_
+   `RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile <https://www.ietf.org/rfc/rfc3280>`_
        Housley et. al.
 
-   `RFC 4366: Transport Layer Security (TLS) Extensions <http://www.ietf.org/rfc/rfc4366>`_
+   `RFC 4366: Transport Layer Security (TLS) Extensions <https://www.ietf.org/rfc/rfc4366>`_
        Blake-Wilson et. al.
 
-   `RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 <http://tools.ietf.org/html/rfc5246>`_
+   `RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 <https://tools.ietf.org/html/rfc5246>`_
        T. Dierks et. al.
 
-   `RFC 6066: Transport Layer Security (TLS) Extensions <http://tools.ietf.org/html/rfc6066>`_
+   `RFC 6066: Transport Layer Security (TLS) Extensions <https://tools.ietf.org/html/rfc6066>`_
        D. Eastlake
 
-   `IANA TLS: Transport Layer Security (TLS) Parameters <http://www.iana.org/assignments/tls-parameters/tls-parameters.xml>`_
+   `IANA TLS: Transport Layer Security (TLS) Parameters <https://www.iana.org/assignments/tls-parameters/tls-parameters.xml>`_
        IANA
index 845b2ef..b256312 100644 (file)
@@ -4,10 +4,10 @@
 .. module:: stat
    :synopsis: Utilities for interpreting the results of os.stat(),
               os.lstat() and os.fstat().
+
 .. sectionauthor:: Skip Montanaro <skip@automatrix.com>
 
-**Source code:** :source:`Modules/_stat.c`
-                 :source:`Lib/stat.py`
+**Source code:** :source:`Lib/stat.py`
 
 --------------
 
@@ -403,7 +403,7 @@ See the \*BSD or Mac OS systems man page :manpage:`chflags(2)` for more informat
 On Windows, the following file attribute constants are available for use when
 testing bits in the ``st_file_attributes`` member returned by :func:`os.stat`.
 See the `Windows API documentation
-<http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx>`_
+<https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx>`_
 for more detail on the meaning of these constants.
 
 .. data:: FILE_ATTRIBUTE_ARCHIVE
index 0c9d88c..ea3d7da 100644 (file)
@@ -3,18 +3,19 @@
 
 .. module:: statistics
    :synopsis: mathematical statistics functions
+
 .. moduleauthor:: Steven D'Aprano <steve+python@pearwood.info>
 .. sectionauthor:: Steven D'Aprano <steve+python@pearwood.info>
 
 .. versionadded:: 3.4
 
+**Source code:** :source:`Lib/statistics.py`
+
 .. testsetup:: *
 
    from statistics import *
    __name__ = '<doctest>'
 
-**Source code:** :source:`Lib/statistics.py`
-
 --------------
 
 This module provides functions for calculating mathematical statistics of
@@ -223,7 +224,7 @@ However, for reading convenience, most of the examples show sorted sequences.
       * "Statistics for the Behavioral Sciences", Frederick J Gravetter and
         Larry B Wallnau (8th Edition).
 
-      * Calculating the `median <http://www.ualberta.ca/~opscan/median.html>`_.
+      * Calculating the `median <https://www.ualberta.ca/~opscan/median.html>`_.
 
       * The `SSMEDIAN
         <https://help.gnome.org/users/gnumeric/stable/gnumeric.html#gnumeric-function-SSMEDIAN>`_
index 71fc3b5..e8a488e 100644 (file)
@@ -361,19 +361,22 @@ Notes:
 All :class:`numbers.Real` types (:class:`int` and :class:`float`) also include
 the following operations:
 
-+--------------------+------------------------------------+--------+
-| Operation          | Result                             | Notes  |
-+====================+====================================+========+
-| ``math.trunc(x)``  | *x* truncated to Integral          |        |
-+--------------------+------------------------------------+--------+
-| ``round(x[, n])``  | *x* rounded to n digits,           |        |
-|                    | rounding half to even. If n is     |        |
-|                    | omitted, it defaults to 0.         |        |
-+--------------------+------------------------------------+--------+
-| ``math.floor(x)``  | the greatest integral float <= *x* |        |
-+--------------------+------------------------------------+--------+
-| ``math.ceil(x)``   | the least integral float >= *x*    |        |
-+--------------------+------------------------------------+--------+
++--------------------+---------------------------------------------+
+| Operation          | Result                                      |
++====================+=============================================+
+| :func:`math.trunc(\| *x* truncated to :class:`~numbers.Integral` |
+| x) <math.trunc>`   |                                             |
++--------------------+---------------------------------------------+
+| :func:`round(x[,   | *x* rounded to *n* digits,                  |
+| n]) <round>`       | rounding half to even. If *n* is            |
+|                    | omitted, it defaults to 0.                  |
++--------------------+---------------------------------------------+
+| :func:`math.floor(\| the greatest :class:`~numbers.Integral`     |
+| x) <math.floor>`   | <= *x*                                      |
++--------------------+---------------------------------------------+
+| :func:`math.ceil(x)| the least :class:`~numbers.Integral` >= *x* |
+| <math.ceil>`       |                                             |
++--------------------+---------------------------------------------+
 
 For additional numeric operations see the :mod:`math` and :mod:`cmath`
 modules.
@@ -397,8 +400,8 @@ Bitwise Operations on Integer Types
    operator: >>
 
 Bitwise operations only make sense for integers.  Negative numbers are treated
-as their 2's complement value (this assumes a sufficiently large number of bits
-that no overflow occurs during the operation).
+as their 2's complement value (this assumes that there are enough bits so that
+no overflow occurs during the operation).
 
 The priorities of the binary bitwise operations are all lower than the numeric
 operations and higher than the comparisons; the unary operation ``~`` has the
@@ -1298,16 +1301,16 @@ loops.
    only represent sequences that follow a strict pattern and repetition and
    concatenation will usually violate that pattern).
 
-   .. data: start
+   .. attribute:: start
 
       The value of the *start* parameter (or ``0`` if the parameter was
       not supplied)
 
-   .. data: stop
+   .. attribute:: stop
 
       The value of the *stop* parameter
 
-   .. data: step
+   .. attribute:: step
 
       The value of the *step* parameter (or ``1`` if the parameter was
       not supplied)
@@ -1450,7 +1453,7 @@ multiple fragments.
 
    For more information on the ``str`` class and its methods, see
    :ref:`textseq` and the :ref:`string-methods` section below.  To output
-   formatted strings, see the :ref:`string-formatting` section.  In addition,
+   formatted strings, see the :ref:`formatstrings` section.  In addition,
    see the :ref:`stringservices` section.
 
 
@@ -1563,10 +1566,9 @@ expression support in the :mod:`re` module).
 
 .. method:: str.find(sub[, start[, end]])
 
-   Return the lowest index in the string where substring *sub* is found, such
-   that *sub* is contained in the slice ``s[start:end]``.  Optional arguments
-   *start* and *end* are interpreted as in slice notation.  Return ``-1`` if
-   *sub* is not found.
+   Return the lowest index in the string where substring *sub* is found within
+   the slice ``s[start:end]``.  Optional arguments *start* and *end* are
+   interpreted as in slice notation.  Return ``-1`` if *sub* is not found.
 
    .. note::
 
@@ -2940,7 +2942,7 @@ place, and instead produce new objects.
 
    Return true if all bytes in the sequence are ASCII whitespace and the
    sequence is not empty, false otherwise.  ASCII whitespace characters are
-   those byte values in the sequence b' \t\n\r\x0b\f' (space, tab, newline,
+   those byte values in the sequence ``b' \t\n\r\x0b\f'`` (space, tab, newline,
    carriage return, vertical tab, form feed).
 
 
@@ -3829,7 +3831,7 @@ The constructors for both classes work the same:
 
    .. describe:: len(s)
 
-      Return the cardinality of set *s*.
+      Return the number of elements in set *s* (cardinality of *s*).
 
    .. describe:: x in s
 
@@ -4434,13 +4436,13 @@ attribute, you need to explicitly set it on the underlying function object::
 See :ref:`types` for more information.
 
 
+.. index:: object; code, code object
+
 .. _bltin-code-objects:
 
 Code Objects
 ------------
 
-.. index:: object: code
-
 .. index::
    builtin: compile
    single: __code__ (function object attribute)
index 2bd8dfd..d5d2430 100644 (file)
@@ -75,14 +75,14 @@ The constants defined in this module are:
 
 .. _string-formatting:
 
-String Formatting
------------------
+Custom String Formatting
+------------------------
 
 The built-in string class provides the ability to do complex variable
-substitutions and value formatting via the :func:`format` method described in
+substitutions and value formatting via the :meth:`~str.format` method described in
 :pep:`3101`.  The :class:`Formatter` class in the :mod:`string` module allows
 you to create and customize your own string formatting behaviors using the same
-implementation as the built-in :meth:`format` method.
+implementation as the built-in :meth:`~str.format` method.
 
 
 .. class:: Formatter
@@ -91,9 +91,9 @@ implementation as the built-in :meth:`format` method.
 
    .. method:: format(format_string, *args, **kwargs)
 
-      :meth:`format` is the primary API method.  It takes a format string and
+      The primary API method.  It takes a format string and
       an arbitrary set of positional and keyword arguments.
-      :meth:`format` is just a wrapper that calls :meth:`vformat`.
+      It is just a wrapper that calls :meth:`vformat`.
 
       .. deprecated:: 3.5
          Passing a format string as keyword argument *format_string* has been
@@ -234,12 +234,12 @@ does an index lookup using :func:`__getitem__`.
 
 Some simple format string examples::
 
-   "First, thou shalt count to {0}" # References first positional argument
-   "Bring me a {}"                  # Implicitly references the first positional argument
-   "From {} to {}"                  # Same as "From {0} to {1}"
-   "My quest is {name}"             # References keyword argument 'name'
-   "Weight in tons {0.weight}"      # 'weight' attribute of first positional arg
-   "Units destroyed: {players[0]}"  # First element of keyword argument 'players'.
+   "First, thou shalt count to {0}"  # References first positional argument
+   "Bring me a {}"                   # Implicitly references the first positional argument
+   "From {} to {}"                   # Same as "From {0} to {1}"
+   "My quest is {name}"              # References keyword argument 'name'
+   "Weight in tons {0.weight}"       # 'weight' attribute of first positional arg
+   "Units destroyed: {players[0]}"   # First element of keyword argument 'players'.
 
 The *conversion* field causes a type coercion before formatting.  Normally, the
 job of formatting a value is done by the :meth:`__format__` method of the value
@@ -267,8 +267,9 @@ Most built-in types support a common formatting mini-language, which is
 described in the next section.
 
 A *format_spec* field can also include nested replacement fields within it.
-These nested replacement fields can contain only a field name; conversion flags
-and format specifications are not allowed.  The replacement fields within the
+These nested replacement fields may contain a field name, conversion flag
+and format specification, but deeper nesting is
+not allowed.  The replacement fields within the
 format_spec are substituted before the *format_spec* string is interpreted.
 This allows the formatting of a value to be dynamically specified.
 
@@ -306,8 +307,10 @@ The general form of a *standard format specifier* is:
 
 If a valid *align* value is specified, it can be preceded by a *fill*
 character that can be any character and defaults to a space if omitted.
-Note that it is not possible to use ``{`` and ``}`` as *fill* char while
-using the :meth:`str.format` method; this limitation however doesn't
+It is not possible to use a literal curly brace ("``{``" or "``}``") as
+the *fill* character when using the :meth:`str.format`
+method.  However, it is possible to insert a curly brace
+with a nested replacement field.  This limitation doesn't
 affect the :func:`format` function.
 
 The meaning of the various alignment options is as follows:
@@ -324,7 +327,8 @@ The meaning of the various alignment options is as follows:
    | ``'='`` | Forces the padding to be placed after the sign (if any)  |
    |         | but before the digits.  This is used for printing fields |
    |         | in the form '+000000120'. This alignment option is only  |
-   |         | valid for numeric types.                                 |
+   |         | valid for numeric types.  It becomes the default when '0'|
+   |         | immediately precedes the field width.                    |
    +---------+----------------------------------------------------------+
    | ``'^'`` | Forces the field to be centered within the available     |
    |         | space.                                                   |
@@ -373,7 +377,8 @@ instead.
 *width* is a decimal integer defining the minimum field width.  If not
 specified, then the field width will be determined by the content.
 
-Preceding the *width* field by a zero (``'0'``) character enables
+When no explicit alignment is given, preceding the *width* field by a zero
+(``'0'``) character enables
 sign-aware zero-padding for numeric types.  This is equivalent to a *fill*
 character of ``'0'`` with an *alignment* type of ``'='``.
 
@@ -496,8 +501,8 @@ The available presentation types for floating point and decimal values are:
 Format examples
 ^^^^^^^^^^^^^^^
 
-This section contains examples of the new format syntax and comparison with
-the old ``%``-formatting.
+This section contains examples of the :meth:`str.format` syntax and
+comparison with the old ``%``-formatting.
 
 In most of the cases the syntax is similar to the old ``%``-formatting, with the
 addition of the ``{}`` and with ``:`` used instead of ``%``.
index fc890cb..e7fae56 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: stringprep
    :synopsis: String preparation, as per RFC 3453
+
 .. moduleauthor:: Martin v. Löwis <martin@v.loewis.de>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
 
+**Source code:** :source:`Lib/stringprep.py`
+
+--------------
 
 When identifying things (such as host names) in the internet, it is often
 necessary to compare such identifications for "equality". Exactly how this
index 12d4fbc..ae2e38f 100644 (file)
@@ -4,10 +4,14 @@
 .. module:: struct
    :synopsis: Interpret bytes as packed binary data.
 
+**Source code:** :source:`Lib/struct.py`
+
 .. index::
    pair: C; structures
    triple: packing; binary; data
 
+--------------
+
 This module performs conversions between Python values and C structs represented
 as Python :class:`bytes` objects.  This can be used in handling binary data
 stored in files or from network connections, among other sources.  It uses
@@ -62,16 +66,16 @@ The module defines the following exception and functions:
 
    Unpack from the buffer *buffer* (presumably packed by ``pack(fmt, ...)``)
    according to the format string *fmt*.  The result is a tuple even if it
-   contains exactly one item.  The buffer must contain exactly the amount of
-   data required by the format (``len(bytes)`` must equal ``calcsize(fmt)``).
+   contains exactly one item.  The buffer's size in bytes must match the
+   size required by the format, as reflected by :func:`calcsize`.
 
 
 .. function:: unpack_from(fmt, buffer, offset=0)
 
    Unpack from *buffer* starting at position *offset*, according to the format
    string *fmt*.  The result is a tuple even if it contains exactly one
-   item.  *buffer* must contain at least the amount of data required by the
-   format (``len(buffer[offset:])`` must be at least ``calcsize(fmt)``).
+   item.  The buffer's size in bytes, minus *offset*, must be at least
+   the size required by the format, as reflected by :func:`calcsize`.
 
 
 .. function:: iter_unpack(fmt, buffer)
@@ -79,8 +83,8 @@ The module defines the following exception and functions:
    Iteratively unpack from the buffer *buffer* according to the format
    string *fmt*.  This function returns an iterator which will read
    equally-sized chunks from the buffer until all its contents have been
-   consumed.  The buffer's size in bytes must be a multiple of the amount
-   of data required by the format, as reflected by :func:`calcsize`.
+   consumed.  The buffer's size in bytes must be a multiple of the size
+   required by the format, as reflected by :func:`calcsize`.
 
    Each iteration yields a tuple as specified by the format string.
 
@@ -389,7 +393,7 @@ The :mod:`struct` module also defines the following type:
    .. method:: pack(v1, v2, ...)
 
       Identical to the :func:`pack` function, using the compiled format.
-      (``len(result)`` will equal :attr:`self.size`.)
+      (``len(result)`` will equal :attr:`size`.)
 
 
    .. method:: pack_into(buffer, offset, v1, v2, ...)
@@ -400,19 +404,20 @@ The :mod:`struct` module also defines the following type:
    .. method:: unpack(buffer)
 
       Identical to the :func:`unpack` function, using the compiled format.
-      (``len(buffer)`` must equal :attr:`self.size`).
+      The buffer's size in bytes must equal :attr:`size`.
 
 
    .. method:: unpack_from(buffer, offset=0)
 
       Identical to the :func:`unpack_from` function, using the compiled format.
-      (``len(buffer[offset:])`` must be at least :attr:`self.size`).
+      The buffer's size in bytes, minus *offset*, must be at least
+      :attr:`size`.
 
 
    .. method:: iter_unpack(buffer)
 
       Identical to the :func:`iter_unpack` function, using the compiled format.
-      (``len(buffer)`` must be a multiple of :attr:`self.size`).
+      The buffer's size in bytes must be a multiple of :attr:`size`.
 
       .. versionadded:: 3.4
 
index adf99ec..f469107 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: subprocess
    :synopsis: Subprocess management.
+
 .. moduleauthor:: Peter Åstrand <astrand@lysator.liu.se>
 .. sectionauthor:: Peter Åstrand <astrand@lysator.liu.se>
 
+**Source code:** :source:`Lib/subprocess.py`
+
+--------------
 
 The :mod:`subprocess` module allows you to spawn new processes, connect to their
 input/output/error pipes, and obtain their return codes.  This module intends to
@@ -188,7 +192,8 @@ compatibility with older versions, see the :ref:`call-function-trio` section.
 
     .. attribute:: returncode
 
-        Exit status of the child process.
+        Exit status of the child process.  If the process exited due to a
+        signal, this will be the negative signal number.
 
     .. attribute:: cmd
 
@@ -475,7 +480,7 @@ functions.
       execute.  On Windows, in order to run a `side-by-side assembly`_ the
       specified *env* **must** include a valid :envvar:`SystemRoot`.
 
-   .. _side-by-side assembly: http://en.wikipedia.org/wiki/Side-by-Side_Assembly
+   .. _side-by-side assembly: https://en.wikipedia.org/wiki/Side-by-Side_Assembly
 
    If *universal_newlines* is ``True``, the file objects *stdin*, *stdout*
    and *stderr* are opened as text streams in universal newlines mode, as
@@ -536,7 +541,7 @@ including shell metacharacters, can safely be passed to child processes.
 If the shell is invoked explicitly, via ``shell=True``, it is the application's
 responsibility to ensure that all whitespace and metacharacters are
 quoted appropriately to avoid
-`shell injection <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
+`shell injection <https://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
 vulnerabilities.
 
 When using ``shell=True``, the :func:`shlex.quote` function can be
@@ -721,7 +726,7 @@ on Windows.
 .. class:: STARTUPINFO()
 
    Partial support of the Windows
-   `STARTUPINFO <http://msdn.microsoft.com/en-us/library/ms686331(v=vs.85).aspx>`__
+   `STARTUPINFO <https://msdn.microsoft.com/en-us/library/ms686331(v=vs.85).aspx>`__
    structure is used for :class:`Popen` creation.
 
    .. attribute:: dwFlags
@@ -757,7 +762,7 @@ on Windows.
       If :attr:`dwFlags` specifies :data:`STARTF_USESHOWWINDOW`, this attribute
       can be any of the values that can be specified in the ``nCmdShow``
       parameter for the
-      `ShowWindow <http://msdn.microsoft.com/en-us/library/ms633548(v=vs.85).aspx>`__
+      `ShowWindow <https://msdn.microsoft.com/en-us/library/ms633548(v=vs.85).aspx>`__
       function, except for ``SW_SHOWDEFAULT``. Otherwise, this attribute is
       ignored.
 
index bd37ee2..d0fd0a3 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: sunau
    :synopsis: Provide an interface to the Sun AU sound format.
+
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
 **Source code:** :source:`Lib/sunau.py`
index ef9ef1e..4499693 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: symbol
    :synopsis: Constants representing internal nodes of the parse tree.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
 **Source code:** :source:`Lib/symbol.py`
index f6325cc..9f70a13 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: sys
    :synopsis: Access system-specific parameters and functions.
 
+--------------
 
 This module provides access to some variables used or maintained by the
 interpreter and to functions that interact strongly with the interpreter. It is
@@ -474,7 +475,7 @@ always available.
    additional garbage collector overhead if the object is managed by the garbage
    collector.
 
-   See `recursive sizeof recipe <http://code.activestate.com/recipes/577504>`_
+   See `recursive sizeof recipe <https://code.activestate.com/recipes/577504>`_
    for an example of using :func:`getsizeof` recursively to find the size of
    containers and all their contents.
 
@@ -774,19 +775,32 @@ always available.
 
 .. data:: meta_path
 
-    A list of :term:`finder` objects that have their :meth:`find_module`
-    methods called to see if one of the objects can find the module to be
-    imported. The :meth:`find_module` method is called at least with the
-    absolute name of the module being imported. If the module to be imported is
-    contained in package then the parent package's :attr:`__path__` attribute
-    is passed in as a second argument. The method returns ``None`` if
-    the module cannot be found, else returns a :term:`loader`.
-
-    :data:`sys.meta_path` is searched before any implicit default finders or
-    :data:`sys.path`.
-
-    See :pep:`302` for the original specification.
-
+    A list of :term:`meta path finder` objects that have their
+    :meth:`~importlib.abc.MetaPathFinder.find_spec` methods called to see if one
+    of the objects can find the module to be imported. The
+    :meth:`~importlib.abc.MetaPathFinder.find_spec` method is called with at
+    least the absolute name of the module being imported. If the module to be
+    imported is contained in a package, then the parent package's :attr:`__path__`
+    attribute is passed in as a second argument. The method returns a
+    :term:`module spec`, or ``None`` if the module cannot be found.
+
+    .. seealso::
+
+        :class:`importlib.abc.MetaPathFinder`
+          The abstract base class defining the interface of finder objects on
+          :data:`meta_path`.
+        :class:`importlib.machinery.ModuleSpec`
+          The concrete class which
+          :meth:`~importlib.abc.MetaPathFinder.find_spec` should return
+          instances of.
+
+    .. versionchanged:: 3.4
+
+        :term:`Module specs <module spec>` were introduced in Python 3.4, by
+        :pep:`451`. Earlier versions of Python looked for a method called
+        :meth:`~importlib.abc.MetaPathFinder.find_module`.
+        This is still called as a fallback if a :data:`meta_path` entry doesn't
+        have a :meth:`~importlib.abc.MetaPathFinder.find_spec` method.
 
 .. data:: modules
 
index 535ac54..0b0df9b 100644 (file)
@@ -3,16 +3,17 @@
 
 .. module:: sysconfig
    :synopsis: Python's configuration information
+
 .. moduleauthor:: Tarek Ziadé <tarek@ziade.org>
 .. sectionauthor:: Tarek Ziadé <tarek@ziade.org>
 
-.. index::
-   single: configuration information
-
 .. versionadded:: 3.2
 
 **Source code:** :source:`Lib/sysconfig.py`
 
+.. index::
+   single: configuration information
+
 --------------
 
 The :mod:`sysconfig` module provides access to Python's configuration
index 6e90dc0..af3fb9b 100644 (file)
@@ -5,6 +5,7 @@
    :platform: Unix
    :synopsis: An interface to the Unix syslog library routines.
 
+--------------
 
 This module provides an interface to the Unix ``syslog`` library routines.
 Refer to the Unix manual pages for a detailed description of the ``syslog``
index 4f3e705..1edb0fb 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: tabnanny
    :synopsis: Tool for detecting white space related problems in Python
               source files in a directory tree.
+
 .. moduleauthor:: Tim Peters <tim_one@users.sourceforge.net>
 .. sectionauthor:: Peter Funk <pf@artcom-gmbh.de>
 
index adacb0a..32d69bf 100644 (file)
@@ -4,7 +4,6 @@
 .. module:: tarfile
    :synopsis: Read and write tar-format archive files.
 
-
 .. moduleauthor:: Lars Gustäbel <lars@gustaebel.de>
 .. sectionauthor:: Lars Gustäbel <lars@gustaebel.de>
 
@@ -101,7 +100,7 @@ Some facts and figures:
 
    For modes ``'w:gz'``, ``'r:gz'``, ``'w:bz2'``, ``'r:bz2'``, ``'x:gz'``,
    ``'x:bz2'``, :func:`tarfile.open` accepts the keyword argument
-   *compresslevel* to specify the compression level of the file.
+   *compresslevel* (default ``9``) to specify the compression level of the file.
 
    For special purposes, there is a second format for *mode*:
    ``'filemode|[compression]'``.  :func:`tarfile.open` will return a :class:`TarFile`
@@ -111,7 +110,7 @@ Some facts and figures:
    specifies the blocksize and defaults to ``20 * 512`` bytes. Use this variant
    in combination with e.g. ``sys.stdin``, a socket :term:`file object` or a tape
    device. However, such a :class:`TarFile` object is limited in that it does
-   not allow to be accessed randomly, see :ref:`tar-examples`.  The currently
+   not allow random access, see :ref:`tar-examples`.  The currently
    possible modes:
 
    +-------------+--------------------------------------------+
@@ -129,7 +128,7 @@ Some facts and figures:
    | ``'r|bz2'`` | Open a bzip2 compressed *stream* for       |
    |             | reading.                                   |
    +-------------+--------------------------------------------+
-   | ``'r|xz'``  | Open a lzma compressed *stream* for        |
+   | ``'r|xz'``  | Open an lzma compressed *stream* for       |
    |             | reading.                                   |
    +-------------+--------------------------------------------+
    | ``'w|'``    | Open an uncompressed *stream* for writing. |
@@ -238,7 +237,7 @@ details.
       Documentation of the higher-level archiving facilities provided by the
       standard :mod:`shutil` module.
 
-   `GNU tar manual, Basic Tar Format <http://www.gnu.org/software/tar/manual/html_node/Standard.html>`_
+   `GNU tar manual, Basic Tar Format <https://www.gnu.org/software/tar/manual/html_node/Standard.html>`_
       Documentation for tar archive files, including GNU tar extensions.
 
 
@@ -456,21 +455,28 @@ be finalized; only the internally used file object will be closed. See the
 .. method:: TarFile.addfile(tarinfo, fileobj=None)
 
    Add the :class:`TarInfo` object *tarinfo* to the archive. If *fileobj* is given,
+   it should be a :term:`binary file`, and
    ``tarinfo.size`` bytes are read from it and added to the archive.  You can
-   create :class:`TarInfo` objects using :meth:`gettarinfo`.
-
-   .. note::
-
-      On Windows platforms, *fileobj* should always be opened with mode ``'rb'`` to
-      avoid irritation about the file size.
+   create :class:`TarInfo` objects directly, or by using :meth:`gettarinfo`.
 
 
 .. method:: TarFile.gettarinfo(name=None, arcname=None, fileobj=None)
 
-   Create a :class:`TarInfo` object for either the file *name* or the :term:`file
-   object` *fileobj* (using :func:`os.fstat` on its file descriptor).  You can modify
-   some of the :class:`TarInfo`'s attributes before you add it using :meth:`addfile`.
-   If given, *arcname* specifies an alternative name for the file in the archive.
+   Create a :class:`TarInfo` object from the result of :func:`os.stat` or
+   equivalent on an existing file.  The file is either named by *name*, or
+   specified as a :term:`file object` *fileobj* with a file descriptor.  If
+   given, *arcname* specifies an alternative name for the file in the
+   archive, otherwise, the name is taken from *fileobj*’s
+   :attr:`~io.FileIO.name` attribute, or the *name* argument.  The name
+   should be a text string.
+
+   You can modify
+   some of the :class:`TarInfo`’s attributes before you add it using :meth:`addfile`.
+   If the file object is not an ordinary file object positioned at the
+   beginning of the file, attributes such as :attr:`~TarInfo.size` may need
+   modifying.  This is the case for objects such as :class:`~gzip.GzipFile`.
+   The :attr:`~TarInfo.name` may also be modified, in which case *arcname*
+   could be a dummy string.
 
 
 .. method:: TarFile.close()
index 4040f72..b950e41 100644 (file)
@@ -3,13 +3,13 @@
 
 .. module:: telnetlib
    :synopsis: Telnet client class.
+
 .. sectionauthor:: Skip Montanaro <skip@pobox.com>
 
+**Source code:** :source:`Lib/telnetlib.py`
 
 .. index:: single: protocol; Telnet
 
-**Source code:** :source:`Lib/telnetlib.py`
-
 --------------
 
 The :mod:`telnetlib` module provides a :class:`Telnet` class that implements the
index 19e1e7f..665261f 100644 (file)
@@ -1,19 +1,17 @@
 :mod:`tempfile` --- Generate temporary files and directories
 ============================================================
 
-.. sectionauthor:: Zack Weinberg <zack@codesourcery.com>
-
-
 .. module:: tempfile
    :synopsis: Generate temporary files and directories.
 
+.. sectionauthor:: Zack Weinberg <zack@codesourcery.com>
+
+**Source code:** :source:`Lib/tempfile.py`
 
 .. index::
    pair: temporary; file name
    pair: temporary; file
 
-**Source code:** :source:`Lib/tempfile.py`
-
 --------------
 
 This module creates temporary files and directories.  It works on all
@@ -74,7 +72,8 @@ The module defines the following user-callable items:
    This function operates exactly as :func:`TemporaryFile` does, except that
    the file is guaranteed to have a visible name in the file system (on
    Unix, the directory entry is not unlinked).  That name can be retrieved
-   from the :attr:`name` attribute of the file object.  Whether the name can be
+   from the :attr:`name` attribute of the returned
+   file-like object.  Whether the name can be
    used to open the file a second time, while the named temporary file is
    still open, varies across platforms (it can be so used on Unix; it cannot
    on Windows NT or later).  If *delete* is true (the default), the file is
@@ -255,7 +254,7 @@ to specify the directory and this is the recommend approach.
    module.
 
    If ``tempdir`` is unset or ``None`` at any call to any of the above
-   functions except :func:`gettempprefix` it is initalized following the
+   functions except :func:`gettempprefix` it is initialized following the
    algorithm described in :func:`gettempdir`.
 
 .. _tempfile-examples:
index a90a825..ad6a9f7 100644 (file)
@@ -5,15 +5,16 @@
    :platform: Unix
    :synopsis: POSIX style tty control.
 
-
 .. index::
    pair: POSIX; I/O control
    pair: tty; I/O control
 
-This module provides an interface to the POSIX calls for tty I/O control.  For a
-complete description of these calls, see the POSIX or Unix manual pages.  It is
-only available for those Unix versions that support POSIX *termios* style tty
-I/O control (and then only if configured at installation time).
+--------------
+
+This module provides an interface to the POSIX calls for tty I/O control. For a
+complete description of these calls, see :manpage:`termios(2)` Unix manual
+page.  It is only available for those Unix versions that support POSIX
+*termios* style tty I/O control configured during installation.
 
 All functions in this module take a file descriptor *fd* as their first
 argument.  This can be an integer file descriptor, such as returned by
index 85cab3b..2ea9c27 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: test
    :synopsis: Regression tests package containing the testing suite for Python.
+
 .. sectionauthor:: Brett Cannon <brett@python.org>
 
 .. note::
@@ -12,6 +13,7 @@
    mentioned here can change or be removed without notice between releases of
    Python.
 
+--------------
 
 The :mod:`test` package contains all regression tests for Python as well as the
 modules :mod:`test.support` and :mod:`test.regrtest`.
@@ -550,7 +552,7 @@ The :mod:`test.support` module defines the following functions:
    or passed to an external program (i.e. the ``-accept`` argument to
    openssl's s_server mode).  Always prefer :func:`bind_port` over
    :func:`find_unused_port` where possible.  Using a hard coded port is
-   discouraged since it can makes multiple instances of the test impossible to
+   discouraged since it can make multiple instances of the test impossible to
    run simultaneously, which is a problem for buildbots.
 
 
@@ -619,7 +621,7 @@ The :mod:`test.support` module defines the following classes:
    are expected to crash a subprocess.
 
    On Windows, it disables Windows Error Reporting dialogs using
-   `SetErrorMode <http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx>`_.
+   `SetErrorMode <https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx>`_.
 
    On UNIX, :func:`resource.setrlimit` is used to set
    :attr:`resource.RLIMIT_CORE`'s soft limit to 0 to prevent coredump file
index 9fe7a35..438007d 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: textwrap
    :synopsis: Text wrapping and filling
+
 .. moduleauthor:: Greg Ward <gward@python.net>
 .. sectionauthor:: Greg Ward <gward@python.net>
 
index c56d707..3066496 100644 (file)
@@ -847,7 +847,7 @@ For example::
        print("hello, world")
 
    t = Timer(30.0, hello)
-   t.start() # after 30 seconds, "hello, world" will be printed
+   t.start()  # after 30 seconds, "hello, world" will be printed
 
 
 .. class:: Timer(interval, function, args=None, kwargs=None)
index 3d335c8..e6626f2 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: time
    :synopsis: Time access and conversions.
 
+--------------
 
 This module provides various time-related functions. For related
 functionality, see also the :mod:`datetime` and :mod:`calendar` modules.
@@ -555,9 +556,11 @@ The module defines the following functions and data items:
    +-------+-------------------+---------------------------------+
 
    Note that unlike the C structure, the month value is a range of [1, 12], not
-   [0, 11].  A ``-1`` argument as the daylight
-   savings flag, passed to :func:`mktime` will usually result in the correct
-   daylight savings state to be filled in.
+   [0, 11].
+
+   In calls to :func:`mktime`, :attr:`tm_isdst` may be set to 1 when daylight
+   savings time is in effect, and 0 when it is not.  A value of -1 indicates that
+   this is not known, and will usually result in the correct state being filled in.
 
    When a tuple with an incorrect length is passed to a function expecting a
    :class:`struct_time`, or having elements of the wrong type, a
index d1051f6..57a4834 100644 (file)
@@ -4,17 +4,16 @@
 .. module:: timeit
    :synopsis: Measure the execution time of small code snippets.
 
+**Source code:** :source:`Lib/timeit.py`
 
 .. index::
    single: Benchmarking
    single: Performance
 
-**Source code:** :source:`Lib/timeit.py`
-
 --------------
 
 This module provides a simple way to time small bits of Python code. It has both
-a :ref:`command-line-interface` as well as a :ref:`callable <python-interface>`
+a :ref:`timeit-command-line-interface` as well as a :ref:`callable <python-interface>`
 one.  It avoids a number of common traps for measuring execution times.
 See also Tim Peters' introduction to the "Algorithms" chapter in the *Python
 Cookbook*, published by O'Reilly.
@@ -23,7 +22,7 @@ Cookbook*, published by O'Reilly.
 Basic Examples
 --------------
 
-The following example shows how the :ref:`command-line-interface`
+The following example shows how the :ref:`timeit-command-line-interface`
 can be used to compare three different expressions:
 
 .. code-block:: sh
@@ -174,7 +173,7 @@ The module defines three convenience functions and a public class:
       where the traceback is sent; it defaults to :data:`sys.stderr`.
 
 
-.. _command-line-interface:
+.. _timeit-command-line-interface:
 
 Command-Line Interface
 ----------------------
index 8b738c3..130aafe 100644 (file)
@@ -3,8 +3,12 @@
 
 .. module:: tkinter
    :synopsis: Interface to Tcl/Tk for graphical user interfaces
+
 .. moduleauthor:: Guido van Rossum <guido@Python.org>
 
+**Source code:** :source:`Lib/tkinter/__init__.py`
+
+--------------
 
 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
@@ -22,22 +26,22 @@ this should open a window demonstrating a simple Tk interface.
    `TKDocs <http://www.tkdocs.com/>`_
       Extensive tutorial plus friendlier widget pages for some of the widgets.
 
-   `Tkinter reference: a GUI for Python <http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html>`_
+   `Tkinter reference: a GUI for Python <https://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html>`_
       On-line reference material.
 
    `Tkinter docs from effbot <http://effbot.org/tkinterbook/>`_
       Online reference for tkinter supported by effbot.org.
 
-   `Tcl/Tk manual <http://www.tcl.tk/man/tcl8.5/>`_
+   `Tcl/Tk manual <https://www.tcl.tk/man/tcl8.5/>`_
       Official manual for the latest tcl/tk version.
 
-   `Programming Python <http://www.rmi.net/~lutz/about-pp4e.html>`_
+   `Programming Python <http://learning-python.com/books/about-pp4e.html>`_
       Book by Mark Lutz, has excellent coverage of Tkinter.
 
    `Modern Tkinter for Busy Python Developers <http://www.amazon.com/Modern-Tkinter-Python-Developers-ebook/dp/B0071QDNLO/>`_
       Book by Mark Rozerman about building attractive and modern graphical user interfaces with Python and Tkinter.
 
-   `Python and Tkinter Programming <http://www.manning.com/grayson/>`_
+   `Python and Tkinter Programming <https://www.manning.com/books/python-and-tkinter-programming>`_
       The book by John Grayson (ISBN 1-884777-81-3).
 
 
@@ -173,7 +177,7 @@ documentation that exists. Here are some hints:
 
 .. seealso::
 
-   `Tcl/Tk 8.6 man pages <http://www.tcl.tk/man/tcl8.6/>`_
+   `Tcl/Tk 8.6 man pages <https://www.tcl.tk/man/tcl8.6/>`_
       The Tcl/Tk manual on www.tcl.tk.
 
    `ActiveState Tcl Home Page <http://tcl.activestate.com/>`_
@@ -206,7 +210,7 @@ A Simple Hello World Program
             self.hi_there.pack(side="top")
 
             self.QUIT = tk.Button(self, text="QUIT", fg="red",
-                                                command=root.destroy)
+                                  command=root.destroy)
             self.QUIT.pack(side="bottom")
 
         def say_hi(self):
index 520970f..138720e 100644 (file)
@@ -4,8 +4,12 @@
 .. module:: tkinter.scrolledtext
    :platform: Tk
    :synopsis: Text widget with a vertical scroll bar.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
+**Source code:** :source:`Lib/tkinter/scrolledtext.py`
+
+--------------
 
 The :mod:`tkinter.scrolledtext` module provides a class of the same name which
 implements a basic text widget which has a vertical scroll bar configured to do
index 9de73ad..41f20dd 100644 (file)
@@ -3,11 +3,15 @@
 
 .. module:: tkinter.tix
    :synopsis: Tk Extension Widgets for Tkinter
+
 .. sectionauthor:: Mike Clarkson <mikeclarkson@users.sourceforge.net>
 
+**Source code:** :source:`Lib/tkinter/tix.py`
 
 .. index:: single: Tix
 
+--------------
+
 The :mod:`tkinter.tix` (Tk Interface Extension) module provides an additional
 rich set of widgets. Although the standard Tk library has many useful widgets,
 they are far from complete. The :mod:`tkinter.tix` library provides most of the
@@ -142,7 +146,7 @@ Basic Widgets
 
    The `LabelEntry
    <http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixLabelEntry.htm>`_
-   widget packages an entry widget and a label into one mega widget. It can be used
+   widget packages an entry widget and a label into one mega widget. It can
    be used to simplify the creation of "entry-form" type of interface.
 
 .. Python Demo of:
@@ -267,7 +271,7 @@ File Selectors
 
    The `ExFileSelectBox
    <http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixExFileSelectBox.htm>`_
-   widget is usually embedded in a tixExFileSelectDialog widget. It provides an
+   widget is usually embedded in a tixExFileSelectDialog widget. It provides a
    convenient method for the user to select files. The style of the
    :class:`ExFileSelectBox` widget is very similar to the standard file dialog on
    MS Windows 3.1.
index 4601171..dbb5bd2 100644 (file)
@@ -3,11 +3,15 @@
 
 .. module:: tkinter.ttk
    :synopsis: Tk themed widget set
+
 .. sectionauthor:: Guilherme Polo <ggpolo@gmail.com>
 
+**Source code:** :source:`Lib/tkinter/ttk.py`
 
 .. index:: single: ttk
 
+--------------
+
 The :mod:`tkinter.ttk` module provides access to the Tk themed widget set,
 introduced in Tk 8.5. If Python has not been compiled against Tk 8.5, this
 module can still be accessed if *Tile* has been installed.  The former
@@ -22,7 +26,7 @@ appearance.
 
 .. seealso::
 
-   `Tk Widget Styling Support <http://www.tcl.tk/cgi-bin/tct/tip/48>`_
+   `Tk Widget Styling Support <https://www.tcl.tk/cgi-bin/tct/tip/48>`_
       A document introducing theming support for Tk
 
 
@@ -299,7 +303,7 @@ Besides the methods inherited from :class:`Widget`: :meth:`Widget.cget`,
 :meth:`Widget.configure`, :meth:`Widget.identify`, :meth:`Widget.instate`
 and :meth:`Widget.state`, and the following inherited from :class:`Entry`:
 :meth:`Entry.bbox`, :meth:`Entry.delete`, :meth:`Entry.icursor`,
-:meth:`Entry.index`, :meth:`Entry.inset`, :meth:`Entry.selection`,
+:meth:`Entry.index`, :meth:`Entry.insert`, :meth:`Entry.selection`,
 :meth:`Entry.xview`, it has some other methods, described at
 :class:`ttk.Combobox`.
 
@@ -701,7 +705,7 @@ the widget option ``displaycolumns``. The tree widget can also display column
 headings. Columns may be accessed by number or symbolic names listed in the
 widget option columns. See `Column Identifiers`_.
 
-Each item is identified by an unique name. The widget will generate item IDs
+Each item is identified by a unique name. The widget will generate item IDs
 if they are not supplied by the caller. There is a distinguished root item,
 named ``{}``. The root item itself is not displayed; its children appear at the
 top level of the hierarchy.
index 88fb38b..116efca 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: token
    :synopsis: Constants representing terminal nodes of the parse tree.
+
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
 **Source code:** :source:`Lib/token.py`
@@ -97,10 +98,16 @@ The token constants are:
           RARROW
           ELLIPSIS
           OP
+          AWAIT
+          ASYNC
           ERRORTOKEN
           N_TOKENS
           NT_OFFSET
 
+   .. versionchanged:: 3.5
+      Added :data:`AWAIT` and :data:`ASYNC` tokens. Starting with
+      Python 3.7, "async" and "await" will be tokenized as :data:`NAME`
+      tokens, and :data:`AWAIT` and :data:`ASYNC` will be removed.
 
 .. seealso::
 
index c9cb518..ff55aac 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: tokenize
    :synopsis: Lexical scanner for Python source code.
+
 .. moduleauthor:: Ka Ping Yee
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
@@ -27,7 +28,7 @@ The primary entry point is a :term:`generator`:
 
 .. function:: tokenize(readline)
 
-   The :func:`tokenize` generator requires one argument, *readline*, which
+   The :func:`.tokenize` generator requires one argument, *readline*, which
    must be a callable object which provides the same interface as the
    :meth:`io.IOBase.readline` method of file objects.  Each call to the
    function should return one line of input as bytes.
@@ -52,7 +53,7 @@ The primary entry point is a :term:`generator`:
    .. versionchanged:: 3.3
       Added support for ``exact_type``.
 
-   :func:`tokenize` determines the source encoding of the file by looking for a
+   :func:`.tokenize` determines the source encoding of the file by looking for a
    UTF-8 BOM or encoding cookie, according to :pep:`263`.
 
 
@@ -74,7 +75,7 @@ All constants from the :mod:`token` module are also exported from
 .. data:: ENCODING
 
     Token value that indicates the encoding used to decode the source bytes
-    into text. The first token returned by :func:`tokenize` will always be an
+    into text. The first token returned by :func:`.tokenize` will always be an
     ENCODING token.
 
 
@@ -96,17 +97,17 @@ write back the modified script.
     positions) may change.
 
     It returns bytes, encoded using the ENCODING token, which is the first
-    token sequence output by :func:`tokenize`.
+    token sequence output by :func:`.tokenize`.
 
 
-:func:`tokenize` needs to detect the encoding of source files it tokenizes. The
+:func:`.tokenize` needs to detect the encoding of source files it tokenizes. The
 function it uses to do this is available:
 
 .. function:: detect_encoding(readline)
 
     The :func:`detect_encoding` function is used to detect the encoding that
     should be used to decode a Python source file. It requires one argument,
-    readline, in the same way as the :func:`tokenize` generator.
+    readline, in the same way as the :func:`.tokenize` generator.
 
     It will call readline a maximum of twice, and return the encoding used
     (as a string) and a list of any lines (not decoded from bytes) it has read
@@ -120,7 +121,7 @@ function it uses to do this is available:
     If no encoding is specified, then the default of ``'utf-8'`` will be
     returned.
 
-    Use :func:`open` to open Python source files: it uses
+    Use :func:`.open` to open Python source files: it uses
     :func:`detect_encoding` to detect the file encoding.
 
 
@@ -201,7 +202,7 @@ objects::
         we're only showing 12 digits, and the 13th isn't close to 5, the
         rest of the output should be platform-independent.
 
-        >>> exec(s) #doctest: +ELLIPSIS
+        >>> exec(s)  #doctest: +ELLIPSIS
         -3.21716034272e-0...7
 
         Output from calculations with Decimal should be identical across all
@@ -211,8 +212,8 @@ objects::
         -3.217160342717258261933904529E-7
         """
         result = []
-        g = tokenize(BytesIO(s.encode('utf-8')).readline) # tokenize the string
-        for toknum, tokval, _, _, _  in g:
+        g = tokenize(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
+        for toknum, tokval, _, _, _ in g:
             if toknum == NUMBER and '.' in tokval:  # replace NUMBER tokens
                 result.extend([
                     (NAME, 'Decimal'),
index 8d216d0..6ec9ada 100644 (file)
@@ -4,6 +4,9 @@
 .. module:: traceback
    :synopsis: Print or retrieve a stack traceback.
 
+**Source code:** :source:`Lib/traceback.py`
+
+--------------
 
 This module provides a standard interface to extract, format and print stack
 traces of Python programs.  It exactly mimics the behavior of the Python
@@ -20,29 +23,29 @@ the :data:`sys.last_traceback` variable and returned as the third item from
 The module defines the following functions:
 
 
-.. function:: print_tb(traceback, limit=None, file=None)
+.. function:: print_tb(tb, limit=None, file=None)
 
-   Print up to *limit* stack trace entries from *traceback* (starting from
-   the caller's frame) if *limit* is positive.  Otherwise, print the last
-   ``abs(limit)`` entries.  If *limit* is omitted or ``None``, all entries
-   are printed.  If *file* is omitted or ``None``, the output goes to
-   ``sys.stderr``; otherwise it should be an open file or file-like object
-   to receive the output.
+   Print up to *limit* stack trace entries from traceback object *tb* (starting
+   from the caller's frame) if *limit* is positive.  Otherwise, print the last
+   ``abs(limit)`` entries.  If *limit* is omitted or ``None``, all entries are
+   printed.  If *file* is omitted or ``None``, the output goes to
+   ``sys.stderr``; otherwise it should be an open file or file-like object to
+   receive the output.
 
    .. versionchanged:: 3.5
        Added negative *limit* support.
 
 
-.. function:: print_exception(type, value, traceback, limit=None, file=None, chain=True)
+.. function:: print_exception(etype, value, tb, limit=None, file=None, chain=True)
 
-   Print exception information and stack trace entries from
-   *traceback* to *file*. This differs from :func:`print_tb` in the following
+   Print exception information and stack trace entries from traceback object
+   *tb* to *file*. This differs from :func:`print_tb` in the following
    ways:
 
-   * if *traceback* is not ``None``, it prints a header ``Traceback (most recent
+   * if *tb* is not ``None``, it prints a header ``Traceback (most recent
      call last):``
-   * it prints the exception *type* and *value* after the stack trace
-   * if *type* is :exc:`SyntaxError` and *value* has the appropriate format, it
+   * it prints the exception *etype* and *value* after the stack trace
+   * if *etype* is :exc:`SyntaxError` and *value* has the appropriate format, it
      prints the line where the syntax error occurred with a caret indicating the
      approximate position of the error.
 
@@ -80,10 +83,10 @@ The module defines the following functions:
           Added negative *limit* support.
 
 
-.. function:: extract_tb(traceback, limit=None)
+.. function:: extract_tb(tb, limit=None)
 
    Return a list of "pre-processed" stack trace entries extracted from the
-   traceback object *traceback*.  It is useful for alternate formatting of
+   traceback object *tb*.  It is useful for alternate formatting of
    stack traces.  The optional *limit* argument has the same meaning as for
    :func:`print_tb`.  A "pre-processed" stack trace entry is a 4-tuple
    (*filename*, *line number*, *function name*, *text*) representing the
@@ -99,39 +102,40 @@ The module defines the following functions:
    arguments have the same meaning as for :func:`print_stack`.
 
 
-.. function:: format_list(list)
+.. function:: format_list(extracted_list)
 
    Given a list of tuples as returned by :func:`extract_tb` or
-   :func:`extract_stack`, return a list of strings ready for printing.  Each string
-   in the resulting list corresponds to the item with the same index in the
-   argument list.  Each string ends in a newline; the strings may contain internal
-   newlines as well, for those items whose source text line is not ``None``.
+   :func:`extract_stack`, return a list of strings ready for printing. Each
+   string in the resulting list corresponds to the item with the same index in
+   the argument list.  Each string ends in a newline; the strings may contain
+   internal newlines as well, for those items whose source text line is not
+   ``None``.
 
 
-.. function:: format_exception_only(type, value)
+.. function:: format_exception_only(etype, value)
 
-   Format the exception part of a traceback.  The arguments are the exception type
-   and value such as given by ``sys.last_type`` and ``sys.last_value``.  The return
-   value is a list of strings, each ending in a newline.  Normally, the list
-   contains a single string; however, for :exc:`SyntaxError` exceptions, it
-   contains several lines that (when printed) display detailed information about
-   where the syntax error occurred.  The message indicating which exception
-   occurred is the always last string in the list.
+   Format the exception part of a traceback.  The arguments are the exception
+   type and value such as given by ``sys.last_type`` and ``sys.last_value``.
+   The return value is a list of strings, each ending in a newline.  Normally,
+   the list contains a single string; however, for :exc:`SyntaxError`
+   exceptions, it contains several lines that (when printed) display detailed
+   information about where the syntax error occurred.  The message indicating
+   which exception occurred is the always last string in the list.
 
 
-.. function:: format_exception(type, value, tb, limit=None, chain=True)
+.. function:: format_exception(etype, value, tb, limit=None, chain=True)
 
    Format a stack trace and the exception information.  The arguments  have the
    same meaning as the corresponding arguments to :func:`print_exception`.  The
-   return value is a list of strings, each ending in a newline and some containing
-   internal newlines.  When these lines are concatenated and printed, exactly the
-   same text is printed as does :func:`print_exception`.
+   return value is a list of strings, each ending in a newline and some
+   containing internal newlines.  When these lines are concatenated and printed,
+   exactly the same text is printed as does :func:`print_exception`.
 
 
 .. function:: format_exc(limit=None, chain=True)
 
-   This is like ``print_exc(limit)`` but returns a string instead of printing to a
-   file.
+   This is like ``print_exc(limit)`` but returns a string instead of printing to
+   file.
 
 
 .. function:: format_tb(tb, limit=None)
index 861be37..3a0b1e0 100644 (file)
@@ -6,6 +6,10 @@
 
 .. versionadded:: 3.4
 
+**Source code:** :source:`Lib/tracemalloc.py`
+
+--------------
+
 The tracemalloc module is a debug tool to trace memory blocks allocated by
 Python. It provides the following information:
 
@@ -620,7 +624,7 @@ Traceback
       *limit* is set, only format the *limit* most recent frames.
 
       Similar to the :func:`traceback.format_tb` function, except that
-      :meth:`format` does not include newlines.
+      :meth:`.format` does not include newlines.
 
       Example::
 
index d13c6f9..b30bc3c 100644 (file)
@@ -4,9 +4,13 @@
 .. module:: tty
    :platform: Unix
    :synopsis: Utility functions that perform common terminal control operations.
+
 .. moduleauthor:: Steen Lumholt
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 
+**Source code:** :source:`Lib/tty.py`
+
+--------------
 
 The :mod:`tty` module defines functions for putting the tty into cbreak and raw
 modes.
index 30dd6ef..e4a82ea 100644 (file)
@@ -4,13 +4,18 @@
 
 .. module:: turtle
    :synopsis: An educational framework for simple graphics applications
+
 .. sectionauthor:: Gregor Lingl <gregor.lingl@aon.at>
 
+**Source code:** :source:`Lib/turtle.py`
+
 .. testsetup:: default
 
    from turtle import *
    turtle = Turtle()
 
+--------------
+
 Introduction
 ============
 
index eb27846..118bc4c 100644 (file)
@@ -252,10 +252,12 @@ Additional Utility Classes and Functions
        class SimpleNamespace:
            def __init__(self, **kwargs):
                self.__dict__.update(kwargs)
+
            def __repr__(self):
                keys = sorted(self.__dict__)
                items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
                return "{}({})".format(type(self).__name__, ", ".join(items))
+
            def __eq__(self, other):
                return self.__dict__ == other.__dict__
 
index 0fe1167..731e2ec 100644 (file)
@@ -4,6 +4,8 @@
 .. module:: typing
    :synopsis: Support for type hints (see PEP 484).
 
+.. versionadded:: 3.5
+
 **Source code:** :source:`Lib/typing.py`
 
 --------------
@@ -20,7 +22,7 @@ The function below takes and returns a string and is annotated as follows::
    def greeting(name: str) -> str:
        return 'Hello ' + name
 
-In the function ``greeting``, the argument ``name`` is expected to by of type
+In the function ``greeting``, the argument ``name`` is expected to be of type
 :class:`str` and the return type :class:`str`. Subtypes are accepted as
 arguments.
 
@@ -154,7 +156,7 @@ You can use multiple inheritance with :class:`Generic`::
    class LinkedList(Sized, Generic[T]):
        ...
 
-When inheriting from generic classes, some type variables could fixed::
+When inheriting from generic classes, some type variables could be fixed::
 
     from typing import TypeVar, Mapping
 
@@ -286,9 +288,16 @@ The module defines the following classes, functions and decorators:
 
    ``Optional[X]`` is equivalent to ``Union[X, type(None)]``.
 
+   Note that this is not the same concept as an optional argument,
+   which is one that has a default.  An optional argument with a
+   default needn't use the ``Optional`` qualifier on its type
+   annotation (although it is inferred if the default is ``None``).
+   A mandatory argument may still have an ``Optional`` type if an
+   explicit value of ``None`` is allowed.
+
 .. class:: Tuple
 
-  Tuple type; ``Tuple[X, Y]`` is the is the type of a tuple of two items
+  Tuple type; ``Tuple[X, Y]`` is the type of a tuple of two items
   with the first item of type X and the second of type Y.
 
   Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding
@@ -422,9 +431,9 @@ The module defines the following classes, functions and decorators:
       def slice__to_4(vector: Sequence[T]) -> List[T]:
           return vector[0:4]
 
-.. class:: AbstractSet(set, MutableSet[T])
+.. class:: Set(set, MutableSet[T])
 
-   A generic version of :class:`collections.abc.Set`.
+   A generic version of :class:`builtins.set <set>`.
 
 .. class:: MappingView(Sized, Iterable[T_co])
 
index 1430d9b..6cd8132 100644 (file)
@@ -3,16 +3,18 @@
 
 .. module:: unicodedata
    :synopsis: Access the Unicode Database.
+
 .. moduleauthor:: Marc-André Lemburg <mal@lemburg.com>
 .. sectionauthor:: Marc-André Lemburg <mal@lemburg.com>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
 
-
 .. index::
    single: Unicode
    single: character
    pair: Unicode; database
 
+--------------
+
 This module provides access to the Unicode Character Database (UCD) which
 defines character properties for all Unicode characters. The data contained in
 this database is compiled from the `UCD version 8.0.0
index 055abe0..05f3374 100644 (file)
@@ -359,7 +359,7 @@ The module name can be 'dotted', in the form ``package.module`` if needed:
 
 A nice pattern is to actually decorate test methods themselves:
 
-    >>> class MyTest(unittest2.TestCase):
+    >>> class MyTest(unittest.TestCase):
     ...     @patch.object(SomeClass, 'attribute', sentinel.attribute)
     ...     def test_something(self):
     ...         self.assertEqual(SomeClass.attribute, sentinel.attribute)
@@ -372,7 +372,7 @@ If you want to patch with a Mock, you can use :func:`patch` with only one argume
 (or :func:`patch.object` with two arguments). The mock will be created for you and
 passed into the test function / method:
 
-    >>> class MyTest(unittest2.TestCase):
+    >>> class MyTest(unittest.TestCase):
     ...     @patch.object(SomeClass, 'static_method')
     ...     def test_something(self, mock_method):
     ...         SomeClass.static_method()
@@ -382,7 +382,7 @@ passed into the test function / method:
 
 You can stack up multiple patch decorators using this pattern:
 
-    >>> class MyTest(unittest2.TestCase):
+    >>> class MyTest(unittest.TestCase):
     ...     @patch('package.module.ClassName1')
     ...     @patch('package.module.ClassName2')
     ...     def test_something(self, MockClass2, MockClass1):
@@ -549,7 +549,7 @@ Calls to the date constructor are recorded in the ``mock_date`` attributes
 
 An alternative way of dealing with mocking dates, or other builtin classes,
 is discussed in `this blog entry
-<http://www.williamjohnbert.com/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/>`_.
+<https://williambert.online/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/>`_.
 
 
 Mocking a Generator Method
@@ -1010,7 +1010,7 @@ subclass.
 Sometimes this is inconvenient. For example, `one user
 <https://code.google.com/p/mock/issues/detail?id=105>`_ is subclassing mock to
 created a `Twisted adaptor
-<http://twistedmatrix.com/documents/11.0.0/api/twisted.python.components.html>`_.
+<https://twistedmatrix.com/documents/11.0.0/api/twisted.python.components.html>`_.
 Having this applied to attributes too actually causes errors.
 
 ``Mock`` (in all its flavours) uses a method called ``_get_child_mock`` to create
@@ -1251,7 +1251,7 @@ With a bit of tweaking you could have the comparison function raise the
 :exc:`AssertionError` directly and provide a more useful failure message.
 
 As of version 1.5, the Python testing library `PyHamcrest
-<https://pypi.python.org/pypi/PyHamcrest>`_ provides similar functionality,
+<https://pyhamcrest.readthedocs.org/>`_ provides similar functionality,
 that may be useful here, in the form of its equality matcher
 (`hamcrest.library.integration.match_equality
-<http://pythonhosted.org/PyHamcrest/integration.html#hamcrest.library.integration.match_equality.match_equality>`_).
+<https://pyhamcrest.readthedocs.org/en/release-1.8/integration/#module-hamcrest.library.integration.match_equality>`_).
index 9a51194..5c9177a 100644 (file)
@@ -4,11 +4,16 @@
 
 .. module:: unittest.mock
    :synopsis: Mock object library.
+
 .. moduleauthor:: Michael Foord <michael@python.org>
 .. currentmodule:: unittest.mock
 
 .. versionadded:: 3.3
 
+**Source code:** :source:`Lib/unittest/mock.py`
+
+--------------
+
 :mod:`unittest.mock` is a library for testing in Python. It allows you to
 replace parts of your system under test with mock objects and make assertions
 about how they have been used.
@@ -32,8 +37,6 @@ used by many mocking frameworks.
 There is a backport of :mod:`unittest.mock` for earlier versions of Python,
 available as `mock on PyPI <https://pypi.python.org/pypi/mock>`_.
 
-**Source code:** :source:`Lib/unittest/mock.py`
-
 
 Quick Guide
 -----------
@@ -1697,7 +1700,7 @@ Methods and their defaults:
 * ``__ge__``: NotImplemented
 * ``__int__``: 1
 * ``__contains__``: False
-* ``__len__``: 1
+* ``__len__``: 0
 * ``__iter__``: iter([])
 * ``__exit__``: False
 * ``__complex__``: 1j
index ff9cc22..0fc02c4 100644 (file)
@@ -3,11 +3,16 @@
 
 .. module:: unittest
    :synopsis: Unit testing framework for Python.
+
 .. moduleauthor:: Steve Purcell <stephen_purcell@yahoo.com>
 .. sectionauthor:: Steve Purcell <stephen_purcell@yahoo.com>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. sectionauthor:: Raymond Hettinger <python@rcn.com>
 
+**Source code:** :source:`Lib/unittest/__init__.py`
+
+--------------
+
 (If you are already familiar with the basic concepts of testing, you might want
 to skip to :ref:`the list of assert methods <assert-methods>`.)
 
@@ -67,7 +72,7 @@ test runner
    a GUI tool for test discovery and execution.  This is intended largely for ease of use
    for those new to unit testing.  For production environments it is
    recommended that tests be driven by a continuous integration system such as
-   `Buildbot <http://buildbot.net/>`_, `Jenkins <http://jenkins-ci.org/>`_
+   `Buildbot <https://buildbot.net/>`_, `Jenkins <https://jenkins.io/>`_
    or  `Hudson <http://hudson-ci.org/>`_.
 
 
@@ -86,19 +91,19 @@ Here is a short script to test three string methods::
 
   class TestStringMethods(unittest.TestCase):
 
-    def test_upper(self):
-        self.assertEqual('foo'.upper(), 'FOO')
+      def test_upper(self):
+          self.assertEqual('foo'.upper(), 'FOO')
 
-    def test_isupper(self):
-        self.assertTrue('FOO'.isupper())
-        self.assertFalse('Foo'.isupper())
+      def test_isupper(self):
+          self.assertTrue('FOO'.isupper())
+          self.assertFalse('Foo'.isupper())
 
-    def test_split(self):
-        s = 'hello world'
-        self.assertEqual(s.split(), ['hello', 'world'])
-        # check that s.split fails when the separator is not a string
-        with self.assertRaises(TypeError):
-            s.split(2)
+      def test_split(self):
+          s = 'hello world'
+          self.assertEqual(s.split(), ['hello', 'world'])
+          # check that s.split fails when the separator is not a string
+          with self.assertRaises(TypeError):
+              s.split(2)
 
   if __name__ == '__main__':
       unittest.main()
@@ -118,7 +123,7 @@ and produce a report.
 
 The :meth:`~TestCase.setUp` and :meth:`~TestCase.tearDown` methods allow you
 to define instructions that will be executed before and after each test method.
-They are covered in more details in the section :ref:`organizing-tests`.
+They are covered in more detail in the section :ref:`organizing-tests`.
 
 The final block shows a simple way to run the tests. :func:`unittest.main`
 provides a command-line interface to the test script.  When run from the command
@@ -680,10 +685,12 @@ Test cases
       Method called immediately after the test method has been called and the
       result recorded.  This is called even if the test method raised an
       exception, so the implementation in subclasses may need to be particularly
-      careful about checking internal state.  Any exception, other than :exc:`AssertionError`
-      or :exc:`SkipTest`, raised by this method will be considered an error rather than a
-      test failure.  This method will only be called if the :meth:`setUp` succeeds,
-      regardless of the outcome of the test method. The default implementation does nothing.
+      careful about checking internal state.  Any exception, other than
+      :exc:`AssertionError` or :exc:`SkipTest`, raised by this method will be
+      considered an additional error rather than a test failure (thus increasing
+      the total number of reported errors). This method will only be called if
+      the :meth:`setUp` succeeds, regardless of the outcome of the test method.
+      The default implementation does nothing.
 
 
    .. method:: setUpClass()
@@ -762,8 +769,9 @@ Test cases
 
    .. _assert-methods:
 
-   The :class:`TestCase` class provides a number of methods to check for and
-   report failures, such as:
+   The :class:`TestCase` class provides several assert methods to check for and
+   report failures.  The following table lists the most commonly used methods
+   (see the tables below for more assert methods):
 
    +-----------------------------------------+-----------------------------+---------------+
    | Method                                  | Checks that                 | New in        |
@@ -884,7 +892,7 @@ Test cases
 
 
 
-   It is also possible to check the production of exceptions, warnings and
+   It is also possible to check the production of exceptions, warnings, and
    log messages using the following methods:
 
    +---------------------------------------------------------+--------------------------------------+------------+
index f7f0c97..5517b04 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: urllib.error
    :synopsis: Exception classes raised by urllib.request.
+
 .. moduleauthor:: Jeremy Hylton <jeremy@alum.mit.edu>
 .. sectionauthor:: Senthil Kumaran <orsenthil@gmail.com>
 
+**Source code:** :source:`Lib/urllib/error.py`
+
+--------------
 
 The :mod:`urllib.error` module defines the exception classes for exceptions
 raised by :mod:`urllib.request`.  The base exception class is :exc:`URLError`.
index 40098d0..c6de230 100644 (file)
@@ -4,6 +4,7 @@
 .. module:: urllib.parse
    :synopsis: Parse URLs into or assemble them from components.
 
+**Source code:** :source:`Lib/urllib/parse.py`
 
 .. index::
    single: WWW
@@ -12,8 +13,6 @@
    pair: URL; parsing
    pair: relative; URL
 
-**Source code:** :source:`Lib/urllib/parse.py`
-
 --------------
 
 This module defines a standard interface to break Uniform Resource Locator (URL)
@@ -525,10 +524,11 @@ task isn't already covered by the URL parsing functions above.
                         errors=None, quote_via=quote_plus)
 
    Convert a mapping object or a sequence of two-element tuples, which may
-   contain :class:`str` or :class:`bytes` objects, to a "percent-encoded"
-   string.  If the resultant string is to be used as a *data* for POST
-   operation with :func:`~urllib.request.urlopen` function, then it should be
-   properly encoded to bytes, otherwise it would result in a :exc:`TypeError`.
+   contain :class:`str` or :class:`bytes` objects, to a percent-encoded ASCII
+   text string.  If the resultant string is to be used as a *data* for POST
+   operation with the :func:`~urllib.request.urlopen` function, then
+   it should be encoded to bytes, otherwise it would result in a
+   :exc:`TypeError`.
 
    The resulting string is a series of ``key=value`` pairs separated by ``'&'``
    characters, where both *key* and *value* are quoted using the *quote_via*
@@ -581,7 +581,7 @@ task isn't already covered by the URL parsing functions above.
       Names (URNs) and Uniform Resource Locators (URLs).
 
    :rfc:`2368` - The mailto URL scheme.
-      Parsing requirements for mailto url schemes.
+      Parsing requirements for mailto URL schemes.
 
    :rfc:`1808` - Relative Uniform Resource Locators
       This Request For Comments includes the rules for joining an absolute and a
index 8755155..1338906 100644 (file)
@@ -3,10 +3,14 @@
 
 .. module:: urllib.request
    :synopsis: Extensible library for opening URLs.
+
 .. moduleauthor:: Jeremy Hylton <jeremy@alum.mit.edu>
 .. sectionauthor:: Moshe Zadka <moshez@users.sourceforge.net>
 .. sectionauthor:: Senthil Kumaran <senthil@uthcode.com>
 
+**Source code:** :source:`Lib/urllib/request.py`
+
+--------------
 
 The :mod:`urllib.request` module defines functions and classes which help in
 opening URLs (mostly HTTP) in a complex world --- basic and digest
@@ -14,8 +18,8 @@ authentication, redirections, cookies and more.
 
 .. seealso::
 
-    The `Requests package <http://requests.readthedocs.org/>`_
-    is recommended for a higher-level http client interface.
+    The `Requests package <https://requests.readthedocs.org/>`_
+    is recommended for a higher-level HTTP client interface.
 
 
 The :mod:`urllib.request` module defines the following functions:
@@ -36,13 +40,8 @@ The :mod:`urllib.request` module defines the following functions:
    *data* should be a buffer in the standard
    :mimetype:`application/x-www-form-urlencoded` format.  The
    :func:`urllib.parse.urlencode` function takes a mapping or sequence of
-   2-tuples and returns a string in this format. It should be encoded to bytes
-   before being used as the *data* parameter. The charset parameter in
-   ``Content-Type`` header may be used to specify the encoding. If charset
-   parameter is not sent with the Content-Type header, the server following the
-   HTTP 1.1 recommendation may assume that the data is encoded in ISO-8859-1
-   encoding. It is advisable to use charset parameter with encoding used in
-   ``Content-Type`` header with the :class:`Request`.
+   2-tuples and returns an ASCII text string in this format. It should
+   be encoded to bytes before being used as the *data* parameter.
 
    urllib.request module uses HTTP/1.1 and includes ``Connection:close`` header
    in its HTTP requests.
@@ -64,13 +63,7 @@ The :mod:`urllib.request` module defines the following functions:
 
    The *cadefault* parameter is ignored.
 
-   For http and https urls, this function returns a
-   :class:`http.client.HTTPResponse` object which has the following
-   :ref:`httpresponse-objects` methods.
-
-   For ftp, file, and data urls and requests explicitly handled by legacy
-   :class:`URLopener` and :class:`FancyURLopener` classes, this function
-   returns a :class:`urllib.response.addinfourl` object which can work as
+   This function always returns an object which can work as a
    :term:`context manager` and has methods such as
 
    * :meth:`~urllib.response.addinfourl.geturl` --- return the URL of the resource retrieved,
@@ -78,11 +71,23 @@ The :mod:`urllib.request` module defines the following functions:
 
    * :meth:`~urllib.response.addinfourl.info` --- return the meta-information of the page, such as headers,
      in the form of an :func:`email.message_from_string` instance (see
-     `Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_)
+     `Quick Reference to HTTP Headers <https://www.cs.tut.fi/~jkorpela/http.html>`_)
 
    * :meth:`~urllib.response.addinfourl.getcode` -- return the HTTP status code of the response.
 
-   Raises :exc:`~urllib.error.URLError` on errors.
+   For HTTP and HTTPS URLs, this function returns a
+   :class:`http.client.HTTPResponse` object slightly modified. In addition
+   to the three new methods above, the msg attribute contains the
+   same information as the :attr:`~http.client.HTTPResponse.reason`
+   attribute --- the reason phrase returned by server --- instead of
+   the response headers as it is specified in the documentation for
+   :class:`~http.client.HTTPResponse`.
+
+   For FTP, file, and data URLs and requests explicitly handled by legacy
+   :class:`URLopener` and :class:`FancyURLopener` classes, this function
+   returns a :class:`urllib.response.addinfourl` object.
+
+   Raises :exc:`~urllib.error.URLError` on protocol errors.
 
    Note that ``None`` may be returned if no handler handles the request (though
    the default installed global :class:`OpenerDirector` uses
@@ -165,6 +170,8 @@ The :mod:`urllib.request` module defines the following functions:
    in a case insensitive approach, for all operating systems first, and when it
    cannot find it, looks for proxy information from Mac OSX System
    Configuration for Mac OS X and Windows Systems Registry for Windows.
+   If both lowercase and uppercase environment variables exist (and disagree),
+   lowercase is preferred.
 
 
 The following classes are provided:
@@ -180,20 +187,13 @@ The following classes are provided:
    the only ones that use *data*; the HTTP request will be a POST instead of a
    GET when the *data* parameter is provided.  *data* should be a buffer in the
    standard :mimetype:`application/x-www-form-urlencoded` format.
-
    The :func:`urllib.parse.urlencode` function takes a mapping or sequence of
-   2-tuples and returns a string in this format. It should be encoded to bytes
-   before being used as the *data* parameter. The charset parameter in
-   ``Content-Type`` header may be used to specify the encoding. If charset
-   parameter is not sent with the Content-Type header, the server following the
-   HTTP 1.1 recommendation may assume that the data is encoded in ISO-8859-1
-   encoding. It is advisable to use charset parameter with encoding used in
-   ``Content-Type`` header with the :class:`Request`.
-
+   2-tuples and returns an ASCII string in this format. It should be
+   encoded to bytes before being used as the *data* parameter.
 
    *headers* should be a dictionary, and will be treated as if
    :meth:`add_header` was called with each key and value as arguments.
-   This is often used to "spoof" the ``User-Agent`` header, which is
+   This is often used to "spoof" the ``User-Agent`` header value, which is
    used by a browser to identify itself -- some HTTP servers only
    allow requests coming from common browsers as opposed to scripts.
    For example, Mozilla Firefox may identify itself as ``"Mozilla/5.0
@@ -202,7 +202,7 @@ The following classes are provided:
    ``"Python-urllib/2.6"`` (on Python 2.6).
 
    An example of using ``Content-Type`` header with *data* argument would be
-   sending a dictionary like ``{"Content-Type":" application/x-www-form-urlencoded;charset=utf-8"}``.
+   sending a dictionary like ``{"Content-Type": "application/x-www-form-urlencoded"}``.
 
    The final two arguments are only of interest for correct handling
    of third-party HTTP cookies:
@@ -275,6 +275,11 @@ The following classes are provided:
 
    To disable autodetected proxy pass an empty dictionary.
 
+   The :envvar:`no_proxy` environment variable can be used to specify hosts
+   which shouldn't be reached via proxy; if set, it should be a comma-separated
+   list of hostname suffixes, optionally with ``:port`` appended, for example
+   ``cern.ch,ncsa.uiuc.edu,some.host:8080``.
+
 
 .. class:: HTTPPasswordMgr()
 
@@ -452,7 +457,7 @@ request.
 .. attribute:: Request.selector
 
    The URI path.  If the :class:`Request` uses a proxy, then selector
-   will be the full url that is passed to the proxy.
+   will be the full URL that is passed to the proxy.
 
 .. attribute:: Request.data
 
@@ -771,8 +776,8 @@ HTTPRedirectHandler Objects
    details of the precise meanings of the various redirection codes.
 
    An :class:`HTTPError` exception raised as a security consideration if the
-   HTTPRedirectHandler is presented with a redirected url which is not an HTTP,
-   HTTPS or FTP url.
+   HTTPRedirectHandler is presented with a redirected URL which is not an HTTP,
+   HTTPS or FTP URL.
 
 
 .. method:: HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)
@@ -1110,6 +1115,9 @@ HTTPErrorProcessor Objects
 Examples
 --------
 
+In addition to the examples below, more examples are given in
+:ref:`urllib-howto`.
+
 This example gets the python.org main page and displays the first 300 bytes of
 it. ::
 
@@ -1125,11 +1133,11 @@ it. ::
 
 Note that urlopen returns a bytes object.  This is because there is no way
 for urlopen to automatically determine the encoding of the byte stream
-it receives from the http server. In general, a program will decode
+it receives from the HTTP server. In general, a program will decode
 the returned bytes object to string once it determines or guesses
 the appropriate encoding.
 
-The following W3C document, http://www.w3.org/International/O-charset\ , lists
+The following W3C document, https://www.w3.org/International/O-charset\ , lists
 the various ways in which a (X)HTML or a XML document could have specified its
 encoding information.
 
@@ -1173,7 +1181,7 @@ The code for the sample CGI used in the above example is::
 Here is an example of doing a ``PUT`` request using :class:`Request`::
 
     import urllib.request
-    DATA=b'some data'
+    DATA = b'some data'
     req = urllib.request.Request(url='http://localhost:8080', data=DATA,method='PUT')
     with urllib.request.urlopen(req) as f:
         pass
@@ -1219,6 +1227,8 @@ Use the *headers* argument to the :class:`Request` constructor, or::
    import urllib.request
    req = urllib.request.Request('http://www.example.com/')
    req.add_header('Referer', 'http://www.python.org/')
+   # Customize the default User-Agent header value:
+   req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)')
    r = urllib.request.urlopen(req)
 
 :class:`OpenerDirector` automatically adds a :mailheader:`User-Agent` header to
@@ -1230,7 +1240,7 @@ every :class:`Request`.  To change this::
    opener.open('http://www.example.com/')
 
 Also, remember that a few standard headers (:mailheader:`Content-Length`,
-:mailheader:`Content-Type` without charset parameter and :mailheader:`Host`)
+:mailheader:`Content-Type` and :mailheader:`Host`)
 are added when the :class:`Request` is passed to :func:`urlopen` (or
 :meth:`OpenerDirector.open`).
 
@@ -1253,11 +1263,8 @@ from urlencode is encoded to bytes before it is sent to urlopen as data::
    >>> import urllib.request
    >>> import urllib.parse
    >>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
-   >>> data = data.encode('utf-8')
-   >>> request = urllib.request.Request("http://requestb.in/xrbl82xr")
-   >>> # adding charset parameter to the Content-Type header.
-   >>> request.add_header("Content-Type","application/x-www-form-urlencoded;charset=utf-8")
-   >>> with urllib.request.urlopen(request, data) as f:
+   >>> data = data.encode('ascii')
+   >>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as f:
    ...     print(f.read().decode('utf-8'))
    ...
 
index f179de2..ba701c3 100644 (file)
@@ -4,8 +4,10 @@
 .. module:: urllib.robotparser
    :synopsis: Load a robots.txt file and answer questions about
               fetchability of other URLs.
+
 .. sectionauthor:: Skip Montanaro <skip@pobox.com>
 
+**Source code:** :source:`Lib/urllib/robotparser.py`
 
 .. index::
    single: WWW
@@ -13,6 +15,8 @@
    single: URL
    single: robots.txt
 
+--------------
+
 This module provides a single class, :class:`RobotFileParser`, which answers
 questions about whether or not a particular user agent can fetch a URL on the
 Web site that published the :file:`robots.txt` file.  For more details on the
index 8e308bc..624e164 100644 (file)
@@ -3,6 +3,10 @@
 
 .. module:: urllib
 
+**Source code:** :source:`Lib/urllib/`
+
+--------------
+
 ``urllib`` is a package that collects several modules for working with URLs:
 
 * :mod:`urllib.request` for opening and reading URLs
index d61c178..33fb36d 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: uu
    :synopsis: Encode and decode files in uuencode format.
+
 .. moduleauthor:: Lance Ellinghouse
 
 **Source code:** :source:`Lib/uu.py`
index 7dc46ac..53cbd6c 100644 (file)
@@ -6,6 +6,9 @@
 .. moduleauthor:: Ka-Ping Yee <ping@zesty.ca>
 .. sectionauthor:: George Yoshida <quiver@users.sourceforge.net>
 
+**Source code:** :source:`Lib/uuid.py`
+
+--------------
 
 This module provides immutable :class:`UUID` objects (the :class:`UUID` class)
 and the functions :func:`uuid1`, :func:`uuid3`, :func:`uuid4`, :func:`uuid5` for
index e9ede8b..af4a6d1 100644 (file)
@@ -3,15 +3,15 @@
 
 .. module:: venv
    :synopsis: Creation of virtual environments.
+
 .. moduleauthor:: Vinay Sajip <vinay_sajip@yahoo.co.uk>
 .. sectionauthor:: Vinay Sajip <vinay_sajip@yahoo.co.uk>
 
-
-.. index:: pair: Environments; virtual
-
 .. versionadded:: 3.3
 
-**Source code:** :source:`Lib/venv`
+**Source code:** :source:`Lib/venv/`
+
+.. index:: pair: Environments; virtual
 
 --------------
 
@@ -43,11 +43,6 @@ Creating virtual environments
    Common installation tools such as ``Setuptools`` and ``pip`` work as
    expected with venvs - i.e. when a venv is active, they install Python
    packages into the venv without needing to be told to do so explicitly.
-   Of course, you need to install them into the venv first: this could be
-   done by running ``ez_setup.py`` with the venv activated,
-   followed by running ``easy_install pip``. Alternatively, you could download
-   the source tarballs and run ``python setup.py install`` after unpacking,
-   with the venv activated.
 
    When a venv is active (i.e. the venv's Python interpreter is running), the
    attributes :attr:`sys.prefix` and :attr:`sys.exec_prefix` point to the base
index 8a538ad..5212131 100644 (file)
@@ -1,13 +1,13 @@
 :mod:`warnings` --- Warning control
 ===================================
 
-.. index:: single: warnings
-
 .. module:: warnings
    :synopsis: Issue warning messages and control their disposition.
 
 **Source code:** :source:`Lib/warnings.py`
 
+.. index:: single: warnings
+
 --------------
 
 Warning messages are typically issued in situations where it is useful to alert
@@ -265,7 +265,7 @@ Updating Code For New Versions of Python
 
 Warnings that are only of interest to the developer are ignored by default. As
 such you should make sure to test your code with typically ignored warnings
-made visible. You can do this from the command-line by passing :option:`-Wd`
+made visible. You can do this from the command-line by passing :option:`-Wd <-W>`
 to the interpreter (this is shorthand for :option:`-W default`).  This enables
 default handling for all warnings, including those that are ignored by default.
 To change what action is taken for encountered warnings you simply change what
index ab64978..7144379 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: wave
    :synopsis: Provide an interface to the WAV sound format.
+
 .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
 .. Documentations stolen from comments in file.
 
index 2e16077..0470bd1 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: weakref
    :synopsis: Support for weak references and weak dictionaries.
+
 .. moduleauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. moduleauthor:: Neil Schemenauer <nas@arctrix.com>
 .. moduleauthor:: Martin von Löwis <martin@loewis.home.cs.tu-berlin.de>
@@ -329,7 +330,7 @@ These method have the same issues as the and :meth:`keyrefs` method of
 
 .. seealso::
 
-   :pep:`0205` - Weak References
+   :pep:`205` - Weak References
       The proposal and rationale for this feature, including links to earlier
       implementations and information about similar features in other languages.
 
index aa5e4ad..85d3636 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: webbrowser
    :synopsis: Easy-to-use controller for Web browsers.
+
 .. moduleauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
@@ -33,7 +34,7 @@ browsers are not available on Unix, the controlling process will launch a new
 browser and wait.
 
 The script :program:`webbrowser` can be used as a command-line interface for the
-module. It accepts an URL as the argument. It accepts the following optional
+module. It accepts a URL as the argument. It accepts the following optional
 parameters: ``-n`` opens the URL in a new browser window, if possible;
 ``-t`` opens the URL in a new browser page ("tab"). The options are,
 naturally, mutually exclusive.  Usage example::
index 6c920b4..52d591a 100644 (file)
@@ -4,8 +4,10 @@
 .. module:: winreg
    :platform: Windows
    :synopsis: Routines and objects for manipulating the Windows registry.
+
 .. sectionauthor:: Mark Hammond <MarkH@ActiveState.com>
 
+--------------
 
 These functions expose the Windows registry API to Python.  Instead of using an
 integer as the registry handle, a :ref:`handle object <handle-object>` is used
@@ -134,7 +136,7 @@ This module offers the following functions:
       The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx
       Windows API function, which is specific to 64-bit versions of Windows.
       See the `RegDeleteKeyEx documentation
-      <http://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx>`__.
+      <https://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx>`__.
 
    *key* is an already open key, or one of the predefined
    :ref:`HKEY_* constants <hkey-constants>`.
@@ -268,7 +270,7 @@ This module offers the following functions:
    A call to :func:`LoadKey` fails if the calling process does not have the
    :const:`SE_RESTORE_PRIVILEGE` privilege.  Note that privileges are different
    from permissions -- see the `RegLoadKey documentation
-   <http://msdn.microsoft.com/en-us/library/ms724889%28v=VS.85%29.aspx>`__ for
+   <https://msdn.microsoft.com/en-us/library/ms724889%28v=VS.85%29.aspx>`__ for
    more details.
 
    If *key* is a handle returned by :func:`ConnectRegistry`, then the path
@@ -383,7 +385,7 @@ This module offers the following functions:
    possess the :const:`SeBackupPrivilege` security privilege.  Note that
    privileges are different than permissions -- see the
    `Conflicts Between User Rights and Permissions documentation
-   <http://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx>`__
+   <https://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx>`__
    for more details.
 
    This function passes NULL for *security_attributes* to the API.
@@ -547,7 +549,7 @@ Access Rights
 +++++++++++++
 
 For more information, see `Registry Key Security and Access
-<http://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx>`__.
+<https://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx>`__.
 
 .. data:: KEY_ALL_ACCESS
 
@@ -602,7 +604,7 @@ For more information, see `Registry Key Security and Access
 ***************
 
 For more information, see `Accessing an Alternate Registry View
-<http://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx>`__.
+<https://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx>`__.
 
 .. data:: KEY_WOW64_64KEY
 
@@ -621,7 +623,7 @@ Value Types
 +++++++++++
 
 For more information, see `Registry Value Types
-<http://msdn.microsoft.com/en-us/library/ms724884%28v=VS.85%29.aspx>`__.
+<https://msdn.microsoft.com/en-us/library/ms724884%28v=VS.85%29.aspx>`__.
 
 .. data:: REG_BINARY
 
index 61f34cd..d2c4210 100644 (file)
@@ -4,9 +4,11 @@
 .. module:: winsound
    :platform: Windows
    :synopsis: Access to the sound-playing machinery for Windows.
+
 .. moduleauthor:: Toby Dickenson <htrd90@zepler.org>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
+--------------
 
 The :mod:`winsound` module provides access to the basic sound-playing machinery
 provided by Windows platforms.  It includes functions and several constants.
index 8c091f6..aad27a8 100644 (file)
@@ -3,9 +3,11 @@
 
 .. module:: wsgiref
    :synopsis: WSGI Utilities and Reference Implementation.
+
 .. moduleauthor:: Phillip J. Eby <pje@telecommunity.com>
 .. sectionauthor:: Phillip J. Eby <pje@telecommunity.com>
 
+--------------
 
 The Web Server Gateway Interface (WSGI) is a standard interface between web
 server software and web applications written in Python. Having a standard
@@ -24,8 +26,8 @@ for implementing WSGI servers, a demo HTTP server that serves WSGI applications,
 and a validation tool that checks WSGI servers and applications for conformance
 to the WSGI specification (:pep:`3333`).
 
-See http://www.wsgi.org for more information about WSGI, and links to tutorials
-and other resources.
+See https://wsgi.readthedocs.org/ for more information about WSGI, and links to
+tutorials and other resources.
 
 .. XXX If you're just trying to write a web application...
 
@@ -419,8 +421,8 @@ Paste" library.
       # Our callable object which is intentionally not compliant to the
       # standard, so the validator is going to break
       def simple_app(environ, start_response):
-          status = '200 OK' # HTTP Status
-          headers = [('Content-type', 'text/plain')] # HTTP Headers
+          status = '200 OK'  # HTTP Status
+          headers = [('Content-type', 'text/plain')]  # HTTP Headers
           start_response(status, headers)
 
           # This is going to break because we need to return a list, and
@@ -515,6 +517,9 @@ input, output, and error streams.
    streams are stored in the :attr:`stdin`, :attr:`stdout`, :attr:`stderr`, and
    :attr:`environ` attributes.
 
+   The :meth:`~io.BufferedIOBase.write` method of *stdout* should write
+   each chunk in full, like :class:`io.BufferedIOBase`.
+
 
 .. class:: BaseHandler()
 
@@ -762,8 +767,8 @@ This is a working "Hello World" WSGI application::
    # is a dictionary containing CGI-style environment variables and the
    # second variable is the callable object (see PEP 333).
    def hello_world_app(environ, start_response):
-       status = '200 OK' # HTTP Status
-       headers = [('Content-type', 'text/plain; charset=utf-8')] # HTTP Headers
+       status = '200 OK'  # HTTP Status
+       headers = [('Content-type', 'text/plain; charset=utf-8')]  # HTTP Headers
        start_response(status, headers)
 
        # The returned object is going to be printed
index 5c7dfa4..42a03a4 100644 (file)
@@ -4,13 +4,12 @@
 .. module:: xdrlib
    :synopsis: Encoders and decoders for the External Data Representation (XDR).
 
+**Source code:** :source:`Lib/xdrlib.py`
 
 .. index::
    single: XDR
    single: External Data Representation
 
-**Source code:** :source:`Lib/xdrlib.py`
-
 --------------
 
 The :mod:`xdrlib` module supports the External Data Representation Standard as
index 6762e91..e1042e7 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: xml.dom.minidom
    :synopsis: Minimal Document Object Model (DOM) implementation.
+
 .. moduleauthor:: Paul Prescod <paul@prescod.net>
 .. sectionauthor:: Paul Prescod <paul@prescod.net>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
@@ -30,10 +31,10 @@ DOM applications typically start by parsing some XML into a DOM.  With
 
    from xml.dom.minidom import parse, parseString
 
-   dom1 = parse('c:\\temp\\mydata.xml') # parse an XML file by name
+   dom1 = parse('c:\\temp\\mydata.xml')  # parse an XML file by name
 
    datasource = open('c:\\temp\\mydata.xml')
-   dom2 = parse(datasource)   # parse an open file
+   dom2 = parse(datasource)  # parse an open file
 
    dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')
 
@@ -100,7 +101,7 @@ eventually take care of the objects in the tree.
 
 .. seealso::
 
-   `Document Object Model (DOM) Level 1 Specification <http://www.w3.org/TR/REC-DOM-Level-1/>`_
+   `Document Object Model (DOM) Level 1 Specification <https://www.w3.org/TR/REC-DOM-Level-1/>`_
       The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`.
 
 
@@ -251,5 +252,5 @@ utility to most DOM users.
    the appropriate standards. For example, "UTF-8" is valid, but
    "UTF8" is not valid in an XML document's declaration, even though
    Python accepts it as an encoding name.
-   See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl
-   and http://www.iana.org/assignments/character-sets/character-sets.xhtml.
+   See https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl
+   and https://www.iana.org/assignments/character-sets/character-sets.xhtml.
index a3b8bc1..c3339ed 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: xml.dom.pulldom
    :synopsis: Support for building partial DOM trees from SAX events.
+
 .. moduleauthor:: Paul Prescod <paul@prescod.net>
 
 **Source code:** :source:`Lib/xml/dom/pulldom.py`
@@ -114,13 +115,15 @@ DOMEventStream Objects
 
       Expands all children of *node* into *node*. Example::
 
+          from xml.dom import pulldom
+
           xml = '<html><title>Foo</title> <p>Some text <div>and more</div></p> </html>'
           doc = pulldom.parseString(xml)
           for event, node in doc:
               if event == pulldom.START_ELEMENT and node.tagName == 'p':
                   # Following statement only prints '<p/>'
                   print(node.toxml())
-                  doc.exandNode(node)
+                  doc.expandNode(node)
                   # Following statement prints node with all its children '<p>Some text <div>and more</div></p>'
                   print(node.toxml())
 
index a432202..b037ff6 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: xml.dom
    :synopsis: Document Object Model API for Python.
+
 .. sectionauthor:: Paul Prescod <paul@prescod.net>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
 
+**Source code:** :source:`Lib/xml/dom/__init__.py`
+
+--------------
 
 The Document Object Model, or "DOM," is a cross-language API from the World Wide
 Web Consortium (W3C) for accessing and modifying XML documents.  A DOM
@@ -63,10 +67,10 @@ implementations are free to support the strict mapping from IDL).  See section
 
 .. seealso::
 
-   `Document Object Model (DOM) Level 2 Specification <http://www.w3.org/TR/DOM-Level-2-Core/>`_
+   `Document Object Model (DOM) Level 2 Specification <https://www.w3.org/TR/DOM-Level-2-Core/>`_
       The W3C recommendation upon which the Python DOM API is based.
 
-   `Document Object Model (DOM) Level 1 Specification <http://www.w3.org/TR/REC-DOM-Level-1/>`_
+   `Document Object Model (DOM) Level 1 Specification <https://www.w3.org/TR/REC-DOM-Level-1/>`_
       The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`.
 
    `Python Language Mapping Specification <http://www.omg.org/spec/PYTH/1.2/PDF>`_
@@ -115,20 +119,20 @@ Some convenience constants are also provided:
 .. data:: XML_NAMESPACE
 
    The namespace URI associated with the reserved prefix ``xml``, as defined by
-   `Namespaces in XML <http://www.w3.org/TR/REC-xml-names/>`_ (section 4).
+   `Namespaces in XML <https://www.w3.org/TR/REC-xml-names/>`_ (section 4).
 
 
 .. data:: XMLNS_NAMESPACE
 
    The namespace URI for namespace declarations, as defined by `Document Object
    Model (DOM) Level 2 Core Specification
-   <http://www.w3.org/TR/DOM-Level-2-Core/core.html>`_ (section 1.1.8).
+   <https://www.w3.org/TR/DOM-Level-2-Core/core.html>`_ (section 1.1.8).
 
 
 .. data:: XHTML_NAMESPACE
 
    The URI of the XHTML namespace as defined by `XHTML 1.0: The Extensible
-   HyperText Markup Language <http://www.w3.org/TR/xhtml1/>`_ (section 3.1.1).
+   HyperText Markup Language <https://www.w3.org/TR/xhtml1/>`_ (section 3.1.1).
 
 
 In addition, :mod:`xml.dom` contains a base :class:`Node` class and the DOM
@@ -874,7 +878,7 @@ attribute.
 .. exception:: NamespaceErr
 
    If an attempt is made to change any object in a way that is not permitted with
-   regard to the `Namespaces in XML <http://www.w3.org/TR/REC-xml-names/>`_
+   regard to the `Namespaces in XML <https://www.w3.org/TR/REC-xml-names/>`_
    recommendation, this exception is raised.
 
 
index dc0274e..99d7e8b 100644 (file)
@@ -3,8 +3,13 @@
 
 .. module:: xml.etree.ElementTree
    :synopsis: Implementation of the ElementTree API.
+
 .. moduleauthor:: Fredrik Lundh <fredrik@pythonware.com>
 
+**Source code:** :source:`Lib/xml/etree/ElementTree.py`
+
+--------------
+
 The :mod:`xml.etree.ElementTree` module implements a simple and efficient API
 for parsing and creating XML data.
 
@@ -94,7 +99,7 @@ As an :class:`Element`, ``root`` has a tag and a dictionary of attributes::
 It also has children nodes over which we can iterate::
 
    >>> for child in root:
-   ...   print(child.tag, child.attrib)
+   ...     print(child.tag, child.attrib)
    ...
    country {'name': 'Liechtenstein'}
    country {'name': 'Singapore'}
@@ -143,8 +148,8 @@ elements, call :meth:`XMLPullParser.read_events`.  Here is an example::
    [('start', <Element 'mytag' at 0x7fa66db2be58>)]
    >>> parser.feed(' more text</mytag>')
    >>> for event, elem in parser.read_events():
-   ...   print(event)
-   ...   print(elem.tag, 'text=', elem.text)
+   ...     print(event)
+   ...     print(elem.tag, 'text=', elem.text)
    ...
    end
 
@@ -166,7 +171,7 @@ the sub-tree below it (its children, their children, and so on).  For example,
 :meth:`Element.iter`::
 
    >>> for neighbor in root.iter('neighbor'):
-   ...   print(neighbor.attrib)
+   ...     print(neighbor.attrib)
    ...
    {'name': 'Austria', 'direction': 'E'}
    {'name': 'Switzerland', 'direction': 'W'}
@@ -180,9 +185,9 @@ with a particular tag, and :attr:`Element.text` accesses the element's text
 content.  :meth:`Element.get` accesses the element's attributes::
 
    >>> for country in root.findall('country'):
-   ...   rank = country.find('rank').text
-   ...   name = country.get('name')
-   ...   print(name, rank)
+   ...     rank = country.find('rank').text
+   ...     name = country.get('name')
+   ...     print(name, rank)
    ...
    Liechtenstein 1
    Singapore 4
@@ -206,9 +211,9 @@ Let's say we want to add one to each country's rank, and add an ``updated``
 attribute to the rank element::
 
    >>> for rank in root.iter('rank'):
-   ...   new_rank = int(rank.text) + 1
-   ...   rank.text = str(new_rank)
-   ...   rank.set('updated', 'yes')
+   ...     new_rank = int(rank.text) + 1
+   ...     rank.text = str(new_rank)
+   ...     rank.set('updated', 'yes')
    ...
    >>> tree.write('output.xml')
 
@@ -244,9 +249,9 @@ We can remove elements using :meth:`Element.remove`.  Let's say we want to
 remove all countries with a rank higher than 50::
 
    >>> for country in root.findall('country'):
-   ...   rank = int(country.find('rank').text)
-   ...   if rank > 50:
-   ...     root.remove(country)
+   ...     rank = int(country.find('rank').text)
+   ...     if rank > 50:
+   ...         root.remove(country)
    ...
    >>> tree.write('output.xml')
 
@@ -292,7 +297,7 @@ If the XML input has `namespaces
 with prefixes in the form ``prefix:sometag`` get expanded to
 ``{uri}sometag`` where the *prefix* is replaced by the full *URI*.
 Also, if there is a `default namespace
-<http://www.w3.org/TR/2006/REC-xml-names-20060816/#defaulting>`__,
+<https://www.w3.org/TR/2006/REC-xml-names-20060816/#defaulting>`__,
 that full URI gets prepended to all of the non-prefixed tags.
 
 Here is an XML example that incorporates two namespaces, one with the
@@ -363,7 +368,7 @@ XPath support
 -------------
 
 This module provides limited support for
-`XPath expressions <http://www.w3.org/TR/xpath>`_ for locating elements in a
+`XPath expressions <https://www.w3.org/TR/xpath>`_ for locating elements in a
 tree.  The goal is to support a small subset of the abbreviated syntax; a full
 XPath engine is outside the scope of the module.
 
@@ -978,7 +983,7 @@ QName Objects
    to get proper namespace handling on output.  *text_or_uri* is a string
    containing the QName value, in the form {uri}local, or, if the tag argument
    is given, the URI part of a QName.  If *tag* is given, the first argument is
-   interpreted as an URI, and this argument is interpreted as a local name.
+   interpreted as a URI, and this argument is interpreted as a local name.
    :class:`QName` instances are opaque.
 
 
@@ -1044,16 +1049,16 @@ XMLParser Objects
 
    This class is the low-level building block of the module.  It uses
    :mod:`xml.parsers.expat` for efficient, event-based parsing of XML.  It can
-   be fed XML data incrementall with the :meth:`feed` method, and parsing events
-   are translated to a push API - by invoking callbacks on the *target* object.
-   If *target* is omitted, the standard :class:`TreeBuilder` is used.  The
-   *html* argument was historically used for backwards compatibility and is now
-   deprecated.  If *encoding* [1]_ is given, the value overrides the encoding
-   specified in the XML file.
+   be fed XML data incrementally with the :meth:`feed` method, and parsing
+   events are translated to a push API - by invoking callbacks on the *target*
+   object.  If *target* is omitted, the standard :class:`TreeBuilder` is used.
+   The *html* argument was historically used for backwards compatibility and is
+   now deprecated.  If *encoding* [1]_ is given, the value overrides the
+   encoding specified in the XML file.
 
    .. deprecated:: 3.4
       The *html* argument.  The remaining arguments should be passed via
-      keywword to prepare for the removal of the *html* argument.
+      keyword to prepare for the removal of the *html* argument.
 
    .. method:: close()
 
@@ -1189,5 +1194,5 @@ Exceptions
 
 .. [#] The encoding string included in XML output should conform to the
    appropriate standards.  For example, "UTF-8" is valid, but "UTF8" is
-   not.  See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl
-   and http://www.iana.org/assignments/character-sets/character-sets.xhtml.
+   not.  See https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl
+   and https://www.iana.org/assignments/character-sets/character-sets.xhtml.
index 0188219..3c2fc89 100644 (file)
@@ -5,9 +5,13 @@ XML Processing Modules
 
 .. module:: xml
    :synopsis: Package containing XML processing modules
+
 .. sectionauthor:: Christian Heimes <christian@python.org>
 .. sectionauthor:: Georg Brandl <georg@python.org>
 
+**Source code:** :source:`Lib/xml/`
+
+--------------
 
 Python's interfaces for processing XML are grouped in the ``xml`` package.
 
@@ -62,7 +66,7 @@ kind                       sax       etree      minidom    pulldom   xmlrpc
 billion laughs             **Yes**   **Yes**    **Yes**    **Yes**   **Yes**
 quadratic blowup           **Yes**   **Yes**    **Yes**    **Yes**   **Yes**
 external entity expansion  **Yes**   No    (1)  No    (2)  **Yes**   No    (3)
-DTD retrieval              **Yes**   No         No         **Yes**   No
+`DTD`_ retrieval           **Yes**   No         No         **Yes**   No
 decompression bomb         No        No         No         No        **Yes**
 =========================  ========  =========  =========  ========  =========
 
@@ -92,7 +96,7 @@ external entity expansion
   also point to external resources or local files. The XML
   parser accesses the resource and embeds the content into the XML document.
 
-DTD retrieval
+`DTD`_ retrieval
   Some XML libraries like Python's :mod:`xml.dom.pulldom` retrieve document type
   definitions from remote or local locations. The feature has similar
   implications as the external entity expansion issue.
@@ -128,6 +132,6 @@ Python because they break backward compatibility.
 
 .. _defusedxml: https://pypi.python.org/pypi/defusedxml/
 .. _defusedexpat: https://pypi.python.org/pypi/defusedexpat/
-.. _Billion Laughs: http://en.wikipedia.org/wiki/Billion_laughs
-.. _ZIP bomb: http://en.wikipedia.org/wiki/Zip_bomb
-.. _DTD: http://en.wikipedia.org/wiki/Document_Type_Definition
+.. _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
index 0fb3341..ae0877c 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: xml.sax.handler
    :synopsis: Base classes for SAX event handlers.
+
 .. moduleauthor:: Lars Marius Garshol <larsga@garshol.priv.no>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
 
+**Source code:** :source:`Lib/xml/sax/handler.py`
+
+--------------
 
 The SAX API defines four kinds of handlers: content handlers, DTD handlers,
 error handlers, and entity resolvers. Applications normally only need to
index 31ca260..c368fc2 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: xml.sax.xmlreader
    :synopsis: Interface which SAX-compliant XML parsers must implement.
+
 .. moduleauthor:: Lars Marius Garshol <larsga@garshol.priv.no>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
 
+**Source code:** :source:`Lib/xml/sax/xmlreader.py`
+
+--------------
 
 SAX parsers implement the :class:`XMLReader` interface. They are implemented in
 a Python module, which must provide a function :func:`create_parser`. This
@@ -98,7 +102,7 @@ The :class:`XMLReader` interface supports the following methods:
 
    Process an input source, producing SAX events. The *source* object can be a
    system identifier (a string identifying the input source -- typically a file
-   name or an URL), a file-like object, or an :class:`InputSource` object. When
+   name or a URL), a file-like object, or an :class:`InputSource` object. When
    :meth:`parse` returns, the input is completely processed, and the parser object
    can be discarded or reset.
 
@@ -228,12 +232,12 @@ Instances of :class:`Locator` provide these methods:
 
 .. method:: Locator.getColumnNumber()
 
-   Return the column number where the current event ends.
+   Return the column number where the current event begins.
 
 
 .. method:: Locator.getLineNumber()
 
-   Return the line number where the current event ends.
+   Return the line number where the current event begins.
 
 
 .. method:: Locator.getPublicId()
index 55f9799..78d6633 100644 (file)
@@ -3,10 +3,14 @@
 
 .. module:: xml.sax
    :synopsis: Package containing SAX2 base classes and convenience functions.
+
 .. moduleauthor:: Lars Marius Garshol <larsga@garshol.priv.no>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
 
+**Source code:** :source:`Lib/xml/sax/__init__.py`
+
+--------------
 
 The :mod:`xml.sax` package provides a number of modules which implement the
 Simple API for XML (SAX) interface for Python.  The package itself provides the
index 14cf078..538b798 100644 (file)
@@ -3,9 +3,13 @@
 
 .. module:: xml.sax.saxutils
    :synopsis: Convenience functions and classes for use with SAX.
+
 .. moduleauthor:: Lars Marius Garshol <larsga@garshol.priv.no>
 .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
 
+**Source code:** :source:`Lib/xml/sax/saxutils.py`
+
+--------------
 
 The module :mod:`xml.sax.saxutils` contains a number of classes and functions
 that are commonly useful when creating SAX applications, either in direct use,
index e199931..e7916d2 100644 (file)
@@ -3,18 +3,18 @@
 
 .. module:: xmlrpc.client
    :synopsis: XML-RPC client access.
+
 .. moduleauthor:: Fredrik Lundh <fredrik@pythonware.com>
 .. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
 
+**Source code:** :source:`Lib/xmlrpc/client.py`
 
 .. XXX Not everything is documented yet.  It might be good to describe
    Marshaller, Unmarshaller, getparser and Transport.
 
-**Source code:** :source:`Lib/xmlrpc/client.py`
-
 --------------
 
-XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a
+XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP(S) as a
 transport.  With it, a client can call methods with parameters on a remote
 server (the server is named by a URI) and get back structured data.  This module
 supports writing XML-RPC client code; it handles all the details of translating
@@ -29,8 +29,8 @@ between conformable Python objects and XML on the wire.
 
 .. versionchanged:: 3.5
 
-   For https URIs, :mod:`xmlrpc.client` now performs all the necessary
-   certificate and hostname checks by default
+   For HTTPS URIs, :mod:`xmlrpc.client` now performs all the necessary
+   certificate and hostname checks by default.
 
 .. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \
                        allow_none=False, use_datetime=False, \
@@ -46,15 +46,19 @@ between conformable Python objects and XML on the wire.
    :class:`SafeTransport` instance for https: URLs and an internal HTTP
    :class:`Transport` instance otherwise.  The optional third argument is an
    encoding, by default UTF-8. The optional fourth argument is a debugging flag.
+
+   The following parameters govern the use of the returned proxy instance.
    If *allow_none* is true,  the Python constant ``None`` will be translated into
    XML; the default behaviour is for ``None`` to raise a :exc:`TypeError`. This is
    a commonly-used extension to the XML-RPC specification, but isn't supported by
-   all clients and servers; see http://ontosys.com/xml-rpc/extensions.php for a
-   description.  The *use_builtin_types* flag can be used to cause date/time values
+   all clients and servers; see `http://ontosys.com/xml-rpc/extensions.php
+   <https://web.archive.org/web/20130120074804/http://ontosys.com/xml-rpc/extensions.php>`_
+   for a description.
+   The *use_builtin_types* flag can be used to cause date/time values
    to be presented as :class:`datetime.datetime` objects and binary data to be
    presented as :class:`bytes` objects; this flag is false by default.
-   :class:`datetime.datetime` and :class:`bytes` objects may be passed to calls.
-
+   :class:`datetime.datetime`, :class:`bytes` and :class:`bytearray` objects
+   may be passed to calls.
    The obsolete *use_datetime* flag is similar to *use_builtin_types* but it
    applies only to date/time values.
 
@@ -63,7 +67,7 @@ between conformable Python objects and XML on the wire.
    portion will be base64-encoded as an HTTP 'Authorization' header, and sent to
    the remote server as part of the connection process when invoking an XML-RPC
    method.  You only need to use this if the remote server requires a Basic
-   Authentication user and password. If an HTTPS url is provided, *context* may
+   Authentication user and password. If an HTTPS URL is provided, *context* may
    be :class:`ssl.SSLContext` and configures the SSL settings of the underlying
    HTTPS connection.
 
@@ -73,42 +77,43 @@ between conformable Python objects and XML on the wire.
    methods it supports (service discovery) and fetch other server-associated
    metadata.
 
-   :class:`ServerProxy` instance methods take Python basic types and objects as
-   arguments and return Python basic types and classes.  Types that are conformable
-   (e.g. that can be marshalled through XML), include the following (and except
-   where noted, they are unmarshalled as the same Python type):
+   Types that are conformable (e.g. that can be marshalled through XML),
+   include the following (and except where noted, they are unmarshalled
+   as the same Python type):
 
    .. tabularcolumns:: |l|L|
 
-   +---------------------------------+---------------------------------------------+
-   | Name                            | Meaning                                     |
-   +=================================+=============================================+
-   | :const:`boolean`                | The :const:`True` and :const:`False`        |
-   |                                 | constants                                   |
-   +---------------------------------+---------------------------------------------+
-   | :const:`integers`               | Pass in directly                            |
-   +---------------------------------+---------------------------------------------+
-   | :const:`floating-point numbers` | Pass in directly                            |
-   +---------------------------------+---------------------------------------------+
-   | :const:`strings`                | Pass in directly                            |
-   +---------------------------------+---------------------------------------------+
-   | :const:`arrays`                 | Any Python sequence type containing         |
-   |                                 | conformable elements. Arrays are returned   |
-   |                                 | as lists                                    |
-   +---------------------------------+---------------------------------------------+
-   | :const:`structures`             | A Python dictionary. Keys must be strings,  |
-   |                                 | values may be any conformable type. Objects |
-   |                                 | of user-defined classes can be passed in;   |
-   |                                 | only their *__dict__* attribute is          |
-   |                                 | transmitted.                                |
-   +---------------------------------+---------------------------------------------+
-   | :const:`dates`                  | In seconds since the epoch.  Pass in an     |
-   |                                 | instance of the :class:`DateTime` class or  |
-   |                                 | a :class:`datetime.datetime` instance.      |
-   +---------------------------------+---------------------------------------------+
-   | :const:`binary data`            | Pass in an instance of the :class:`Binary`  |
-   |                                 | wrapper class or a :class:`bytes` instance. |
-   +---------------------------------+---------------------------------------------+
+   +----------------------+-------------------------------------------------------+
+   | XML-RPC type         | Python type                                           |
+   +======================+=======================================================+
+   | ``boolean``          | :class:`bool`                                         |
+   +----------------------+-------------------------------------------------------+
+   | ``int`` or ``i4``    | :class:`int` in range from -2147483648 to 2147483647. |
+   +----------------------+-------------------------------------------------------+
+   | ``double``           | :class:`float`                                        |
+   +----------------------+-------------------------------------------------------+
+   | ``string``           | :class:`str`                                          |
+   +----------------------+-------------------------------------------------------+
+   | ``array``            | :class:`list` or :class:`tuple` containing            |
+   |                      | conformable elements.  Arrays are returned as         |
+   |                      | :class:`lists <list>`.                                |
+   +----------------------+-------------------------------------------------------+
+   | ``struct``           | :class:`dict`.  Keys must be strings, values may be   |
+   |                      | any conformable type.  Objects of user-defined        |
+   |                      | classes can be passed in; only their                  |
+   |                      | :attr:`~object.__dict__` attribute is transmitted.    |
+   +----------------------+-------------------------------------------------------+
+   | ``dateTime.iso8601`` | :class:`DateTime` or :class:`datetime.datetime`.      |
+   |                      | Returned type depends on values of                    |
+   |                      | *use_builtin_types* and *use_datetime* flags.         |
+   +----------------------+-------------------------------------------------------+
+   | ``base64``           | :class:`Binary`, :class:`bytes` or                    |
+   |                      | :class:`bytearray`.  Returned type depends on the     |
+   |                      | value of the *use_builtin_types* flag.                |
+   +----------------------+-------------------------------------------------------+
+   | ``nil``              | The ``None`` constant.  Passing is allowed only if    |
+   |                      | *allow_none* is true.                                 |
+   +----------------------+-------------------------------------------------------+
 
    This is the full set of data types supported by XML-RPC.  Method calls may also
    raise a special :exc:`Fault` instance, used to signal XML-RPC server errors, or
@@ -123,8 +128,8 @@ between conformable Python objects and XML on the wire.
    the control characters with ASCII values between 0 and 31 (except, of course,
    tab, newline and carriage return); failing to do this will result in an XML-RPC
    request that isn't well-formed XML.  If you have to pass arbitrary bytes
-   via XML-RPC, use the :class:`bytes` class or the class:`Binary` wrapper class
-   described below.
+   via XML-RPC, use :class:`bytes` or :class:`bytearray` classes or the
+   :class:`Binary` wrapper class described below.
 
    :class:`Server` is retained as an alias for :class:`ServerProxy` for backwards
    compatibility.  New code should use :class:`ServerProxy`.
@@ -142,7 +147,7 @@ between conformable Python objects and XML on the wire.
    `XML-RPC Introspection <http://xmlrpc-c.sourceforge.net/introspection.html>`_
       Describes the XML-RPC protocol extension for introspection.
 
-   `XML-RPC Specification <http://www.xmlrpc.com/spec>`_
+   `XML-RPC Specification <http://xmlrpc.scripting.com/spec.html>`_
       The official specification.
 
    `Unofficial XML-RPC Errata <http://effbot.org/zone/xmlrpc-errata.htm>`_
@@ -164,7 +169,7 @@ returning a value, which may be either returned data in a conformant type or a
 :class:`Fault` or :class:`ProtocolError` object indicating an error.
 
 Servers that support the XML introspection API support some common methods
-grouped under the reserved :attr:`system` attribute:
+grouped under the reserved :attr:`~ServerProxy.system` attribute:
 
 
 .. method:: ServerProxy.system.listMethods()
@@ -211,7 +216,7 @@ A working example follows. The server code::
    from xmlrpc.server import SimpleXMLRPCServer
 
    def is_even(n):
-       return n%2 == 0
+       return n % 2 == 0
 
    server = SimpleXMLRPCServer(("localhost", 8000))
    print("Listening on port 8000...")
@@ -231,24 +236,26 @@ The client code for the preceding server::
 DateTime Objects
 ----------------
 
-This class may be initialized with seconds since the epoch, a time
-tuple, an ISO 8601 time/date string, or a :class:`datetime.datetime`
-instance.  It has the following methods, supported mainly for internal
-use by the marshalling/unmarshalling code:
+.. class:: DateTime
+
+   This class may be initialized with seconds since the epoch, a time
+   tuple, an ISO 8601 time/date string, or a :class:`datetime.datetime`
+   instance.  It has the following methods, supported mainly for internal
+   use by the marshalling/unmarshalling code:
 
 
-.. method:: DateTime.decode(string)
+   .. method:: decode(string)
 
-   Accept a string as the instance's new time value.
+      Accept a string as the instance's new time value.
 
 
-.. method:: DateTime.encode(out)
+   .. method:: encode(out)
 
-   Write the XML-RPC encoding of this :class:`DateTime` item to the *out* stream
-   object.
+      Write the XML-RPC encoding of this :class:`DateTime` item to the *out* stream
+      object.
 
-It also supports certain of Python's built-in operators through rich comparison
-and :meth:`__repr__` methods.
+   It also supports certain of Python's built-in operators through rich comparison
+   and :meth:`__repr__` methods.
 
 A working example follows. The server code::
 
@@ -282,36 +289,38 @@ The client code for the preceding server::
 Binary Objects
 --------------
 
-This class may be initialized from bytes data (which may include NULs). The
-primary access to the content of a :class:`Binary` object is provided by an
-attribute:
+.. class:: Binary
 
+   This class may be initialized from bytes data (which may include NULs). The
+   primary access to the content of a :class:`Binary` object is provided by an
+   attribute:
 
-.. attribute:: Binary.data
 
-   The binary data encapsulated by the :class:`Binary` instance.  The data is
-   provided as a :class:`bytes` object.
+   .. attribute:: data
 
-:class:`Binary` objects have the following methods, supported mainly for
-internal use by the marshalling/unmarshalling code:
+      The binary data encapsulated by the :class:`Binary` instance.  The data is
+      provided as a :class:`bytes` object.
 
+   :class:`Binary` objects have the following methods, supported mainly for
+   internal use by the marshalling/unmarshalling code:
 
-.. method:: Binary.decode(bytes)
 
-   Accept a base64 :class:`bytes` object and decode it as the instance's new data.
+   .. method:: decode(bytes)
 
+      Accept a base64 :class:`bytes` object and decode it as the instance's new data.
 
-.. method:: Binary.encode(out)
 
-   Write the XML-RPC base 64 encoding of this binary item to the out stream object.
+   .. method:: encode(out)
 
-   The encoded data will have newlines every 76 characters as per
-   `RFC 2045 section 6.8 <http://tools.ietf.org/html/rfc2045#section-6.8>`_,
-   which was the de facto standard base64 specification when the
-   XML-RPC spec was written.
+      Write the XML-RPC base 64 encoding of this binary item to the *out* stream object.
 
-It also supports certain of Python's built-in operators through :meth:`__eq__`
-and :meth:`__ne__` methods.
+      The encoded data will have newlines every 76 characters as per
+      `RFC 2045 section 6.8 <https://tools.ietf.org/html/rfc2045#section-6.8>`_,
+      which was the de facto standard base64 specification when the
+      XML-RPC spec was written.
+
+   It also supports certain of Python's built-in operators through :meth:`__eq__`
+   and :meth:`__ne__` methods.
 
 Example usage of the binary objects.  We're going to transfer an image over
 XMLRPC::
@@ -342,18 +351,20 @@ The client gets the image and saves it to a file::
 Fault Objects
 -------------
 
-A :class:`Fault` object encapsulates the content of an XML-RPC fault tag. Fault
-objects have the following attributes:
+.. class:: Fault
+
+   A :class:`Fault` object encapsulates the content of an XML-RPC fault tag. Fault
+   objects have the following attributes:
 
 
-.. attribute:: Fault.faultCode
+   .. attribute:: faultCode
 
-   A string indicating the fault type.
+      A string indicating the fault type.
 
 
-.. attribute:: Fault.faultString
+   .. attribute:: faultString
 
-   A string containing a diagnostic message associated with the fault.
+      A string containing a diagnostic message associated with the fault.
 
 In the following example we're going to intentionally cause a :exc:`Fault` by
 returning a complex type object.  The server code::
@@ -362,7 +373,7 @@ returning a complex type object.  The server code::
 
    # A marshalling error is going to occur because we're returning a
    # complex number
-   def add(x,y):
+   def add(x, y):
        return x+y+0j
 
    server = SimpleXMLRPCServer(("localhost", 8000))
@@ -390,37 +401,39 @@ The client code for the preceding server::
 ProtocolError Objects
 ---------------------
 
-A :class:`ProtocolError` object describes a protocol error in the underlying
-transport layer (such as a 404 'not found' error if the server named by the URI
-does not exist).  It has the following attributes:
+.. class:: ProtocolError
+
+   A :class:`ProtocolError` object describes a protocol error in the underlying
+   transport layer (such as a 404 'not found' error if the server named by the URI
+   does not exist).  It has the following attributes:
 
 
-.. attribute:: ProtocolError.url
+   .. attribute:: url
 
-   The URI or URL that triggered the error.
+      The URI or URL that triggered the error.
 
 
-.. attribute:: ProtocolError.errcode
+   .. attribute:: errcode
 
-   The error code.
+      The error code.
 
 
-.. attribute:: ProtocolError.errmsg
+   .. attribute:: errmsg
 
-   The error message or diagnostic string.
+      The error message or diagnostic string.
 
 
-.. attribute:: ProtocolError.headers
+   .. attribute:: headers
 
-   A dict containing the headers of the HTTP/HTTPS request that triggered the
-   error.
+      A dict containing the headers of the HTTP/HTTPS request that triggered the
+      error.
 
 In the following example we're going to intentionally cause a :exc:`ProtocolError`
 by providing an invalid URI::
 
    import xmlrpc.client
 
-   # create a ServerProxy with an URI that doesn't respond to XMLRPC requests
+   # create a ServerProxy with a URI that doesn't respond to XMLRPC requests
    proxy = xmlrpc.client.ServerProxy("http://google.com/")
 
    try:
@@ -541,7 +554,7 @@ Example of Client Usage
        except Error as v:
            print("ERROR", v)
 
-To access an XML-RPC server through a proxy, you need to define  a custom
+To access an XML-RPC server through a HTTP proxy, you need to define a custom
 transport.  The following example shows how:
 
 .. Example taken from http://lowlife.jp/nobonobo/wiki/xmlrpcwithproxy.html
@@ -553,18 +566,21 @@ transport.  The following example shows how:
    class ProxiedTransport(xmlrpc.client.Transport):
        def set_proxy(self, proxy):
            self.proxy = proxy
+
        def make_connection(self, host):
            self.realhost = host
-           h = http.client.HTTP(self.proxy)
+           h = http.client.HTTPConnection(self.proxy)
            return h
-       def send_request(self, connection, handler, request_body):
+
+       def send_request(self, connection, handler, request_body, debug):
            connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
+
        def send_host(self, connection, host):
            connection.putheader('Host', self.realhost)
 
    p = ProxiedTransport()
    p.set_proxy('proxy-server:8080')
-   server = xmlrpc.client.Server('http://time.xmlrpc.com/RPC2', transport=p)
+   server = xmlrpc.client.ServerProxy('http://time.xmlrpc.com/RPC2', transport=p)
    print(server.currentTime.getCurrentTime())
 
 
@@ -577,7 +593,7 @@ See :ref:`simplexmlrpcserver-example`.
 .. rubric:: Footnotes
 
 .. [#] This approach has been first presented in `a discussion on xmlrpc.com
-   <http://web.archive.org/web/20060624230303/http://www.xmlrpc.com/discuss/msgReader$1208?mode=topic>`_.
+   <https://web.archive.org/web/20060624230303/http://www.xmlrpc.com/discuss/msgReader$1208?mode=topic>`_.
 .. the link now points to webarchive since the one at
 .. http://www.xmlrpc.com/discuss/msgReader%241208 is broken (and webadmin
 .. doesn't reply)
index 37d1393..ad1e812 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: xmlrpc.server
    :synopsis: Basic XML-RPC server implementations.
+
 .. moduleauthor:: Brian Quinlan <brianq@activestate.com>
 .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
 
@@ -18,7 +19,7 @@ servers written in Python.  Servers can either be free standing, using
 
 .. warning::
 
-   The :mod:`xmlrpc.client` module is not secure against maliciously
+   The :mod:`xmlrpc.server` module is not secure against maliciously
    constructed data.  If you need to parse untrusted or unauthenticated data see
    :ref:`xml-vulnerabilities`.
 
index b4484c8..7c7767f 100644 (file)
@@ -4,14 +4,13 @@
 .. module:: zipapp
    :synopsis: Manage executable python zip archives
 
-
-.. index::
-   single: Executable Zip Files
-
 .. versionadded:: 3.5
 
 **Source code:** :source:`Lib/zipapp.py`
 
+.. index::
+   single: Executable Zip Files
+
 --------------
 
 This module provides tools to manage the creation of zip files containing
@@ -23,7 +22,7 @@ Python code, which can be  :ref:`executed directly by the Python interpreter
 Basic Example
 -------------
 
-The following example shows how the :ref:`command-line-interface`
+The following example shows how the :ref:`zipapp-command-line-interface`
 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.
index d40315e..b421ea5 100644 (file)
@@ -3,6 +3,7 @@
 
 .. module:: zipfile
    :synopsis: Read and write ZIP-format archive files.
+
 .. moduleauthor:: James C. Ahlstrom <jim@interet.com>
 .. sectionauthor:: James C. Ahlstrom <jim@interet.com>
 
@@ -13,8 +14,7 @@
 The ZIP file format is a common archive and compression standard. This module
 provides tools to create, read, write, append, and list a ZIP file.  Any
 advanced use of this module will require an understanding of the format, as
-defined in `PKZIP Application Note
-<http://www.pkware.com/documents/casestudies/APPNOTE.TXT>`_.
+defined in `PKZIP Application Note`_.
 
 This module does not currently handle multi-disk ZIP files.
 It can handle ZIP files that use the ZIP64 extensions
@@ -115,7 +115,7 @@ The module defines the following items:
 
 .. seealso::
 
-   `PKZIP Application Note <http://www.pkware.com/documents/casestudies/APPNOTE.TXT>`_
+   `PKZIP Application Note`_
       Documentation on the ZIP file format by Phil Katz, the creator of the format and
       algorithms used.
 
@@ -134,8 +134,8 @@ ZipFile Objects
 
    Open a ZIP file, where *file* can be either a path to a file (a string) or a
    file-like object.  The *mode* parameter should be ``'r'`` to read an existing
-   file, ``'w'`` to truncate and write a new file, ``'x'`` to exclusive create
-   and write a new file, or ``'a'`` to append to an existing file.
+   file, ``'w'`` to truncate and write a new file, ``'a'`` to append to an
+   existing file, or ``'x'`` to exclusively create and write a new file.
    If *mode* is ``'x'`` and *file* refers to an existing file,
    a :exc:`FileExistsError` will be raised.
    If *mode* is ``'a'`` and *file* refers to an existing ZIP
@@ -511,8 +511,7 @@ Instances have the following attributes:
 
 .. attribute:: ZipInfo.extra
 
-   Expansion field data.  The `PKZIP Application Note
-   <http://www.pkware.com/documents/casestudies/APPNOTE.TXT>`_ contains
+   Expansion field data.  The `PKZIP Application Note`_ contains
    some comments on the internal structure of the data contained in this string.
 
 
@@ -574,3 +573,5 @@ Instances have the following attributes:
 .. attribute:: ZipInfo.file_size
 
    Size of the uncompressed file.
+
+.. _PKZIP Application Note: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
index 8a5d5d1..0a0f175 100644 (file)
@@ -3,8 +3,10 @@
 
 .. module:: zipimport
    :synopsis: support for importing Python modules from ZIP archives.
+
 .. moduleauthor:: Just van Rossum <just@letterror.com>
 
+--------------
 
 This module adds the ability to import Python modules (:file:`\*.py`,
 :file:`\*.py[co]`) and packages from ZIP-format archives. It is usually not
@@ -30,7 +32,7 @@ ZIP archives with an archive comment are currently not supported.
 
 .. seealso::
 
-   `PKZIP Application Note <http://www.pkware.com/documents/casestudies/APPNOTE.TXT>`_
+   `PKZIP Application Note <https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT>`_
       Documentation on the ZIP file format by Phil Katz, the creator of the format and
       algorithms used.
 
index 58fc31b..1de7bae 100644 (file)
@@ -5,6 +5,7 @@
    :synopsis: Low-level interface to compression and decompression routines
               compatible with gzip.
 
+--------------
 
 For applications that require data compression, the functions in this module
 allow compression and decompression, using the zlib library. The zlib library
@@ -31,22 +32,19 @@ The available exception and functions in this module are:
 .. function:: adler32(data[, value])
 
    Computes an Adler-32 checksum of *data*.  (An Adler-32 checksum is almost as
-   reliable as a CRC32 but can be computed much more quickly.)  If *value* is
-   present, it is used as the starting value of the checksum; otherwise, a fixed
-   default value is used.  This allows computing a running checksum over the
+   reliable as a CRC32 but can be computed much more quickly.)  The result
+   is an unsigned 32-bit integer.  If *value* is present, it is used as
+   the starting value of the checksum; otherwise, a default value of 1
+   is used.  Passing in *value* allows computing a running checksum over the
    concatenation of several inputs.  The algorithm is not cryptographically
    strong, and should not be used for authentication or digital signatures.  Since
    the algorithm is designed for use as a checksum algorithm, it is not suitable
    for use as a general hash algorithm.
 
-   Always returns an unsigned 32-bit integer.
-
-.. note::
-   To generate the same numeric value across all Python versions and
-   platforms use adler32(data) & 0xffffffff.  If you are only using
-   the checksum in packed binary format this is not necessary as the
-   return value is the correct 32bit binary representation
-   regardless of sign.
+   .. versionchanged:: 3.0
+      Always returns an unsigned value.
+      To generate the same numeric value across all Python versions and
+      platforms, use ``adler32(data) & 0xffffffff``.
 
 
 .. function:: compress(data[, level])
@@ -63,17 +61,31 @@ The available exception and functions in this module are:
    Returns a compression object, to be used for compressing data streams that won't
    fit into memory at once.
 
-   *level* is the compression level -- an integer from ``0`` to ``9``. A value
-   of ``1`` is fastest and produces the least compression, while a value of
+   *level* is the compression level -- an integer from ``0`` to ``9`` or ``-1``.
+   A value of ``1`` is fastest and produces the least compression, while a value of
    ``9`` is slowest and produces the most. ``0`` is no compression. The default
-   value is ``6``.
+   value is ``-1`` (Z_DEFAULT_COMPRESSION). Z_DEFAULT_COMPRESSION represents a default
+   compromise between speed and compression (currently equivalent to level 6).
 
    *method* is the compression algorithm. Currently, the only supported value is
    ``DEFLATED``.
 
-   *wbits* is the base two logarithm of the size of the window buffer. This
-   should be an integer from ``8`` to ``15``. Higher values give better
-   compression, but use more memory.
+   The *wbits* argument controls the size of the history buffer (or the
+   "window size") used when compressing data, and whether a header and
+   trailer is included in the output.  It can take several ranges of values:
+
+   * +9 to +15: The base-two logarithm of the window size, which
+     therefore ranges between 512 and 32768.  Larger values produce
+     better compression at the expense of greater memory usage.  The
+     resulting output will include a zlib-specific header and trailer.
+
+   * −9 to −15: Uses the absolute value of *wbits* as the
+     window size logarithm, while producing a raw output stream with no
+     header or trailing checksum.
+
+   * +25 to +31 = 16 + (9 to 15): Uses the low 4 bits of the value as the
+     window size logarithm, while including a basic :program:`gzip` header
+     and trailing checksum in the output.
 
    The *memLevel* argument controls the amount of memory used for the
    internal compression state. Valid values range from ``1`` to ``9``.
@@ -97,42 +109,58 @@ The available exception and functions in this module are:
       single: Cyclic Redundancy Check
       single: checksum; Cyclic Redundancy Check
 
-   Computes a CRC (Cyclic Redundancy Check)  checksum of *data*. If *value* is
-   present, it is used as the starting value of the checksum; otherwise, a fixed
-   default value is used.  This allows computing a running checksum over the
+   Computes a CRC (Cyclic Redundancy Check) checksum of *data*. The
+   result is an unsigned 32-bit integer. If *value* is present, it is used
+   as the starting value of the checksum; otherwise, a default value of 0
+   is used.  Passing in *value* allows computing a running checksum over the
    concatenation of several inputs.  The algorithm is not cryptographically
    strong, and should not be used for authentication or digital signatures.  Since
    the algorithm is designed for use as a checksum algorithm, it is not suitable
    for use as a general hash algorithm.
 
-   Always returns an unsigned 32-bit integer.
-
-   .. note::
-
+   .. versionchanged:: 3.0
+      Always returns an unsigned value.
       To generate the same numeric value across all Python versions and
-      platforms, use ``crc32(data) & 0xffffffff``.  If you are only using
-      the checksum in packed binary format this is not necessary as the
-      return value is the correct 32-bit binary representation
-      regardless of sign.
+      platforms, use ``crc32(data) & 0xffffffff``.
 
 
 .. function:: decompress(data[, wbits[, bufsize]])
 
    Decompresses the bytes in *data*, returning a bytes object containing the
-   uncompressed data.  The *wbits* parameter controls the size of the window
-   buffer, and is discussed further below.
+   uncompressed data.  The *wbits* parameter depends on
+   the format of *data*, and is discussed further below.
    If *bufsize* is given, it is used as the initial size of the output
    buffer.  Raises the :exc:`error` exception if any error occurs.
 
-   The absolute value of *wbits* is the base two logarithm of the size of the
-   history buffer (the "window size") used when compressing data.  Its absolute
-   value should be between 8 and 15 for the most recent versions of the zlib
-   library, larger values resulting in better compression at the expense of greater
-   memory usage.  When decompressing a stream, *wbits* must not be smaller
+   .. _decompress-wbits:
+
+   The *wbits* parameter controls the size of the history buffer
+   (or "window size"), and what header and trailer format is expected.
+   It is similar to the parameter for :func:`compressobj`, but accepts
+   more ranges of values:
+
+   * +8 to +15: The base-two logarithm of the window size.  The input
+     must include a zlib header and trailer.
+
+   * 0: Automatically determine the window size from the zlib header.
+     Only supported since zlib 1.2.3.5.
+
+   * −8 to −15: Uses the absolute value of *wbits* as the window size
+     logarithm.  The input must be a raw stream with no header or trailer.
+
+   * +24 to +31 = 16 + (8 to 15): Uses the low 4 bits of the value as
+     the window size logarithm.  The input must include a gzip header and
+     trailer.
+
+   * +40 to +47 = 32 + (8 to 15): Uses the low 4 bits of the value as
+     the window size logarithm, and automatically accepts either
+     the zlib or gzip format.
+
+   When decompressing a stream, the window size must not be smaller
    than the size originally used to compress the stream; using a too-small
-   value will result in an exception. The default value is therefore the
-   highest value, 15.  When *wbits* is negative, the standard
-   :program:`gzip` header is suppressed.
+   value may result in an :exc:`error` exception. The default *wbits* value
+   is 15, which corresponds to the largest window size and requires a zlib
+   header and trailer to be included.
 
    *bufsize* is the initial size of the buffer used to hold decompressed data.  If
    more space is required, the buffer size will be increased as needed, so you
@@ -145,7 +173,9 @@ The available exception and functions in this module are:
    Returns a decompression object, to be used for decompressing data streams that
    won't fit into memory at once.
 
-   The *wbits* parameter controls the size of the window buffer.
+   The *wbits* parameter controls the size of the history buffer (or the
+   "window size"), and what header and trailer format is expected.  It has
+   the same meaning as `described for decompress() <#decompress-wbits>`__.
 
    The *zdict* parameter specifies a predefined compression dictionary. If
    provided, this must be the same dictionary as was used by the compressor that
index 53a1c4d..8843116 100644 (file)
@@ -11,12 +11,12 @@ History of the software
 =======================
 
 Python was created in the early 1990s by Guido van Rossum at Stichting
-Mathematisch Centrum (CWI, see http://www.cwi.nl/) in the Netherlands as a
+Mathematisch Centrum (CWI, see https://www.cwi.nl/) in the Netherlands as a
 successor of a language called ABC.  Guido remains Python's principal author,
 although it includes many contributions from others.
 
 In 1995, Guido continued his work on Python at the Corporation for National
-Research Initiatives (CNRI, see http://www.cnri.reston.va.us/) in Reston,
+Research Initiatives (CNRI, see https://www.cnri.reston.va.us/) in Reston,
 Virginia where he released several versions of the software.
 
 In May 2000, Guido and the Python core development team moved to BeOpen.com to
@@ -27,7 +27,7 @@ https://www.python.org/psf/) was formed, a non-profit organization created
 specifically to own Python-related Intellectual Property.  Zope Corporation is a
 sponsoring member of the PSF.
 
-All Python releases are Open Source (see http://opensource.org/ for the Open
+All Python releases are Open Source (see https://opensource.org/ for the Open
 Source Definition). Historically, most, but not all, Python releases have also
 been GPL-compatible; the table below summarizes the various releases.
 
@@ -73,181 +73,189 @@ Terms and conditions for accessing or otherwise using Python
 ============================================================
 
 
-.. centered:: PSF LICENSE AGREEMENT FOR PYTHON |release|
-
-#. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
-   the Individual or Organization ("Licensee") accessing and otherwise using Python
-   |release| software in source or binary form and its associated documentation.
-
-#. Subject to the terms and conditions of this License Agreement, PSF hereby
-   grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
-   analyze, test, perform and/or display publicly, prepare derivative works,
-   distribute, and otherwise use Python |release| alone or in any derivative
-   version, provided, however, that PSF's License Agreement and PSF's notice of
-   copyright, i.e., "Copyright © 2001-2015 Python Software Foundation; All
-   Rights Reserved" are retained in Python |release| alone or in any derivative
-   version prepared by Licensee.
-
-#. In the event Licensee prepares a derivative work that is based on or
-   incorporates Python |release| or any part thereof, and wants to make the
-   derivative work available to others as provided herein, then Licensee hereby
-   agrees to include in any such work a brief summary of the changes made to Python
-   |release|.
-
-#. PSF is making Python |release| available to Licensee on an "AS IS" basis.
-   PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  BY WAY OF
-   EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
-   WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
-   USE OF PYTHON |release| WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
-
-#. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON |release|
-   FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
-   MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON |release|, OR ANY DERIVATIVE
-   THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-#. This License Agreement will automatically terminate upon a material breach of
-   its terms and conditions.
-
-#. Nothing in this License Agreement shall be deemed to create any relationship
-   of agency, partnership, or joint venture between PSF and Licensee.  This License
-   Agreement does not grant permission to use PSF trademarks or trade name in a
-   trademark sense to endorse or promote products or services of Licensee, or any
-   third party.
-
-#. By copying, installing or otherwise using Python |release|, Licensee agrees
-   to be bound by the terms and conditions of this License Agreement.
-
-
-.. centered:: BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
-
-
-.. centered:: BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
-
-#. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at
-   160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization
-   ("Licensee") accessing and otherwise using this software in source or binary
-   form and its associated documentation ("the Software").
-
-#. Subject to the terms and conditions of this BeOpen Python License Agreement,
-   BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license
-   to reproduce, analyze, test, perform and/or display publicly, prepare derivative
-   works, distribute, and otherwise use the Software alone or in any derivative
-   version, provided, however, that the BeOpen Python License is retained in the
-   Software, alone or in any derivative version prepared by Licensee.
-
-#. BeOpen is making the Software available to Licensee on an "AS IS" basis.
-   BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  BY WAY OF
-   EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
-   WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
-   USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
-
-#. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR
-   ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING,
-   MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF
-   ADVISED OF THE POSSIBILITY THEREOF.
-
-#. This License Agreement will automatically terminate upon a material breach of
-   its terms and conditions.
-
-#. This License Agreement shall be governed by and interpreted in all respects
-   by the law of the State of California, excluding conflict of law provisions.
-   Nothing in this License Agreement shall be deemed to create any relationship of
-   agency, partnership, or joint venture between BeOpen and Licensee.  This License
-   Agreement does not grant permission to use BeOpen trademarks or trade names in a
-   trademark sense to endorse or promote products or services of Licensee, or any
-   third party.  As an exception, the "BeOpen Python" logos available at
-   http://www.pythonlabs.com/logos.html may be used according to the permissions
-   granted on that web page.
-
-#. By copying, installing or otherwise using the software, Licensee agrees to be
-   bound by the terms and conditions of this License Agreement.
-
-
-.. centered:: CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
-
-#. This LICENSE AGREEMENT is between the Corporation for National Research
-   Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191
-   ("CNRI"), and the Individual or Organization ("Licensee") accessing and
-   otherwise using Python 1.6.1 software in source or binary form and its
-   associated documentation.
-
-#. Subject to the terms and conditions of this License Agreement, CNRI hereby
-   grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
-   analyze, test, perform and/or display publicly, prepare derivative works,
-   distribute, and otherwise use Python 1.6.1 alone or in any derivative version,
-   provided, however, that CNRI's License Agreement and CNRI's notice of copyright,
-   i.e., "Copyright © 1995-2001 Corporation for National Research Initiatives; All
-   Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version
-   prepared by Licensee.  Alternately, in lieu of CNRI's License Agreement,
-   Licensee may substitute the following text (omitting the quotes): "Python 1.6.1
-   is made available subject to the terms and conditions in CNRI's License
-   Agreement.  This Agreement together with Python 1.6.1 may be located on the
-   Internet using the following unique, persistent identifier (known as a handle):
-   1895.22/1013.  This Agreement may also be obtained from a proxy server on the
-   Internet using the following URL: http://hdl.handle.net/1895.22/1013."
-
-#. In the event Licensee prepares a derivative work that is based on or
-   incorporates Python 1.6.1 or any part thereof, and wants to make the derivative
-   work available to others as provided herein, then Licensee hereby agrees to
-   include in any such work a brief summary of the changes made to Python 1.6.1.
-
-#. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis.  CNRI
-   MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  BY WAY OF EXAMPLE,
-   BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY
-   OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
-   PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
-
-#. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR
-   ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
-   MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE
-   THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-#. This License Agreement will automatically terminate upon a material breach of
-   its terms and conditions.
-
-#. This License Agreement shall be governed by the federal intellectual property
-   law of the United States, including without limitation the federal copyright
-   law, and, to the extent such U.S. federal law does not apply, by the law of the
-   Commonwealth of Virginia, excluding Virginia's conflict of law provisions.
-   Notwithstanding the foregoing, with regard to derivative works based on Python
-   1.6.1 that incorporate non-separable material that was previously distributed
-   under the GNU General Public License (GPL), the law of the Commonwealth of
-   Virginia shall govern this License Agreement only as to issues arising under or
-   with respect to Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in
-   this License Agreement shall be deemed to create any relationship of agency,
-   partnership, or joint venture between CNRI and Licensee.  This License Agreement
-   does not grant permission to use CNRI trademarks or trade name in a trademark
-   sense to endorse or promote products or services of Licensee, or any third
-   party.
-
-#. By clicking on the "ACCEPT" button where indicated, or by copying, installing
-   or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and
-   conditions of this License Agreement.
-
-
-.. centered:: ACCEPT
-
-
-.. centered:: CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
-
-Copyright © 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The
-Netherlands.  All rights reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted, provided that
-the above copyright notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting documentation, and that
-the name of Stichting Mathematisch Centrum or CWI not be used in advertising or
-publicity pertaining to distribution of the software without specific, written
-prior permission.
-
-STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT
-OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
+PSF LICENSE AGREEMENT FOR PYTHON |release|
+------------------------------------------
+
+.. parsed-literal::
+
+   1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
+      the Individual or Organization ("Licensee") accessing and otherwise using Python
+      |release| software in source or binary form and its associated documentation.
+
+   2. Subject to the terms and conditions of this License Agreement, PSF hereby
+      grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+      analyze, test, perform and/or display publicly, prepare derivative works,
+      distribute, and otherwise use Python |release| alone or in any derivative
+      version, provided, however, that PSF's License Agreement and PSF's notice of
+      copyright, i.e., "Copyright © 2001-2016 Python Software Foundation; All Rights
+      Reserved" are retained in Python |release| alone or in any derivative version
+      prepared by Licensee.
+
+   3. In the event Licensee prepares a derivative work that is based on or
+      incorporates Python |release| or any part thereof, and wants to make the
+      derivative work available to others as provided herein, then Licensee hereby
+      agrees to include in any such work a brief summary of the changes made to Python
+      |release|.
+
+   4. PSF is making Python |release| available to Licensee on an "AS IS" basis.
+      PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  BY WAY OF
+      EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
+      WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
+      USE OF PYTHON |release| WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+   5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON |release|
+      FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
+      MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON |release|, OR ANY DERIVATIVE
+      THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+   6. This License Agreement will automatically terminate upon a material breach of
+      its terms and conditions.
+
+   7. Nothing in this License Agreement shall be deemed to create any relationship
+      of agency, partnership, or joint venture between PSF and Licensee.  This License
+      Agreement does not grant permission to use PSF trademarks or trade name in a
+      trademark sense to endorse or promote products or services of Licensee, or any
+      third party.
+
+   8. By copying, installing or otherwise using Python |release|, Licensee agrees
+      to be bound by the terms and conditions of this License Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+.. parsed-literal::
+
+   1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at
+      160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization
+      ("Licensee") accessing and otherwise using this software in source or binary
+      form and its associated documentation ("the Software").
+
+   2. Subject to the terms and conditions of this BeOpen Python License Agreement,
+      BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license
+      to reproduce, analyze, test, perform and/or display publicly, prepare derivative
+      works, distribute, and otherwise use the Software alone or in any derivative
+      version, provided, however, that the BeOpen Python License is retained in the
+      Software, alone or in any derivative version prepared by Licensee.
+
+   3. BeOpen is making the Software available to Licensee on an "AS IS" basis.
+      BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  BY WAY OF
+      EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
+      WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
+      USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+   4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR
+      ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING,
+      MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF
+      ADVISED OF THE POSSIBILITY THEREOF.
+
+   5. This License Agreement will automatically terminate upon a material breach of
+      its terms and conditions.
+
+   6. This License Agreement shall be governed by and interpreted in all respects
+      by the law of the State of California, excluding conflict of law provisions.
+      Nothing in this License Agreement shall be deemed to create any relationship of
+      agency, partnership, or joint venture between BeOpen and Licensee.  This License
+      Agreement does not grant permission to use BeOpen trademarks or trade names in a
+      trademark sense to endorse or promote products or services of Licensee, or any
+      third party.  As an exception, the "BeOpen Python" logos available at
+      http://www.pythonlabs.com/logos.html may be used according to the permissions
+      granted on that web page.
+
+   7. By copying, installing or otherwise using the software, Licensee agrees to be
+      bound by the terms and conditions of this License Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+.. parsed-literal::
+
+   1. This LICENSE AGREEMENT is between the Corporation for National Research
+      Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191
+      ("CNRI"), and the Individual or Organization ("Licensee") accessing and
+      otherwise using Python 1.6.1 software in source or binary form and its
+      associated documentation.
+
+   2. Subject to the terms and conditions of this License Agreement, CNRI hereby
+      grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+      analyze, test, perform and/or display publicly, prepare derivative works,
+      distribute, and otherwise use Python 1.6.1 alone or in any derivative version,
+      provided, however, that CNRI's License Agreement and CNRI's notice of copyright,
+      i.e., "Copyright © 1995-2001 Corporation for National Research Initiatives; All
+      Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version
+      prepared by Licensee.  Alternately, in lieu of CNRI's License Agreement,
+      Licensee may substitute the following text (omitting the quotes): "Python 1.6.1
+      is made available subject to the terms and conditions in CNRI's License
+      Agreement.  This Agreement together with Python 1.6.1 may be located on the
+      Internet using the following unique, persistent identifier (known as a handle):
+      1895.22/1013.  This Agreement may also be obtained from a proxy server on the
+      Internet using the following URL: http://hdl.handle.net/1895.22/1013."
+
+   3. In the event Licensee prepares a derivative work that is based on or
+      incorporates Python 1.6.1 or any part thereof, and wants to make the derivative
+      work available to others as provided herein, then Licensee hereby agrees to
+      include in any such work a brief summary of the changes made to Python 1.6.1.
+
+   4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis.  CNRI
+      MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  BY WAY OF EXAMPLE,
+      BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY
+      OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
+      PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+   5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR
+      ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
+      MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE
+      THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+   6. This License Agreement will automatically terminate upon a material breach of
+      its terms and conditions.
+
+   7. This License Agreement shall be governed by the federal intellectual property
+      law of the United States, including without limitation the federal copyright
+      law, and, to the extent such U.S. federal law does not apply, by the law of the
+      Commonwealth of Virginia, excluding Virginia's conflict of law provisions.
+      Notwithstanding the foregoing, with regard to derivative works based on Python
+      1.6.1 that incorporate non-separable material that was previously distributed
+      under the GNU General Public License (GPL), the law of the Commonwealth of
+      Virginia shall govern this License Agreement only as to issues arising under or
+      with respect to Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in
+      this License Agreement shall be deemed to create any relationship of agency,
+      partnership, or joint venture between CNRI and Licensee.  This License Agreement
+      does not grant permission to use CNRI trademarks or trade name in a trademark
+      sense to endorse or promote products or services of Licensee, or any third
+      party.
+
+   8. By clicking on the "ACCEPT" button where indicated, or by copying, installing
+      or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and
+      conditions of this License Agreement.
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+.. parsed-literal::
+
+   Copyright © 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The
+   Netherlands.  All rights reserved.
+
+   Permission to use, copy, modify, and distribute this software and its
+   documentation for any purpose and without fee is hereby granted, provided that
+   the above copyright notice appear in all copies and that both that copyright
+   notice and this permission notice appear in supporting documentation, and that
+   the name of Stichting Mathematisch Centrum or CWI not be used in advertising or
+   publicity pertaining to distribution of the software without specific, written
+   prior permission.
+
+   STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+   SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+   EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT
+   OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+   DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+   ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+   SOFTWARE.
 
 
 Licenses and Acknowledgements for Incorporated Software
@@ -329,14 +337,14 @@ Project, http://www.wide.ad.jp/. ::
       without specific prior written permission.
 
    THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-   GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-   FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-   HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
 
@@ -946,5 +954,3 @@ library unless the build is configured ``--with-system-libmpdec``::
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
-
-
index 01cfd6d..2469422 100644 (file)
@@ -439,7 +439,7 @@ is equivalent to ::
 
 .. seealso::
 
-   :pep:`0343` - The "with" statement
+   :pep:`343` - The "with" statement
       The specification, background, and examples for the Python :keyword:`with`
       statement.
 
@@ -469,7 +469,7 @@ A function definition defines a user-defined function object (see section
 .. productionlist::
    funcdef: [`decorators`] "def" `funcname` "(" [`parameter_list`] ")" ["->" `expression`] ":" `suite`
    decorators: `decorator`+
-   decorator: "@" `dotted_name` ["(" [`parameter_list` [","]] ")"] NEWLINE
+   decorator: "@" `dotted_name` ["(" [`argument_list` [","]] ")"] NEWLINE
    dotted_name: `identifier` ("." `identifier`)*
    parameter_list: (`defparameter` ",")*
                  : | "*" [`parameter`] ("," `defparameter`)* ["," "**" `parameter`]
@@ -604,7 +604,7 @@ A class definition defines a class object (see section :ref:`types`):
 
 .. productionlist::
    classdef: [`decorators`] "class" `classname` [`inheritance`] ":" `suite`
-   inheritance: "(" [`parameter_list`] ")"
+   inheritance: "(" [`argument_list`] ")"
    classname: `identifier`
 
 A class definition is an executable statement.  The inheritance list usually
@@ -726,7 +726,7 @@ The following code::
 Is semantically equivalent to::
 
     iter = (ITER)
-    iter = await type(iter).__aiter__(iter)
+    iter = type(iter).__aiter__(iter)
     running = True
     while running:
         try:
index 764c491..71d695f 100644 (file)
@@ -846,11 +846,9 @@ Internal types
    definitions may change with future versions of the interpreter, but they are
    mentioned here for completeness.
 
-   Code objects
-      .. index::
-         single: bytecode
-         object: code
+   .. index:: bytecode, object; code, code object
 
+   Code objects
       Code objects represent *byte-compiled* executable Python code, or :term:`bytecode`.
       The difference between a code object and a function object is that the function
       object contains an explicit reference to the function's globals (the module in
@@ -1734,6 +1732,11 @@ After the class object is created, it is passed to the class decorators
 included in the class definition (if any) and the resulting object is bound
 in the local namespace as the defined class.
 
+When a new class is created by ``type.__new__``, the object provided as the
+namespace parameter is copied to a standard Python dictionary and the original
+object is discarded. The new copy becomes the :attr:`~object.__dict__` attribute
+of the class object.
+
 .. seealso::
 
    :pep:`3135` - New super
@@ -1753,11 +1756,11 @@ to remember the order that class variables are defined::
 
     class OrderedClass(type):
 
-         @classmethod
-         def __prepare__(metacls, name, bases, **kwds):
+        @classmethod
+        def __prepare__(metacls, name, bases, **kwds):
             return collections.OrderedDict()
 
-         def __new__(cls, name, bases, namespace, **kwds):
+        def __new__(cls, name, bases, namespace, **kwds):
             result = type.__new__(cls, name, bases, dict(namespace))
             result.members = tuple(namespace)
             return result
@@ -2188,7 +2191,7 @@ For more information on context managers, see :ref:`typecontextmanager`.
 
 .. seealso::
 
-   :pep:`0343` - The "with" statement
+   :pep:`343` - The "with" statement
       The specification, background, and examples for the Python :keyword:`with`
       statement.
 
@@ -2316,6 +2319,10 @@ Coroutines also have the methods listed below, which are analogous to
 those of generators (see :ref:`generator-methods`).  However, unlike
 generators, coroutines do not directly support iteration.
 
+.. versionchanged:: 3.5.2
+   It is a :exc:`RuntimeError` to await on a coroutine more than once.
+
+
 .. method:: coroutine.send(value)
 
    Starts or resumes execution of the coroutine.  If *value* is ``None``,
@@ -2350,6 +2357,7 @@ generators, coroutines do not directly support iteration.
    Coroutine objects are automatically closed using the above process when
    they are about to be destroyed.
 
+.. _async-iterators:
 
 Asynchronous Iterators
 ----------------------
@@ -2362,7 +2370,7 @@ Asynchronous iterators can be used in an :keyword:`async for` statement.
 
 .. method:: object.__aiter__(self)
 
-   Must return an *awaitable* resulting in an *asynchronous iterator* object.
+   Must return an *asynchronous iterator* object.
 
 .. method:: object.__anext__(self)
 
@@ -2375,7 +2383,7 @@ An example of an asynchronous iterable object::
         async def readline(self):
             ...
 
-        async def __aiter__(self):
+        def __aiter__(self):
             return self
 
         async def __anext__(self):
@@ -2386,6 +2394,49 @@ An example of an asynchronous iterable object::
 
 .. versionadded:: 3.5
 
+.. note::
+
+   .. versionchanged:: 3.5.2
+      Starting with CPython 3.5.2, ``__aiter__`` can directly return
+      :term:`asynchronous iterators <asynchronous iterator>`.  Returning
+      an :term:`awaitable` object will result in a
+      :exc:`PendingDeprecationWarning`.
+
+      The recommended way of writing backwards compatible code in
+      CPython 3.5.x is to continue returning awaitables from
+      ``__aiter__``.  If you want to avoid the PendingDeprecationWarning
+      and keep the code backwards compatible, the following decorator
+      can be used::
+
+          import functools
+          import sys
+
+          if sys.version_info < (3, 5, 2):
+              def aiter_compat(func):
+                  @functools.wraps(func)
+                  async def wrapper(self):
+                      return func(self)
+                  return wrapper
+          else:
+              def aiter_compat(func):
+                  return func
+
+      Example::
+
+          class AsyncIterator:
+
+              @aiter_compat
+              def __aiter__(self):
+                  return self
+
+              async def __anext__(self):
+                  ...
+
+      Starting with CPython 3.6, the :exc:`PendingDeprecationWarning`
+      will be replaced with the :exc:`DeprecationWarning`.
+      In CPython 3.7, returning an awaitable from ``__aiter__`` will
+      result in a :exc:`RuntimeError`.
+
 
 Asynchronous Context Managers
 -----------------------------
index 99fa037..f508eaa 100644 (file)
@@ -133,7 +133,7 @@ Parenthesized forms
 A parenthesized form is an optional expression list enclosed in parentheses:
 
 .. productionlist::
-   parenth_form: "(" [`expression_list`] ")"
+   parenth_form: "(" [`starred_expression`] ")"
 
 A parenthesized expression list yields whatever that expression list yields: if
 the list contains at least one comma, it yields a tuple; otherwise, it yields
@@ -202,7 +202,7 @@ A list display is a possibly empty series of expressions enclosed in square
 brackets:
 
 .. productionlist::
-   list_display: "[" [`expression_list` | `comprehension`] "]"
+   list_display: "[" [`starred_list` | `comprehension`] "]"
 
 A list display yields a new list object, the contents being specified by either
 a list of expressions or a comprehension.  When a comma-separated list of
@@ -223,7 +223,7 @@ A set display is denoted by curly braces and distinguishable from dictionary
 displays by the lack of colons separating keys and values:
 
 .. productionlist::
-   set_display: "{" (`expression_list` | `comprehension`) "}"
+   set_display: "{" (`starred_list` | `comprehension`) "}"
 
 A set display yields a new mutable set object, the contents being specified by
 either a sequence of expressions or a comprehension.  When a comma-separated
@@ -250,7 +250,7 @@ curly braces:
 .. productionlist::
    dict_display: "{" [`key_datum_list` | `dict_comprehension`] "}"
    key_datum_list: `key_datum` ("," `key_datum`)* [","]
-   key_datum: `expression` ":" `expression`
+   key_datum: `expression` ":" `expression` | "**" `or_expr`
    dict_comprehension: `expression` ":" `expression` `comp_for`
 
 A dictionary display yields a new dictionary object.
@@ -261,6 +261,16 @@ used as a key into the dictionary to store the corresponding datum.  This means
 that you can specify the same key multiple times in the key/datum list, and the
 final dictionary's value for that key will be the last one given.
 
+.. index:: unpacking; dictionary, **; in dictionary displays
+
+A double asterisk ``**`` denotes :dfn:`dictionary unpacking`.
+Its operand must be a :term:`mapping`.  Each mapping item is added
+to the new dictionary.  Later values replace values already set by
+earlier key/datum pairs and earlier dictionary unpackings.
+
+.. versionadded:: 3.5
+   Unpacking into dictionary displays, originally proposed by :pep:`448`.
+
 A dict comprehension, in contrast to list and set comprehensions, needs two
 expressions separated with a colon followed by the usual "for" and "if" clauses.
 When the comprehension is run, the resulting key and value elements are inserted
@@ -378,14 +388,14 @@ on the right hand side of an assignment statement.
 
 .. seealso::
 
-   :pep:`0255` - Simple Generators
+   :pep:`255` - Simple Generators
       The proposal for adding generators and the :keyword:`yield` statement to Python.
 
-   :pep:`0342` - Coroutines via Enhanced Generators
+   :pep:`342` - Coroutines via Enhanced Generators
       The proposal to enhance the API and syntax of generators, making them
       usable as simple coroutines.
 
-   :pep:`0380` - Syntax for Delegating to a Subgenerator
+   :pep:`380` - Syntax for Delegating to a Subgenerator
       The proposal to introduce the :token:`yield_from` syntax, making delegation
       to sub-generators easy.
 
@@ -649,15 +659,15 @@ series of :term:`arguments <argument>`:
 
 .. productionlist::
    call: `primary` "(" [`argument_list` [","] | `comprehension`] ")"
-   argument_list: `positional_arguments` ["," `keyword_arguments`]
-                :   ["," "*" `expression`] ["," `keyword_arguments`]
-                :   ["," "**" `expression`]
-                : | `keyword_arguments` ["," "*" `expression`]
-                :   ["," `keyword_arguments`] ["," "**" `expression`]
-                : | "*" `expression` ["," `keyword_arguments`] ["," "**" `expression`]
-                : | "**" `expression`
-   positional_arguments: `expression` ("," `expression`)*
-   keyword_arguments: `keyword_item` ("," `keyword_item`)*
+   argument_list: `positional_arguments` ["," `starred_and_keywords`]
+                :   ["," `keywords_arguments`]
+                : | `starred_and_keywords` ["," `keywords_arguments`]
+                : | `keywords_arguments`
+   positional_arguments: ["*"] `expression` ("," ["*"] `expression`)*
+   starred_and_keywords: ("*" `expression` | `keyword_item`)
+                : ("," "*" `expression` | "," `keyword_item`)*
+   keywords_arguments: (`keyword_item` | "**" `expression`)
+                : ("," `keyword_item` | "**" `expression`)*
    keyword_item: `identifier` "=" `expression`
 
 An optional trailing comma may be present after the positional and keyword arguments
@@ -715,20 +725,21 @@ there were no excess keyword arguments.
 
 .. index::
    single: *; in function calls
+   single: unpacking; in function calls
 
 If the syntax ``*expression`` appears in the function call, ``expression`` must
-evaluate to an iterable.  Elements from this iterable are treated as if they
-were additional positional arguments; if there are positional arguments
-*x1*, ..., *xN*, and ``expression`` evaluates to a sequence *y1*, ..., *yM*,
-this is equivalent to a call with M+N positional arguments *x1*, ..., *xN*,
-*y1*, ..., *yM*.
+evaluate to an :term:`iterable`.  Elements from these iterables are
+treated as if they were additional positional arguments.  For the call
+``f(x1, x2, *y, x3, x4)``, if *y* evaluates to a sequence *y1*, ..., *yM*,
+this is equivalent to a call with M+4 positional arguments *x1*, *x2*,
+*y1*, ..., *yM*, *x3*, *x4*.
 
 A consequence of this is that although the ``*expression`` syntax may appear
-*after* some keyword arguments, it is processed *before* the keyword arguments
-(and the ``**expression`` argument, if any -- see below).  So::
+*after* explicit keyword arguments, it is processed *before* the
+keyword arguments (and any ``**expression`` arguments -- see below).  So::
 
    >>> def f(a, b):
-   ...  print(a, b)
+   ...     print(a, b)
    ...
    >>> f(b=1, *(2,))
    2 1
@@ -746,13 +757,20 @@ used in the same call, so in practice this confusion does not arise.
    single: **; in function calls
 
 If the syntax ``**expression`` appears in the function call, ``expression`` must
-evaluate to a mapping, the contents of which are treated as additional keyword
-arguments.  In the case of a keyword appearing in both ``expression`` and as an
-explicit keyword argument, a :exc:`TypeError` exception is raised.
+evaluate to a :term:`mapping`, the contents of which are treated as
+additional keyword arguments.  If a keyword is already present
+(as an explicit keyword argument, or from another unpacking),
+a :exc:`TypeError` exception is raised.
 
 Formal parameters using the syntax ``*identifier`` or ``**identifier`` cannot be
 used as positional argument slots or as keyword argument names.
 
+.. versionchanged:: 3.5
+   Function calls accept any number of ``*`` and ``**`` unpackings,
+   positional arguments may follow iterable unpackings (``*``),
+   and keyword arguments may follow dictionary unpackings (``**``).
+   Originally proposed by :pep:`448`.
+
 A call always returns some value, possibly ``None``, unless it raises an
 exception.  How this value is computed depends on the type of the callable
 object.
@@ -821,7 +839,7 @@ Suspend the execution of :term:`coroutine` on an :term:`awaitable` object.
 Can only be used inside a :term:`coroutine function`.
 
 .. productionlist::
-   await: ["await"] `primary`
+   await_expr: "await" `primary`
 
 .. versionadded:: 3.5
 
@@ -835,7 +853,7 @@ The power operator binds more tightly than unary operators on its left; it binds
 less tightly than unary operators on its right.  The syntax is:
 
 .. productionlist::
-   power: `await` ["**" `u_expr`]
+   power: ( `await_expr` | `primary` ) ["**" `u_expr`]
 
 Thus, in an unparenthesized sequence of power and unary operators, the operators
 are evaluated from right to left (this does not constrain the evaluation order
@@ -1407,13 +1425,29 @@ Expression lists
 
 .. productionlist::
    expression_list: `expression` ( "," `expression` )* [","]
+   starred_list: `starred_item` ( "," `starred_item` )* [","]
+   starred_expression: `expression` | ( `starred_item` "," )* [`starred_item`]
+   starred_item: `expression` | "*" `or_expr`
 
 .. index:: object: tuple
 
-An expression list containing at least one comma yields a tuple.  The length of
+Except when part of a list or set display, an expression list
+containing at least one comma yields a tuple.  The length of
 the tuple is the number of expressions in the list.  The expressions are
 evaluated from left to right.
 
+.. index::
+   pair: iterable; unpacking
+   single: *; in expression lists
+
+An asterisk ``*`` denotes :dfn:`iterable unpacking`.  Its operand must be
+an :term:`iterable`.  The iterable is expanded into a sequence of items,
+which are included in the new tuple, list, or set, at the site of
+the unpacking.
+
+.. versionadded:: 3.5
+   Iterable unpacking in expression lists, originally proposed by :pep:`448`.
+
 .. index:: pair: trailing; comma
 
 The trailing comma is required only to create a single tuple (a.k.a. a
index d549b26..2144c1f 100644 (file)
@@ -29,11 +29,10 @@ such as the importing of parent packages, and the updating of various caches
 a name binding operation.
 
 When calling :func:`__import__` as part of an import statement, the
-import system first checks the module global namespace for a function by
-that name. If it is not found, then the standard builtin :func:`__import__`
-is called. Other mechanisms for invoking the import system (such as
-:func:`importlib.import_module`) do not perform this check and will always
-use the standard import system.
+standard builtin :func:`__import__` is called. Other mechanisms for
+invoking the import system (such as :func:`importlib.import_module`) may
+choose to subvert :func:`__import__` and use its own solution to
+implement import semantics.
 
 When a module is first imported, Python searches for the module and if found,
 it creates a module object [#fnmo]_, initializing it.  If the named module
index 5633ae3..bb7e390 100644 (file)
@@ -60,7 +60,7 @@ Python for .NET
    This implementation actually uses the CPython implementation, but is a managed
    .NET application and makes .NET libraries available.  It was created by Brian
    Lloyd.  For more information, see the `Python for .NET home page
-   <http://pythonnet.sourceforge.net>`_.
+   <https://pythonnet.github.io/>`_.
 
 IronPython
    An alternate Python for .NET.  Unlike Python.NET, this is a complete Python
index 8ad975f..71964d7 100644 (file)
@@ -322,7 +322,7 @@ of identifiers is based on NFKC.
 
 A non-normative HTML file listing all valid identifier characters for Unicode
 4.1 can be found at
-http://www.dcl.hpi.uni-potsdam.de/home/loewis/table-3131.html.
+https://www.dcl.hpi.uni-potsdam.de/home/loewis/table-3131.html.
 
 
 .. _keywords:
@@ -538,8 +538,7 @@ Notes:
       Support for name aliases [#]_ has been added.
 
 (5)
-   Individual code units which form parts of a surrogate pair can be encoded using
-   this escape sequence.  Exactly four hex digits are required.
+   Exactly four hex digits are required.
 
 (6)
    Any Unicode character can be encoded this way.  Exactly eight hex digits
index 5f60540..d403c4d 100644 (file)
@@ -45,7 +45,7 @@ expression statements are allowed and occasionally useful.  The syntax for an
 expression statement is:
 
 .. productionlist::
-   expression_stmt: `expression_list`
+   expression_stmt: `starred_expression`
 
 An expression statement evaluates the expression list (which may be a single
 expression).
@@ -81,11 +81,11 @@ Assignment statements are used to (re)bind names to values and to modify
 attributes or items of mutable objects:
 
 .. productionlist::
-   assignment_stmt: (`target_list` "=")+ (`expression_list` | `yield_expression`)
+   assignment_stmt: (`target_list` "=")+ (`starred_expression` | `yield_expression`)
    target_list: `target` ("," `target`)* [","]
    target: `identifier`
          : | "(" `target_list` ")"
-         : | "[" `target_list` "]"
+         : | "[" [`target_list`] "]"
          : | `attributeref`
          : | `subscription`
          : | `slicing`
@@ -115,21 +115,25 @@ given with the definition of the object types (see section :ref:`types`).
 Assignment of an object to a target list, optionally enclosed in parentheses or
 square brackets, is recursively defined as follows.
 
-* If the target list is a single target: The object is assigned to that target.
+* If the target list is empty: The object must also be an empty iterable.
 
-* If the target list is a comma-separated list of targets: The object must be an
-  iterable with the same number of items as there are targets in the target list,
-  and the items are assigned, from left to right, to the corresponding targets.
+* If the target list is a single target in parentheses: The object is assigned
+  to that target.
+
+* If the target list is a comma-separated list of targets, or a single target
+  in square brackets: The object must be an iterable with the same number of
+  items as there are targets in the target list, and the items are assigned,
+  from left to right, to the corresponding targets.
 
   * If the target list contains one target prefixed with an asterisk, called a
-    "starred" target: The object must be a sequence with at least as many items
+    "starred" target: The object must be an iterable with at least as many items
     as there are targets in the target list, minus one.  The first items of the
-    sequence are assigned, from left to right, to the targets before the starred
-    target.  The final items of the sequence are assigned to the targets after
-    the starred target.  A list of the remaining items in the sequence is then
+    iterable are assigned, from left to right, to the targets before the starred
+    target.  The final items of the iterable are assigned to the targets after
+    the starred target.  A list of the remaining items in the iterable is then
     assigned to the starred target (the list can be empty).
 
-  * Else: The object must be a sequence with the same number of items as there
+  * Else: The object must be an iterable with the same number of items as there
     are targets in the target list, and the items are assigned, from left to
     right, to the corresponding targets.
 
@@ -150,11 +154,6 @@ Assignment of an object to a single target is recursively defined as follows.
   count for the object previously bound to the name to reach zero, causing the
   object to be deallocated and its destructor (if it has one) to be called.
 
-* If the target is a target list enclosed in parentheses or in square brackets:
-  The object must be an iterable with the same number of items as there are
-  targets in the target list, and its items are assigned, from left to right,
-  to the corresponding targets.
-
   .. index:: pair: attribute; assignment
 
 * If the target is an attribute reference: The primary expression in the
@@ -237,7 +236,7 @@ Assignment of an object to a single target is recursively defined as follows.
    phase, causing less detailed error messages.
 
 Although the definition of assignment implies that overlaps between the
-left-hand side and the right-hand side are 'simultanenous' (for example ``a, b =
+left-hand side and the right-hand side are 'simultaneous' (for example ``a, b =
 b, a`` swaps two variables), overlaps *within* the collection of assigned-to
 variables occur left-to-right, sometimes resulting in confusion.  For instance,
 the following program prints ``[0, 2]``::
@@ -331,12 +330,12 @@ program:
 The simple form, ``assert expression``, is equivalent to ::
 
    if __debug__:
-      if not expression: raise AssertionError
+       if not expression: raise AssertionError
 
 The extended form, ``assert expression1, expression2``, is equivalent to ::
 
    if __debug__:
-      if not expression1: raise AssertionError(expression2)
+       if not expression1: raise AssertionError(expression2)
 
 .. index::
    single: __debug__
@@ -661,7 +660,7 @@ steps:
 
 When the statement contains multiple clauses (separated by
 commas) the two steps are carried out separately for each clause, just
-as though the clauses had been separated out into individiual import
+as though the clauses had been separated out into individual import
 statements.
 
 The details of the first step, finding and loading modules are described in
@@ -893,7 +892,7 @@ The :keyword:`nonlocal` statement
    nonlocal_stmt: "nonlocal" `identifier` ("," `identifier`)*
 
 .. XXX add when implemented
-                : ["=" (`target_list` "=")+ expression_list]
+                : ["=" (`target_list` "=")+ starred_expression]
                 : | "nonlocal" identifier augop expression_list
 
 The :keyword:`nonlocal` statement causes the listed identifiers to refer to
index d44b052..6311283 100644 (file)
@@ -164,6 +164,19 @@ class PyCoroutineMethod(PyCoroutineMixin, PyClassmember):
         return PyClassmember.run(self)
 
 
+class PyAbstractMethod(PyClassmember):
+
+    def handle_signature(self, sig, signode):
+        ret = super(PyAbstractMethod, self).handle_signature(sig, signode)
+        signode.insert(0, addnodes.desc_annotation('abstractmethod ',
+                                                   'abstractmethod '))
+        return ret
+
+    def run(self):
+        self.name = 'py:method'
+        return PyClassmember.run(self)
+
+
 # Support for documenting version of removal in deprecations
 
 class DeprecatedRemoved(Directive):
@@ -368,5 +381,6 @@ def setup(app):
     app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod)
     app.add_directive_to_domain('py', 'coroutinefunction', PyCoroutineFunction)
     app.add_directive_to_domain('py', 'coroutinemethod', PyCoroutineMethod)
+    app.add_directive_to_domain('py', 'abstractmethod', PyAbstractMethod)
     app.add_directive('miscnews', MiscNews)
     return {'version': '1.0', 'parallel_read_safe': True}
index 50835bb..e24043f 100644 (file)
@@ -176,3 +176,8 @@ div.footer a:hover {
 .stableabi {
     color: #229;
 }
+
+.highlight {
+    background: none !important;
+}
+
index 7dccf72..de78041 100755 (executable)
@@ -43,7 +43,7 @@ directives = [
 ]
 
 all_directives = '(' + '|'.join(directives) + ')'
-seems_directive_re = re.compile(r'\.\. %s([^a-z:]|:(?!:))' % all_directives)
+seems_directive_re = re.compile(r'(?<!\.)\.\. %s([^a-z:]|:(?!:))' % all_directives)
 default_role_re = re.compile(r'(^| )`\w([^`]*?\w)?`($| )')
 leaked_markup_re = re.compile(r'[a-z]::\s|`|\.\.\s*\w+:')
 
@@ -83,7 +83,7 @@ def check_suspicious_constructs(fn, lines):
     """Check for suspicious reST constructs."""
     inprod = False
     for lno, line in enumerate(lines):
-        if seems_directive_re.match(line):
+        if seems_directive_re.search(line):
             yield lno+1, 'comment seems to be intended as a directive'
         if '.. productionlist::' in line:
             inprod = True
index 5d82c67..716c9e4 100644 (file)
@@ -28,6 +28,7 @@ $(document).ready(function() {
             var button = $('<span class="copybutton">&gt;&gt;&gt;</span>');
             button.css(button_styles)
             button.attr('title', hide_text);
+            button.data('hidden', 'false');
             jthis.prepend(button);
         }
         // tracebacks (.gt) contain bare text elements that need to be
@@ -38,20 +39,24 @@ $(document).ready(function() {
     });
 
     // define the behavior of the button when it's clicked
-    $('.copybutton').toggle(
-        function() {
-            var button = $(this);
+    $('.copybutton').click(function(e){
+        e.preventDefault();
+        var button = $(this);
+        if (button.data('hidden') === 'false') {
+            // hide the code output
             button.parent().find('.go, .gp, .gt').hide();
             button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
             button.css('text-decoration', 'line-through');
             button.attr('title', show_text);
-        },
-        function() {
-            var button = $(this);
+            button.data('hidden', 'true');
+        } else {
+            // show the code output
             button.parent().find('.go, .gp, .gt').show();
             button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
             button.css('text-decoration', 'none');
             button.attr('title', hide_text);
-        });
+            button.data('hidden', 'false');
+        }
+    });
 });
 
index 2a95fca..dba93bf 100644 (file)
@@ -82,7 +82,7 @@ howto/pyporting,,::,Programming Language :: Python :: 2
 howto/pyporting,,::,Programming Language :: Python :: 3
 howto/regex,,::,
 howto/regex,,:foo,(?:foo)
-howto/urllib2,,:example,"for example ""joe@password:example.com"""
+howto/urllib2,,:password,"for example ""joe:password@example.com"""
 library/audioop,,:ipos,"# factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],"
 library/bisect,32,:hi,all(val >= x for val in a[i:hi])
 library/bisect,42,:hi,all(val > x for val in a[i:hi])
@@ -198,6 +198,7 @@ library/unittest,,:first,"self.assertEqual(cm.output, ['INFO:foo:first message',
 library/unittest,,:foo,'ERROR:foo.bar:second message'])
 library/unittest,,:second,'ERROR:foo.bar:second message'])
 library/urllib.request,,:close,Connection:close
+library/urllib.request,,:port,:port
 library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n<head>\n"
 library/urllib.request,,:password,"""joe:password@python.org"""
 library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678
@@ -237,7 +238,7 @@ using/cmdline,,:line,action:message:category:module:line
 using/cmdline,,:line,file:line: category: message
 using/cmdline,,:message,action:message:category:module:line
 using/cmdline,,:module,action:message:category:module:line
-using/unix,,:Packaging,http://en.opensuse.org/Portal:Packaging
+using/unix,,:Packaging,https://en.opensuse.org/Portal:Packaging
 whatsnew/2.0,418,:len,
 whatsnew/2.3,,::,
 whatsnew/2.3,,:config,
@@ -281,9 +282,9 @@ library/xml.etree.elementtree,301,:character,<fictional:character>Archie Leach</
 library/xml.etree.elementtree,301,:character,<fictional:character>Sir Robin</fictional:character>
 library/xml.etree.elementtree,301,:character,<fictional:character>Gunther</fictional:character>
 library/xml.etree.elementtree,301,:character,<fictional:character>Commander Clement</fictional:character>
-library/xml.etree.elementtree,332,:actor,"for actor in root.findall('real_person:actor', ns):"
-library/xml.etree.elementtree,332,:name,"name = actor.find('real_person:name', ns)"
-library/xml.etree.elementtree,332,:character,"for char in actor.findall('role:character', ns):"
+library/xml.etree.elementtree,,:actor,"for actor in root.findall('real_person:actor', ns):"
+library/xml.etree.elementtree,,:name,"name = actor.find('real_person:name', ns)"
+library/xml.etree.elementtree,,:character,"for char in actor.findall('role:character', ns):"
 library/zipapp,31,:main,"$ python -m zipapp myapp -m ""myapp:main"""
 library/zipapp,82,:fn,"argument should have the form ""pkg.mod:fn"", where ""pkg.mod"" is a"
 library/zipapp,155,:callable,"""pkg.module:callable"" and the archive will be run by importing"
index 969099a..1076c1f 100644 (file)
@@ -1,59 +1,59 @@
 {% extends "defindex.html" %}
 {% block tables %}
-  <p><strong>Parts of the documentation:</strong></p>
+  <p><strong>{% trans %}Parts of the documentation:{% endtrans %}</strong></p>
   <table class="contentstable" align="center"><tr>
     <td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("whatsnew/" + version) }}">What's new in Python {{ version }}?</a><br/>
-         <span class="linkdescr">or <a href="{{ pathto("whatsnew/index") }}">all "What's new" documents</a> since 2.0</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("tutorial/index") }}">Tutorial</a><br/>
-         <span class="linkdescr">start here</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("library/index") }}">Library Reference</a><br/>
-         <span class="linkdescr">keep this under your pillow</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("reference/index") }}">Language Reference</a><br/>
-         <span class="linkdescr">describes syntax and language elements</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("using/index") }}">Python Setup and Usage</a><br/>
-         <span class="linkdescr">how to use Python on different platforms</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("howto/index") }}">Python HOWTOs</a><br/>
-         <span class="linkdescr">in-depth documents on specific topics</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("whatsnew/" + version) }}">{% trans %}What's new in Python {{ version }}?{% endtrans %}</a><br/>
+        <span class="linkdescr"> {% trans whatsnew_index=pathto("whatsnew/index") %}or <a href="{{ whatsnew_index }}">all "What's new" documents</a> since 2.0{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("tutorial/index") }}">{% trans %}Tutorial{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}start here{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("library/index") }}">{% trans %}Library Reference{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}keep this under your pillow{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("reference/index") }}">{% trans %}Language Reference{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}describes syntax and language elements{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("using/index") }}">{% trans %}Python Setup and Usage{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}how to use Python on different platforms{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("howto/index") }}">{% trans %}Python HOWTOs{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}in-depth documents on specific topics{% endtrans %}</span></p>
     </td><td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("installing/index") }}">Installing Python Modules</a><br/>
-         <span class="linkdescr">installing from the Python Package Index &amp; other sources</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("distributing/index") }}">Distributing Python Modules</a><br/>
-         <span class="linkdescr">publishing modules for installation by others</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("extending/index") }}">Extending and Embedding</a><br/>
-         <span class="linkdescr">tutorial for C/C++ programmers</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("c-api/index") }}">Python/C API</a><br/>
-         <span class="linkdescr">reference for C/C++ programmers</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("faq/index") }}">FAQs</a><br/>
-         <span class="linkdescr">frequently asked questions (with answers!)</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("installing/index") }}">{% trans %}Installing Python Modules{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}installing from the Python Package Index &amp; other sources{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("distributing/index") }}">{% trans %}Distributing Python Modules{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}publishing modules for installation by others{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("extending/index") }}">{% trans %}Extending and Embedding{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}tutorial for C/C++ programmers{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("c-api/index") }}">{% trans %}Python/C API{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}reference for C/C++ programmers{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("faq/index") }}">{% trans %}FAQs{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}frequently asked questions (with answers!){% endtrans %}</span></p>
     </td></tr>
   </table>
 
-  <p><strong>Indices and tables:</strong></p>
+  <p><strong>{% trans %}Indices and tables:{% endtrans %}</strong></p>
   <table class="contentstable" align="center"><tr>
     <td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("py-modindex") }}">Global Module Index</a><br/>
-         <span class="linkdescr">quick access to all modules</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">General Index</a><br/>
-         <span class="linkdescr">all functions, classes, terms</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("glossary") }}">Glossary</a><br/>
-         <span class="linkdescr">the most important terms explained</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("py-modindex") }}">{% trans %}Global Module Index{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}quick access to all modules{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">{% trans %}General Index{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}all functions, classes, terms{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("glossary") }}">{% trans %}Glossary{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}the most important terms explained{% endtrans %}</span></p>
     </td><td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("search") }}">Search page</a><br/>
-         <span class="linkdescr">search this documentation</span></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">Complete Table of Contents</a><br/>
-         <span class="linkdescr">lists all sections and subsections</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("search") }}">{% trans %}Search page{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}search this documentation{% endtrans %}</span></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">{% trans %}Complete Table of Contents{% endtrans %}</a><br/>
+         <span class="linkdescr">{% trans %}lists all sections and subsections{% endtrans %}</span></p>
     </td></tr>
   </table>
 
-  <p><strong>Meta information:</strong></p>
+  <p><strong>{% trans %}Meta information:{% endtrans %}</strong></p>
   <table class="contentstable" align="center"><tr>
     <td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("bugs") }}">Reporting bugs</a></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("about") }}">About the documentation</a></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("bugs") }}">{% trans %}Reporting bugs{% endtrans %}</a></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("about") }}">{% trans %}About the documentation{% endtrans %}</a></p>
     </td><td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("license") }}">History and License of Python</a></p>
-      <p class="biglink"><a class="biglink" href="{{ pathto("copyright") }}">Copyright</a></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("license") }}">{% trans %}History and License of Python{% endtrans %}</a></p>
+      <p class="biglink"><a class="biglink" href="{{ pathto("copyright") }}">{% trans %}Copyright{% endtrans %}</a></p>
     </td></tr>
   </table>
 {% endblock %}
index 78e9c4f..bb449ef 100644 (file)
@@ -1,17 +1,17 @@
-<h3>Download</h3>
-<p><a href="{{ pathto('download') }}">Download these documents</a></p>
-<h3>Docs for other versions</h3>
+<h3>{% trans %}Download{% endtrans %}</h3>
+<p><a href="{{ pathto('download') }}">{% trans %}Download these documents{% endtrans %}</a></p>
+<h3>{% trans %}Docs for other versions{% endtrans %}</h3>
 <ul>
-  <li><a href="https://docs.python.org/2.7/">Python 2.7 (stable)</a></li>
-  <li><a href="https://docs.python.org/3.4/">Python 3.4 (stable)</a></li>
-  <li><a href="https://www.python.org/doc/versions/">Old versions</a></li>
+  <li><a href="https://docs.python.org/2.7/">{% trans %}Python 2.7 (stable){% endtrans %}</a></li>
+  <li><a href="https://docs.python.org/3.4/">{% trans %}Python 3.4 (stable){% endtrans %}</a></li>
+  <li><a href="https://www.python.org/doc/versions/">{% trans %}Old versions{% endtrans %}</a></li>
 </ul>
 
-<h3>Other resources</h3>
+<h3>{% trans %}Other resources{% endtrans %}</h3>
 <ul>
   {# XXX: many of these should probably be merged in the main docs #}
-  <li><a href="https://www.python.org/dev/peps/">PEP Index</a></li>
-  <li><a href="https://wiki.python.org/moin/BeginnersGuide">Beginner's Guide</a></li>
-  <li><a href="https://wiki.python.org/moin/PythonBooks">Book List</a></li>
-  <li><a href="https://www.python.org/doc/av/">Audio/Visual Talks</a></li>
+  <li><a href="https://www.python.org/dev/peps/">{% trans %}PEP Index{% endtrans %}</a></li>
+  <li><a href="https://wiki.python.org/moin/BeginnersGuide">{% trans %}Beginner's Guide{% endtrans %}</a></li>
+  <li><a href="https://wiki.python.org/moin/PythonBooks">{% trans %}Book List{% endtrans %}</a></li>
+  <li><a href="https://www.python.org/doc/av/">{% trans %}Audio/Visual Talks{% endtrans %}</a></li>
 </ul>
index 5abff1b..1887b85 100644 (file)
@@ -6,7 +6,7 @@
         <li>
           {%- if versionswitcher is defined %}
           <span class="version_switcher_placeholder">{{ release }}</span>
-          <a href="{{ pathto('index') }}">Documentation</a>{{ reldelim1 }}
+          <a href="{{ pathto('index') }}">{% trans %}Documentation {% endtrans %}</a>{{ reldelim1 }}
           {%- else %}
           <a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}
           {%- endif %}
@@ -18,7 +18,7 @@
     <link rel="shortcut icon" type="image/png" href="{{ pathto('_static/py.png', 1) }}" />
     {% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
     {% if versionswitcher is defined and not embedded %}<script type="text/javascript" src="{{ pathto('_static/version_switch.js', 1) }}"></script>{% endif %}
-    {% if pagename == 'whatsnew/changelog' %}
+    {% if pagename == 'whatsnew/changelog' and not embedded %}
     <script type="text/javascript">
       $(document).ready(function() {
           // add the search form and bind the events
 {% endblock %}
 {% block footer %}
     <div class="footer">
-    &copy; <a href="{{ pathto('copyright') }}">Copyright</a> {{ copyright|e }}.
+    &copy; <a href="{{ pathto('copyright') }}">{% trans %}Copyright{% endtrans %}</a> {{ copyright|e }}.
     <br />
-    The Python Software Foundation is a non-profit corporation.
-    <a href="https://www.python.org/psf/donations/">Please donate.</a>
+    {% trans %}The Python Software Foundation is a non-profit corporation.{% endtrans %}
+    <a href="https://www.python.org/psf/donations/">{% trans %}Please donate.{% endtrans %}</a>
     <br />
-    Last updated on {{ last_updated|e }}.
-    <a href="{{ pathto('bugs') }}">Found a bug</a>?
+    {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+    {% trans pathto_bugs=pathto('bugs') %}<a href="{{ pathto_bugs }}">Found a bug</a>?{% endtrans %}
     <br />
-    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version|e }}.
+    {% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
     </div>
 {% endblock %}
 {% block sidebarsourcelink %}
 {%- if show_source and has_source and sourcename %}
 <h3>{{ _('This Page') }}</h3>
 <ul class="this-page-menu">
-  <li><a href="{{ pathto('bugs') }}">Report a Bug</a></li>
+  <li><a href="{{ pathto('bugs') }}">{% trans %}Report a Bug{% endtrans %}</a></li>
   <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
-         rel="nofollow">Show Source</a></li>
+         rel="nofollow">{% trans %}Show Source{% endtrans %}</a></li>
 </ul>
 {%- endif %}
 {% endblock %}
index e04459b..ffd16aa 100644 (file)
@@ -92,7 +92,7 @@ in the script::
    filename = os.environ.get('PYTHONSTARTUP')
    if filename and os.path.isfile(filename):
        with open(filename) as fobj:
-          startup_file = fobj.read()
+           startup_file = fobj.read()
        exec(startup_file)
 
 
index 7e014ef..2489d75 100644 (file)
@@ -120,7 +120,7 @@ are directly accessible:
 If a name is declared global, then all references and assignments go directly to
 the middle scope containing the module's global names.  To rebind variables
 found outside of the innermost scope, the :keyword:`nonlocal` statement can be
-used; if not declared nonlocal, those variable are read-only (an attempt to
+used; if not declared nonlocal, those variables are read-only (an attempt to
 write to such a variable will simply create a *new* local variable in the
 innermost scope, leaving the identically named outer variable unchanged).
 
@@ -162,12 +162,15 @@ binding::
    def scope_test():
        def do_local():
            spam = "local spam"
+
        def do_nonlocal():
            nonlocal spam
            spam = "nonlocal spam"
+
        def do_global():
            global spam
            spam = "global spam"
+
        spam = "test spam"
        do_local()
        print("After local assignment:", spam)
@@ -260,6 +263,7 @@ definition looked like this::
    class MyClass:
        """A simple example class"""
        i = 12345
+
        def f(self):
            return 'hello world'
 
@@ -508,8 +512,10 @@ variable in the class is also ok.  For example::
 
    class C:
        f = f1
+
        def g(self):
            return 'hello world'
+
        h = g
 
 Now ``f``, ``g`` and ``h`` are all attributes of class :class:`C` that refer to
@@ -523,8 +529,10 @@ argument::
    class Bag:
        def __init__(self):
            self.data = []
+
        def add(self, x):
            self.data.append(x)
+
        def addtwice(self, x):
            self.add(x)
            self.add(x)
@@ -713,7 +721,7 @@ will do nicely::
    class Employee:
        pass
 
-   john = Employee() # Create an empty employee record
+   john = Employee()  # Create an empty employee record
 
    # Fill the fields of the record
    john.name = 'John Doe'
@@ -839,8 +847,10 @@ defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``::
        def __init__(self, data):
            self.data = data
            self.index = len(data)
+
        def __iter__(self):
            return self
+
        def __next__(self):
            if self.index == 0:
                raise StopIteration
index 813c828..ddc0855 100644 (file)
@@ -312,7 +312,7 @@ You can see it if you really want to using :func:`print`::
 It is simple to write a function that returns a list of the numbers of the
 Fibonacci series, instead of printing it::
 
-   >>> def fib2(n): # return Fibonacci series up to n
+   >>> def fib2(n):  # return Fibonacci series up to n
    ...     """Return a list containing the Fibonacci series up to n."""
    ...     result = []
    ...     a, b = 0, 1
@@ -361,7 +361,7 @@ The most useful form is to specify a default value for one or more arguments.
 This creates a function that can be called with fewer arguments than it is
 defined to allow.  For example::
 
-   def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
+   def ask_ok(prompt, retries=4, reminder='Please try again!'):
        while True:
            ok = input(prompt)
            if ok in ('y', 'ye', 'yes'):
@@ -370,8 +370,8 @@ defined to allow.  For example::
                return False
            retries = retries - 1
            if retries < 0:
-               raise OSError('uncooperative user')
-           print(complaint)
+               raise ValueError('invalid user response')
+           print(reminder)
 
 This function can be called in several ways:
 
@@ -540,7 +540,7 @@ parameter are 'keyword-only' arguments, meaning that they can only be used as
 keywords rather than positional arguments. ::
 
    >>> def concat(*args, sep="/"):
-   ...    return sep.join(args)
+   ...     return sep.join(args)
    ...
    >>> concat("earth", "mars", "venus")
    'earth/mars/venus'
index 0d51480..b39bdf4 100644 (file)
@@ -397,7 +397,7 @@ objects, such as lists.
 
 Though tuples may seem similar to lists, they are often used in different
 situations and for different purposes.
-Tuples are :term:`immutable`, and usually contain an heterogeneous sequence of
+Tuples are :term:`immutable`, and usually contain a heterogeneous sequence of
 elements that are accessed via unpacking (see later in this section) or indexing
 (or even by attribute in the case of :func:`namedtuples <collections.namedtuple>`).
 Lists are :term:`mutable`, and their elements are usually homogeneous and are
index 351ee52..4195c7e 100644 (file)
@@ -170,15 +170,15 @@ reference ``.args``.  One may also instantiate an exception first before
 raising it and add any attributes to it as desired. ::
 
    >>> try:
-   ...    raise Exception('spam', 'eggs')
+   ...     raise Exception('spam', 'eggs')
    ... except Exception as inst:
-   ...    print(type(inst))    # the exception instance
-   ...    print(inst.args)     # arguments stored in .args
-   ...    print(inst)          # __str__ allows args to be printed directly,
-   ...                         # but may be overridden in exception subclasses
-   ...    x, y = inst.args     # unpack args
-   ...    print('x =', x)
-   ...    print('y =', y)
+   ...     print(type(inst))    # the exception instance
+   ...     print(inst.args)     # arguments stored in .args
+   ...     print(inst)          # __str__ allows args to be printed directly,
+   ...                          # but may be overridden in exception subclasses
+   ...     x, y = inst.args     # unpack args
+   ...     print('x =', x)
+   ...     print('y =', y)
    ...
    <class 'Exception'>
    ('spam', 'eggs')
index 9c3c143..d440e53 100644 (file)
@@ -155,7 +155,7 @@ which implements arithmetic based on rational numbers (so the numbers like
 
 If you are a heavy user of floating point operations you should take a look
 at the Numerical Python package and many other packages for mathematical and
-statistical operations supplied by the SciPy project. See <http://scipy.org>.
+statistical operations supplied by the SciPy project. See <https://scipy.org>.
 
 Python provides tools that may help on those rare occasions when you really
 *do* want to know the exact value of a float.  The
index c157f22..dd9c7cd 100644 (file)
@@ -152,11 +152,11 @@ Positional and keyword arguments can be arbitrarily combined::
 ``'!a'`` (apply :func:`ascii`), ``'!s'`` (apply :func:`str`) and ``'!r'``
 (apply :func:`repr`) can be used to convert the value before it is formatted::
 
-   >>> import math
-   >>> print('The value of PI is approximately {}.'.format(math.pi))
-   The value of PI is approximately 3.14159265359.
-   >>> print('The value of PI is approximately {!r}.'.format(math.pi))
-   The value of PI is approximately 3.141592653589793.
+   >>> contents = 'eels'
+   >>> print('My hovercraft is full of {}.'.format(contents))
+   My hovercraft is full of eels.
+   >>> print('My hovercraft is full of {!r}.'.format(contents))
+   My hovercraft is full of 'eels'.
 
 An optional ``':'`` and format specifier can follow the field name. This allows
 greater control over how the value is formatted.  The following example
@@ -271,10 +271,11 @@ The rest of the examples in this section will assume that a file object called
 ``f`` has already been created.
 
 To read a file's contents, call ``f.read(size)``, which reads some quantity of
-data and returns it as a string or bytes object.  *size* is an optional numeric
-argument.  When *size* is omitted or negative, the entire contents of the file
-will be read and returned; it's your problem if the file is twice as large as
-your machine's memory. Otherwise, at most *size* bytes are read and returned.
+data and returns it as a string (in text mode) or bytes object (in binary mode).
+*size* is an optional numeric argument.  When *size* is omitted or negative, the
+entire contents of the file will be read and returned; it's your problem if the
+file is twice as large as your machine's memory. Otherwise, at most *size* bytes
+are read and returned.
 If the end of the file has been reached, ``f.read()`` will return an empty
 string (``''``).  ::
 
@@ -315,11 +316,11 @@ the number of characters written. ::
    >>> f.write('This is a test\n')
    15
 
-To write something other than a string, it needs to be converted to a string
-first::
+Other types of objects need to be converted -- either to a string (in text mode)
+or a bytes object (in binary mode) -- before writing them::
 
    >>> value = ('the answer', 42)
-   >>> s = str(value)
+   >>> s = str(value)  # convert the tuple to string
    >>> f.write(s)
    18
 
@@ -337,11 +338,11 @@ beginning of the file as the reference point. ::
    >>> f = open('workfile', 'rb+')
    >>> f.write(b'0123456789abcdef')
    16
-   >>> f.seek(5)     # Go to the 6th byte in the file
+   >>> f.seek(5)      # Go to the 6th byte in the file
    5
    >>> f.read(1)
    b'5'
-   >>> f.seek(-3, 2) # Go to the 3rd byte before the end
+   >>> f.seek(-3, 2)  # Go to the 3rd byte before the end
    13
    >>> f.read(1)
    b'd'
index abf30f0..d73cfeb 100644 (file)
@@ -49,6 +49,6 @@ into other applications.  Another similar enhanced interactive environment is
 bpython_.
 
 
-.. _GNU Readline: http://tiswww.case.edu/php/chet/readline/rltop.html
-.. _IPython: http://ipython.scipy.org/
+.. _GNU Readline: https://tiswww.case.edu/php/chet/readline/rltop.html
+.. _IPython: https://ipython.org/
 .. _bpython: http://www.bpython-interpreter.org/
index c5c1343..2140329 100644 (file)
@@ -232,7 +232,7 @@ If you want to concatenate variables or a variable and a literal, use ``+``::
 This feature is particularly useful when you want to break long strings::
 
    >>> text = ('Put several strings within parentheses '
-               'to have them joined together.')
+   ...         'to have them joined together.')
    >>> text
    'Put several strings within parentheses to have them joined together.'
 
@@ -276,11 +276,11 @@ makes sure that ``s[:i] + s[i:]`` is always equal to ``s``::
 Slice indices have useful defaults; an omitted first index defaults to zero, an
 omitted second index defaults to the size of the string being sliced. ::
 
-   >>> word[:2]  # character from the beginning to position 2 (excluded)
+   >>> word[:2]   # character from the beginning to position 2 (excluded)
    'Py'
-   >>> word[4:]  # characters from position 4 (included) to the end
+   >>> word[4:]   # characters from position 4 (included) to the end
    'on'
-   >>> word[-2:] # characters from the second-last (included) to the end
+   >>> word[-2:]  # characters from the second-last (included) to the end
    'on'
 
 One way to remember how slices work is to think of the indices as pointing
@@ -352,9 +352,8 @@ The built-in function :func:`len` returns the length of a string::
       Strings support a large number of methods for
       basic transformations and searching.
 
-   :ref:`string-formatting`
-      Information about string formatting with :meth:`str.format` is described
-      here.
+   :ref:`formatstrings`
+      Information about string formatting with :meth:`str.format`.
 
    :ref:`old-string-formatting`
       The old formatting operations invoked when strings and Unicode strings are
index 9ae64b0..261a3f3 100644 (file)
@@ -34,7 +34,7 @@ called :file:`fibo.py` in the current directory with the following contents::
            a, b = b, a+b
        print()
 
-   def fib2(n): # return Fibonacci series up to n
+   def fib2(n):   # return Fibonacci series up to n
        result = []
        a, b = 0, 1
        while b < n:
@@ -117,7 +117,8 @@ use it to save typing in interactive sessions.
    For efficiency reasons, each module is only imported once per interpreter
    session.  Therefore, if you change your modules, you must restart the
    interpreter -- or, if it's just one module you want to test interactively,
-   use :func:`imp.reload`, e.g. ``import imp; imp.reload(modulename)``.
+   use :func:`importlib.reload`, e.g. ``import importlib;
+   importlib.reload(modulename)``.
 
 
 .. _tut-modulesasscripts:
index 0954eba..52ffdbe 100644 (file)
@@ -152,7 +152,7 @@ The :mod:`statistics` module calculates basic statistical properties
     >>> statistics.variance(data)
     1.3720238095238095
 
-The SciPy project <http://scipy.org> has many other modules for numerical
+The SciPy project <https://scipy.org> has many other modules for numerical
 computations.
 
 .. _tut-internet-access:
@@ -301,7 +301,7 @@ file::
            with self.assertRaises(TypeError):
                average(20, 30, 70)
 
-   unittest.main() # Calling from the command line invokes all tests
+   unittest.main()  # Calling from the command line invokes all tests
 
 
 .. _tut-batteries-included:
index f7d2a0a..3714384 100644 (file)
@@ -180,6 +180,7 @@ tasks in background while the main program continues to run::
            threading.Thread.__init__(self)
            self.infile = infile
            self.outfile = outfile
+
        def run(self):
            f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
            f.write(self.infile)
index 479542c..1ea22ae 100644 (file)
@@ -43,7 +43,7 @@ More Python resources:
   for download.  Once you begin releasing code, you can register it here so that
   others can find it.
 
-* http://code.activestate.com/recipes/langs/python/: The Python Cookbook is a
+* https://code.activestate.com/recipes/langs/python/: The Python Cookbook is a
   sizable collection of code examples, larger modules, and useful scripts.
   Particularly notable contributions are collected in a book also titled Python
   Cookbook (O'Reilly & Associates, ISBN 0-596-00797-3.)
@@ -51,7 +51,7 @@ More Python resources:
 * http://www.pyvideo.org collects links to Python-related videos from
   conferences and user-group meetings.
 
-* http://scipy.org: The Scientific Python project includes modules for fast
+* https://scipy.org: The Scientific Python project includes modules for fast
   array computations and manipulations plus a host of packages for such
   things as linear algebra, Fourier transforms, non-linear solvers,
   random number distributions, statistical analysis and the like.
index c7210a0..ec744a3 100644 (file)
@@ -77,7 +77,7 @@ source.
    the :mod:`__main__` module.
 
    Since the argument is a *module* name, you must not give a file extension
-   (``.py``).  The ``module-name`` should be a valid Python module name, but
+   (``.py``).  The module name should be a valid absolute Python module name, but
    the implementation may not always enforce this (e.g. it may allow you to
    use a name that includes a hyphen).
 
@@ -194,7 +194,7 @@ Miscellaneous options
    :class:`str` or :class:`bytes` with :class:`int`.  Issue an error when the
    option is given twice (:option:`-bb`).
 
-   .. versionchanged: 3.5
+   .. versionchanged:: 3.5
       Affects comparisons of :class:`bytes` with :class:`int`.
 
 .. cmdoption:: -B
@@ -398,7 +398,7 @@ Miscellaneous options
      tracing with a traceback limit of *NFRAME* frames. See the
      :func:`tracemalloc.start` for more information.
 
-   It also allows to pass arbitrary values and retrieve them through the
+   It also allows passing arbitrary values and retrieving them through the
    :data:`sys._xoptions` dictionary.
 
    .. versionchanged:: 3.2
index ef091e5..05c91bb 100644 (file)
@@ -25,7 +25,7 @@ there.
 
 What you get after installing is a number of things:
 
-* A :file:`MacPython 3.4` folder in your :file:`Applications` folder. In here
+* A :file:`MacPython 3.5` folder in your :file:`Applications` folder. In here
   you find IDLE, the development environment that is a standard part of official
   Python distributions; PythonLauncher, which handles double-clicking Python
   scripts from the Finder; and the "Build Applet" tool, which allows you to
@@ -65,7 +65,7 @@ number of standard Unix command line editors, :program:`vim` and
 :program:`emacs` among them. If you want a more Mac-like editor,
 :program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see
 http://www.barebones.com/products/bbedit/index.html) are good choices, as is
-:program:`TextMate` (see http://macromates.com/). Other editors include
+:program:`TextMate` (see https://macromates.com/). Other editors include
 :program:`Gvim` (http://macvim.org) and :program:`Aquamacs`
 (http://aquamacs.org/).
 
@@ -93,7 +93,7 @@ aware of: programs that talk to the Aqua window manager (in other words,
 anything that has a GUI) need to be run in a special way. Use :program:`pythonw`
 instead of :program:`python` to start such scripts.
 
-With Python 3.4, you can use either :program:`python` or :program:`pythonw`.
+With Python 3.5, you can use either :program:`python` or :program:`pythonw`.
 
 
 Configuration
@@ -144,22 +144,22 @@ the foundation of most modern Mac development. Information on PyObjC is
 available from https://pythonhosted.org/pyobjc/.
 
 The standard Python GUI toolkit is :mod:`tkinter`, based on the cross-platform
-Tk toolkit (http://www.tcl.tk). An Aqua-native version of Tk is bundled with OS
+Tk toolkit (https://www.tcl.tk). An Aqua-native version of Tk is bundled with OS
 X by Apple, and the latest version can be downloaded and installed from
-http://www.activestate.com; it can also be built from source.
+https://www.activestate.com; it can also be built from source.
 
 *wxPython* is another popular cross-platform GUI toolkit that runs natively on
 Mac OS X. Packages and documentation are available from http://www.wxpython.org.
 
 *PyQt* is another popular cross-platform GUI toolkit that runs natively on Mac
 OS X. More information can be found at
-http://www.riverbankcomputing.co.uk/software/pyqt/intro.
+https://riverbankcomputing.com/software/pyqt/intro.
 
 
 Distributing Python Applications on the Mac
 ===========================================
 
-The "Build Applet" tool that is placed in the MacPython 3.4 folder is fine for
+The "Build Applet" tool that is placed in the MacPython 3.5 folder is fine for
 packaging small Python scripts on your own machine to run as a standard Mac
 application. This tool, however, is not robust enough to distribute Python
 applications to other users.
index 5da1f23..4449d4f 100644 (file)
@@ -26,11 +26,11 @@ following links:
 
 .. seealso::
 
-   http://www.debian.org/doc/manuals/maint-guide/first.en.html
+   https://www.debian.org/doc/manuals/maint-guide/first.en.html
       for Debian users
-   http://en.opensuse.org/Portal:Packaging
+   https://en.opensuse.org/Portal:Packaging
       for OpenSuse users
-   http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html
+   https://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html
       for Fedora users
    http://www.slackbook.org/html/package-management-making-packages.html
       for Slackware users
@@ -55,7 +55,7 @@ On FreeBSD and OpenBSD
 On OpenSolaris
 --------------
 
-You can get Python from `OpenCSW <http://www.opencsw.org/>`_.  Various versions
+You can get Python from `OpenCSW <https://www.opencsw.org/>`_.  Various versions
 of Python are available and can be installed with e.g. ``pkgutil -i python27``.
 
 
@@ -65,7 +65,7 @@ Building Python
 ===============
 
 If you want to compile CPython yourself, first thing you should do is get the
-`source <https://www.python.org/download/source/>`_. You can download either the
+`source <https://www.python.org/downloads/source/>`_. You can download either the
 latest release's source or just grab a fresh `clone
 <https://docs.python.org/devguide/setup.html#getting-the-source-code>`_.  (If you want
 to contribute patches, you will need a clone.)
@@ -139,10 +139,10 @@ Vim and Emacs are excellent editors which support Python very well.  For more
 information on how to code in Python in these editors, look at:
 
 * http://www.vim.org/scripts/script.php?script_id=790
-* http://sourceforge.net/projects/python-mode
+* https://sourceforge.net/projects/python-mode
 
 Geany is an excellent IDE with support for a lot of languages. For more
-information, read: http://www.geany.org/
+information, read: https://www.geany.org/
 
 Komodo edit is another extremely good IDE.  It also has support for a lot of
-languages. For more information, read http://komodoide.com/.
+languages. For more information, read https://komodoide.com/.
index 02bcbee..c529478 100644 (file)
@@ -14,7 +14,7 @@ subdirectory (on Windows, this is ``Lib\site-packages``).
 .. seealso::
 
    `Python Packaging User Guide: Creating and using virtual environments
-   <https://packaging.python.org/en/latest/installing.html#virtual-environments>`__
+   <https://packaging.python.org/en/latest/installing/#creating-virtual-environments>`__
 
 .. highlight:: none
 
@@ -29,8 +29,9 @@ or equivalently::
 
 The command, if run with ``-h``, will show the available options::
 
-    usage: venv [-h] [--system-site-packages] [--symlinks] [--clear]
-                [--upgrade] [--without-pip] ENV_DIR [ENV_DIR ...]
+    usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
+                [--upgrade] [--without-pip]
+                ENV_DIR [ENV_DIR ...]
 
     Creates virtual Python environments in one or more target directories.
 
@@ -39,15 +40,14 @@ The command, if run with ``-h``, will show the available options::
 
     optional arguments:
       -h, --help             show this help message and exit
-      --system-site-packages Give access to the global site-packages dir to the
-                             virtual environment.
+      --system-site-packages Give the virtual environment access to the system
+                             site-packages dir.
       --symlinks             Try to use symlinks rather than copies, when symlinks
                              are not the default for the platform.
       --copies               Try to use copies rather than symlinks, even when
                              symlinks are the default for the platform.
-      --clear                Delete the environment directory if it already exists.
-                             If not specified and the directory exists, an error is
-                             raised.
+      --clear                Delete the contents of the environment directory if it
+                             already exists, before environment creation.
       --upgrade              Upgrade the environment directory to use this version
                              of Python, assuming Python has been upgraded in-place.
       --without-pip          Skips installing or upgrading pip in the virtual
@@ -89,9 +89,9 @@ venv's binary directory. The invocation of the script is platform-specific:
 +-------------+-----------------+-----------------------------------------+
 |             | csh/tcsh        | $ source <venv>/bin/activate.csh        |
 +-------------+-----------------+-----------------------------------------+
-| Windows     | cmd.exe         | C:\> <venv>/Scripts/activate.bat        |
+| Windows     | cmd.exe         | C:\> <venv>\Scripts\activate.bat        |
 +-------------+-----------------+-----------------------------------------+
-|             | PowerShell      | PS C:\> <venv>/Scripts/Activate.ps1     |
+|             | PowerShell      | PS C:\> <venv>\Scripts\Activate.ps1     |
 +-------------+-----------------+-----------------------------------------+
 
 You don't specifically *need* to activate an environment; activation just
index 2116c10..7520d60 100644 (file)
@@ -24,6 +24,14 @@ core interpreter and library being used by a single user. The installer is also
 able to install for all users of a single machine, and a separate ZIP file is
 available for application-local distributions.
 
+Supported Versions
+------------------
+
+As specified in :pep:`11`, a Python release only supports a Windows platform
+while Microsoft considers the platform under extended support. This means that
+Python 3.5 supports Windows Vista and newer. If you require Windows XP support
+then please install Python 3.4.
+
 Installation Steps
 ------------------
 
@@ -211,6 +219,23 @@ avoid collisions between files with the same name.
 
 You may also specify the ``/quiet`` option to hide the progress display.
 
+Modifying an install
+--------------------
+
+Once Python has been installed, you can add or remove features through the
+Programs and Features tool that is part of Windows. Select the Python entry and
+choose "Uninstall/Change" to open the installer in maintenance mode.
+
+"Modify" allows you to add or remove features by modifying the checkboxes -
+unchanged checkboxes will not install or remove anything. Some options cannot be
+changed in this mode, such as the install directory; to modify these, you will
+need to remove and then reinstall Python completely.
+
+"Repair" will verify all the files that should be installed using the current
+settings and replace any that have been removed or modified.
+
+"Uninstall" will remove Python entirely, with the exception of the
+:ref:`launcher`, which has its own entry in Programs and Features.
 
 Other Platforms
 ---------------
@@ -220,18 +245,18 @@ earlier are no longer supported (due to the lack of users or developers).
 Check :pep:`11` for details on all unsupported platforms.
 
 * `Windows CE <http://pythonce.sourceforge.net/>`_ is still supported.
-* The `Cygwin <http://cygwin.com/>`_ installer offers to install the Python
+* The `Cygwin <https://cygwin.com/>`_ installer offers to install the Python
   interpreter as well (cf. `Cygwin package source
   <ftp://ftp.uni-erlangen.de/pub/pc/gnuwin32/cygwin/mirrors/cygnus/
   release/python>`_, `Maintainer releases
   <http://www.tishler.net/jason/software/python/>`_)
 
-See `Python for Windows <https://www.python.org/download/windows/>`_
+See `Python for Windows <https://www.python.org/downloads/windows/>`_
 for detailed information about platforms with pre-compiled installers.
 
 .. seealso::
 
-   `Python on XP <http://www.richarddooling.com/index.php/2006/03/14/python-on-xp-7-minutes-to-hello-world/>`_
+   `Python on XP <http://dooling.com/index.php/2006/03/14/python-on-xp-7-minutes-to-hello-world/>`_
       "7 Minutes to "Hello World!""
       by Richard Dooling, 2006
 
@@ -241,9 +266,9 @@ for detailed information about platforms with pre-compiled installers.
       by Mark Pilgrim, 2004,
       ISBN 1-59059-356-1
 
-   `For Windows users <http://www.swaroopch.com/notes/python/#install_windows>`_
+   `For Windows users <http://python.swaroopch.com/installation.html#installation-on-windows>`_
       in "Installing Python"
-      in "`A Byte of Python <http://www.swaroopch.com/notes/python/>`_"
+      in "`A Byte of Python <http://python.swaroopch.com/>`_"
       by Swaroop C H, 2003
 
 
@@ -254,10 +279,10 @@ Besides the standard CPython distribution, there are modified packages including
 additional functionality.  The following is a list of popular versions and their
 key features:
 
-`ActivePython <http://www.activestate.com/activepython/>`_
+`ActivePython <https://www.activestate.com/activepython/>`_
     Installer with multi-platform compatibility, documentation, PyWin32
 
-`Anaconda <http://www.continuum.io/downloads/>`_
+`Anaconda <https://www.continuum.io/downloads/>`_
     Popular scientific modules (such as numpy, scipy and pandas) and the
     ``conda`` package manager.
 
@@ -327,19 +352,19 @@ System variables, you need non-restricted access to your machine
 
 .. seealso::
 
-    http://support.microsoft.com/kb/100843
+    https://support.microsoft.com/kb/100843
       Environment variables in Windows NT
 
-    http://technet.microsoft.com/en-us/library/cc754250.aspx
+    https://technet.microsoft.com/en-us/library/cc754250.aspx
       The SET command, for temporarily modifying environment variables
 
-    http://technet.microsoft.com/en-us/library/cc755104.aspx
+    https://technet.microsoft.com/en-us/library/cc755104.aspx
       The SETX command, for permanently modifying environment variables
 
-    http://support.microsoft.com/kb/310519
+    https://support.microsoft.com/kb/310519
       How To Manage Environment Variables in Windows XP
 
-    http://www.chem.gla.ac.uk/~louis/software/faq/q1.html
+    https://www.chem.gla.ac.uk/~louis/software/faq/q1.html
       Setting Environment variables, Louis J. Farrugia
 
 .. _windows-path-mod:
@@ -756,18 +781,18 @@ The Windows-specific standard modules are documented in
 PyWin32
 -------
 
-The `PyWin32 <http://python.net/crew/mhammond/win32/>`_ module by Mark Hammond
+The `PyWin32 <https://pypi.python.org/pypi/pywin32>`_ module by Mark Hammond
 is a collection of modules for advanced Windows-specific support.  This includes
 utilities for:
 
-* `Component Object Model <http://www.microsoft.com/com/>`_ (COM)
+* `Component Object Model <https://www.microsoft.com/com/>`_ (COM)
 * Win32 API calls
 * Registry
 * Event log
-* `Microsoft Foundation Classes <http://msdn.microsoft.com/en-us/library/fe1cf721%28VS.80%29.aspx>`_ (MFC)
+* `Microsoft Foundation Classes <https://msdn.microsoft.com/en-us/library/fe1cf721%28VS.80%29.aspx>`_ (MFC)
   user interfaces
 
-`PythonWin <http://web.archive.org/web/20060524042422/
+`PythonWin <https://web.archive.org/web/20060524042422/
 https://www.python.org/windows/pythonwin/>`_ is a sample MFC application
 shipped with PyWin32.  It is an embeddable IDE with a built-in debugger.
 
@@ -806,7 +831,7 @@ Compiling Python on Windows
 ===========================
 
 If you want to compile CPython yourself, first thing you should do is get the
-`source <https://www.python.org/download/source/>`_. You can download either the
+`source <https://www.python.org/downloads/source/>`_. You can download either the
 latest release's source or just grab a fresh `checkout
 <https://docs.python.org/devguide/setup.html#getting-the-source-code>`_.
 
@@ -849,7 +874,7 @@ dependants, such as Idle), pip and the Python documentation are not included.
 .. note::
 
     The embedded distribution does not include the `Microsoft C Runtime
-    <http://www.microsoft.com/en-us/download/details.aspx?id=48145>`_ and it is
+    <https://www.microsoft.com/en-us/download/details.aspx?id=48145>`_ and it is
     the responsibility of the application installer to provide this. The
     runtime may have already been installed on a user's system previously or
     automatically via Windows Update, and can be detected by finding
index 10bb29e..87462f3 100644 (file)
@@ -61,7 +61,7 @@ how Python is developed: in May 2000 the Python developers began using the tools
 made available by SourceForge for storing  source code, tracking bug reports,
 and managing the queue of patch submissions.  To report bugs or submit patches
 for Python 2.0, use the bug tracking and patch manager tools available from
-Python's project page, located at http://sourceforge.net/projects/python/.
+Python's project page, located at https://sourceforge.net/projects/python/.
 
 The most important of the services now hosted at SourceForge is the Python CVS
 tree, the version-controlled repository containing the source code for Python.
@@ -130,7 +130,7 @@ Guidelines":
 Read the rest of PEP 1 for the details of the PEP editorial process, style, and
 format.  PEPs are kept in the Python CVS tree on SourceForge, though they're not
 part of the Python 2.0 distribution, and are also available in HTML form from
-https://www.python.org/peps/.  As of September 2000, there are 25 PEPS, ranging
+https://www.python.org/dev/peps/.  As of September 2000, there are 25 PEPS, ranging
 from PEP 201, "Lockstep Iteration", to PEP 225, "Elementwise/Objectwise
 Operators".
 
@@ -337,7 +337,7 @@ comprehension below is a syntax error, while the second one is correct::
    [ (x,y) for x in seq1 for y in seq2]
 
 The idea of list comprehensions originally comes from the functional programming
-language Haskell (http://www.haskell.org).  Greg Ewing argued most effectively
+language Haskell (https://www.haskell.org).  Greg Ewing argued most effectively
 for adding them to Python and wrote the initial list comprehension patch, which
 was then discussed for a seemingly endless time on the python-dev mailing list
 and kept up-to-date by Skip Montanaro.
index 6de5bf5..e55eaac 100644 (file)
@@ -562,7 +562,7 @@ You can start creating packages containing :file:`PKG-INFO` even if you're not
 using Python 2.1, since a new release of the Distutils will be made for users of
 earlier Python versions.  Version 1.0.2 of the Distutils includes the changes
 described in PEP 241, as well as various bugfixes and enhancements.  It will be
-available from  the Distutils SIG at https://www.python.org/sigs/distutils-sig/.
+available from the Distutils SIG at https://www.python.org/community/sigs/current/distutils-sig/.
 
 
 .. seealso::
@@ -731,7 +731,7 @@ of the more notable changes are:
          ...
 
   For a fuller discussion of the line I/O changes, see the python-dev summary for
-  January 1-15, 2001 at https://www.python.org/dev/summary/2001-01-1/.
+  January 1-15, 2001 at https://mail.python.org/pipermail/python-dev/2001-January/.
 
 * A new method, :meth:`popitem`, was added to dictionaries to enable
   destructively iterating through the contents of a dictionary; this can be faster
index f3c4a91..885fd60 100644 (file)
@@ -24,8 +24,8 @@ up irregularities and dark corners of the language design.
 This article doesn't attempt to provide a complete specification of the new
 features, but instead provides a convenient overview.  For full details, you
 should refer to the documentation for Python 2.2, such as the `Python Library
-Reference <https://www.python.org/doc/2.2/lib/lib.html>`_ and the `Python
-Reference Manual <https://www.python.org/doc/2.2/ref/ref.html>`_.  If you want to
+Reference <https://docs.python.org/2.2/lib/lib.html>`_ and the `Python
+Reference Manual <https://docs.python.org/2.2/ref/ref.html>`_.  If you want to
 understand the complete implementation and design rationale for a change, refer
 to the PEP for a particular new feature.
 
@@ -395,7 +395,7 @@ This section has just been a quick overview of the new features, giving enough
 of an explanation to start you programming, but many details have been
 simplified or ignored.  Where should you go to get a more complete picture?
 
-https://www.python.org/2.2/descrintro.html is a lengthy tutorial introduction to
+https://docs.python.org/dev/howto/descriptor.html is a lengthy tutorial introduction to
 the descriptor features, written by Guido van Rossum. If my description has
 whetted your appetite, go read this tutorial next, because it goes into much
 more detail about the new features while still remaining quite easy to read.
@@ -632,10 +632,10 @@ queen threatens another) and the Knight's Tour (a route that takes a knight to
 every square of an $NxN$ chessboard without visiting any square twice).
 
 The idea of generators comes from other programming languages, especially Icon
-(http://www.cs.arizona.edu/icon/), where the idea of generators is central.  In
+(https://www.cs.arizona.edu/icon/), where the idea of generators is central.  In
 Icon, every expression and function call behaves like a generator.  One example
 from "An Overview of the Icon Programming Language" at
-http://www.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks
+https://www.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks
 like::
 
    sentence := "Store it in the neighboring harbor"
@@ -720,7 +720,7 @@ possible types of the operands.
 
 (The controversy is over whether this is *really* a design flaw, and whether
 it's worth breaking existing code to fix this.  It's caused endless discussions
-on python-dev, and in July 2001 erupted into an storm of acidly sarcastic
+on python-dev, and in July 2001 erupted into a storm of acidly sarcastic
 postings on :newsgroup:`comp.lang.python`. I won't argue for either side here
 and will stick to describing what's  implemented in 2.2.  Read :pep:`238` for a
 summary of arguments and counter-arguments.)
@@ -758,7 +758,7 @@ Here are the changes 2.2 introduces:
   operators.
 
 * Python 2.2 supports some command-line arguments for testing whether code will
-  works with the changed division semantics.  Running python with :option:`-Q
+  work with the changed division semantics.  Running python with :option:`-Q
   warn` will cause a warning to be issued whenever division is applied to two
   integers.  You can use this to find code that's affected by the change and fix
   it.  By default, Python 2.2 will simply perform classic division without a
index 9d99074..b8cdcf1 100644 (file)
@@ -218,10 +218,10 @@ queen threatens another) and the Knight's Tour (a route that takes a knight to
 every square of an $NxN$ chessboard without visiting any square twice).
 
 The idea of generators comes from other programming languages, especially Icon
-(http://www.cs.arizona.edu/icon/), where the idea of generators is central.  In
+(https://www.cs.arizona.edu/icon/), where the idea of generators is central.  In
 Icon, every expression and function call behaves like a generator.  One example
 from "An Overview of the Icon Programming Language" at
-http://www.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks
+https://www.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks
 like::
 
    sentence := "Store it in the neighboring harbor"
@@ -1057,7 +1057,7 @@ Here are all of the changes that Python 2.3 makes to the core Python language.
 * A new warning, :exc:`PendingDeprecationWarning` was added to indicate features
   which are in the process of being deprecated.  The warning will *not* be printed
   by default.  To check for use of features that will be deprecated in the future,
-  supply :option:`-Walways::PendingDeprecationWarning::` on the command line or
+  supply :option:`-Walways::PendingDeprecationWarning:: <-W>` on the command line or
   use :func:`warnings.filterwarnings`.
 
 * The process of deprecating string-based exceptions, as in ``raise "Error
@@ -1080,9 +1080,9 @@ Here are all of the changes that Python 2.3 makes to the core Python language.
   hierarchy.  Classic classes are unaffected by this change.  Python 2.2
   originally used a topological sort of a class's ancestors, but 2.3 now uses the
   C3 algorithm as described in the paper `"A Monotonic Superclass Linearization
-  for Dylan" <http://www.webcom.com/haahr/dylan/linearization-oopsla96.html>`_. To
+  for Dylan" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To
   understand the motivation for this change,  read Michele Simionato's article
-  `"Python 2.3 Method Resolution Order" <https://www.python.org/2.3/mro.html>`_, or
+  `"Python 2.3 Method Resolution Order" <http://www.phyast.pitt.edu/~micheles/mro.html>`_, or
   read the thread on python-dev starting with the message at
   https://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele
   Pedroni first pointed out the problem and also implemented the fix by coding the
@@ -1306,7 +1306,7 @@ complete list of changes, or look through the CVS logs for all the details.
   partially sorted order such that, for every index *k*, ``heap[k] <=
   heap[2*k+1]`` and ``heap[k] <= heap[2*k+2]``.  This makes it quick to remove the
   smallest item, and inserting a new item while maintaining the heap property is
-  O(lg n).  (See http://www.nist.gov/dads/HTML/priorityque.html for more
+  O(lg n).  (See https://xlinux.nist.gov/dads//HTML/priorityque.html for more
   information about the priority queue data structure.)
 
   The :mod:`heapq` module provides :func:`heappush` and :func:`heappop` functions
@@ -1734,7 +1734,7 @@ The optparse Module
 The :mod:`getopt` module provides simple parsing of command-line arguments.  The
 new :mod:`optparse` module (originally named Optik) provides more elaborate
 command-line parsing that follows the Unix conventions, automatically creates
-the output for :option:`--help`, and can perform different actions for different
+the output for :option:`!--help`, and can perform different actions for different
 options.
 
 You start by creating an instance of :class:`OptionParser` and telling it what
@@ -1858,7 +1858,7 @@ and bundle it with the source of your extension.
 
 .. seealso::
 
-   https://svn.python.org/view/python/trunk/Objects/obmalloc.c
+   https://hg.python.org/cpython/file/default/Objects/obmalloc.c
       For the full details of the pymalloc implementation, see the comments at
       the top of the file :file:`Objects/obmalloc.c` in the Python source code.
       The above link points to the file within the python.org SVN browser.
@@ -1949,7 +1949,7 @@ The RPM spec files, found in the :file:`Misc/RPM/` directory in the Python
 source distribution, were updated for 2.3.  (Contributed by Sean Reifschneider.)
 
 Other new platforms now supported by Python include AtheOS
-(http://www.atheos.cx/), GNU/Hurd, and OpenVMS.
+(http://atheos.cx/), GNU/Hurd, and OpenVMS.
 
 .. ======================================================================
 
@@ -1973,7 +1973,7 @@ Some of the more notable changes are:
   the Python program as part of its execution.
 
 * The :file:`regrtest.py` script now provides a way to allow "all resources
-  except *foo*."  A resource name passed to the :option:`-u` option can now be
+  except *foo*."  A resource name passed to the :option:`!-u` option can now be
   prefixed with a hyphen (``'-'``) to mean "remove this resource."  For example,
   the option '``-uall,-bsddb``' could be used to enable the use of all resources
   except ``bsddb``.
index 569e5e9..fb4558b 100644 (file)
@@ -337,7 +337,7 @@ returned.
       wrote patches implementing function decorators, but the one that was actually
       checked in was patch #979728, written by Mark Russell.
 
-   https://www.python.org/moin/PythonDecoratorLibrary
+   https://wiki.python.org/moin/PythonDecoratorLibrary
       This Wiki page contains several examples of decorators.
 
 .. ======================================================================
@@ -687,7 +687,7 @@ includes a quick-start tutorial and a reference.
       The article uses Fortran code to illustrate many of the problems that floating-
       point inaccuracy can cause.
 
-   http://www2.hursley.ibm.com/decimal/
+   http://speleotrove.com/decimal/
       A description of a decimal-based representation.  This representation is being
       proposed as a standard, and underlies the new Python decimal type.  Much of this
       material was written by Mike Cowlishaw, designer of the Rexx language.
@@ -756,7 +756,7 @@ API that perform ASCII-only conversions, ignoring the locale setting:
   :c:type:`double` to an ASCII string.
 
 The code for these functions came from the GLib library
-(http://library.gnome.org/devel/glib/stable/), whose developers kindly
+(https://developer.gnome.org/glib/stable/), whose developers kindly
 relicensed the relevant functions and donated them to the Python Software
 Foundation.  The :mod:`locale` module  can now change the numeric locale,
 letting extensions such as GTK+  produce the correct results.
@@ -1481,10 +1481,10 @@ Some of the changes to Python's build process and to the C API are:
 
 * Python can now be built with additional profiling for the interpreter itself,
   intended as an aid to people developing the Python core.  Providing
-  :option:`----enable-profiling` to the :program:`configure` script will let you
+  :option:`--enable-profiling` to the :program:`configure` script will let you
   profile the interpreter with :program:`gprof`, and providing the
-  :option:`----with-tsc` switch enables profiling using the Pentium's Time-Stamp-
-  Counter register.  Note that the :option:`----with-tsc` switch is slightly
+  :option:`--with-tsc` switch enables profiling using the Pentium's Time-Stamp-
+  Counter register.  Note that the :option:`--with-tsc` switch is slightly
   misnamed, because the profiling feature also works on the PowerPC platform,
   though that processor architecture doesn't call that register "the TSC
   register".  (Contributed by Jeremy Hylton.)
index cb92e08..093189e 100644 (file)
@@ -330,7 +330,7 @@ statement, only the ``from ... import`` form.
    :pep:`328` - Imports: Multi-Line and Absolute/Relative
       PEP written by Aahz; implemented by Thomas Wouters.
 
-   http://codespeak.net/py/current/doc/index.html
+   https://pylib.readthedocs.org/
       The py library by Holger Krekel, which contains the :mod:`py.std` package.
 
 .. ======================================================================
@@ -547,7 +547,7 @@ exhausted.
       Earlier versions of these features were proposed in  :pep:`288` by Raymond
       Hettinger and :pep:`325` by Samuele Pedroni.
 
-   http://en.wikipedia.org/wiki/Coroutine
+   https://en.wikipedia.org/wiki/Coroutine
       The Wikipedia entry for  coroutines.
 
    http://www.sidhe.org/~dan/blog/archives/000178.html
@@ -1095,7 +1095,7 @@ Here are all of the changes that Python 2.5 makes to the core Python language.
   log all the paths searched. In Python 2.5, a new :exc:`ImportWarning` warning is
   triggered when an import would have picked up a directory as a package but no
   :file:`__init__.py` was found.  This warning is silently ignored by default;
-  provide the :option:`-Wd` option when running the Python executable to display
+  provide the :option:`-Wd <-W>` option when running the Python executable to display
   the warning message. (Implemented by Thomas Wouters.)
 
 * The list of base classes in a class definition can now be empty.   As an
@@ -1126,7 +1126,7 @@ or ``exit()`` will now exit the interpreter as they expect.  (Implemented by
 Georg Brandl.)
 
 The Python executable now accepts the standard long options  :option:`--help`
-and :option:`--version`; on Windows,  it also accepts the :option:`/?` option
+and :option:`--version`; on Windows,  it also accepts the :option:`/? <-?>` option
 for displaying a help message. (Implemented by Georg Brandl.)
 
 .. ======================================================================
@@ -1528,7 +1528,7 @@ complete list of changes, or look through the SVN logs for all the details.
 * The :mod:`socket` module now supports :const:`AF_NETLINK` sockets on Linux,
   thanks to a patch from Philippe Biondi.   Netlink sockets are a Linux-specific
   mechanism for communications between a user-space process and kernel code; an
-  introductory  article about them is at http://www.linuxjournal.com/article/7356.
+  introductory  article about them is at https://www.linuxjournal.com/article/7356.
   In Python code, netlink addresses are represented as a tuple of 2 integers,
   ``(pid, group_mask)``.
 
@@ -1640,7 +1640,7 @@ complete list of changes, or look through the SVN logs for all the details.
 * The :mod:`webbrowser` module received a number of enhancements. It's now
   usable as a script with ``python -m webbrowser``, taking a URL as the argument;
   there are a number of switches  to control the behaviour (:option:`-n` for a new
-  browser window,  :option:`-t` for a new tab).  New module-level functions,
+  browser window,  :option:`!-t` for a new tab).  New module-level functions,
   :func:`open_new` and :func:`open_new_tab`, were added  to support this.  The
   module's :func:`open` function supports an additional feature, an *autoraise*
   parameter that signals whether to raise the open window when possible. A number
@@ -2013,7 +2013,7 @@ This example uses the iterator form::
    >>>
 
 For more information about the SQL dialect supported by SQLite, see
-http://www.sqlite.org.
+https://www.sqlite.org.
 
 
 .. seealso::
@@ -2021,7 +2021,7 @@ http://www.sqlite.org.
    http://www.pysqlite.org
       The pysqlite web page.
 
-   http://www.sqlite.org
+   https://www.sqlite.org
       The SQLite web page; the documentation describes the syntax and the available
       data types for the supported SQL dialect.
 
@@ -2088,7 +2088,7 @@ Changes to Python's build process and to the C API include:
   provided the results of their examination of the Python source code.  The
   analysis found about 60 bugs that  were quickly fixed.  Many of the bugs were
   refcounting problems, often occurring in error-handling code.  See
-  http://scan.coverity.com for the statistics.
+  https://scan.coverity.com for the statistics.
 
 * The largest change to the C API came from :pep:`353`, which modifies the
   interpreter to use a :c:type:`Py_ssize_t` type definition instead of
index e763265..4ab1656 100644 (file)
@@ -153,10 +153,10 @@ The infrastructure committee of the Python Software Foundation
 therefore posted a call for issue trackers, asking volunteers to set
 up different products and import some of the bugs and patches from
 SourceForge.  Four different trackers were examined: `Jira
-<http://www.atlassian.com/software/jira/>`__,
-`Launchpad <http://www.launchpad.net>`__,
+<https://www.atlassian.com/software/jira/>`__,
+`Launchpad <https://launchpad.net/>`__,
 `Roundup <http://roundup.sourceforge.net/>`__, and
-`Trac <http://trac.edgewall.org/>`__.
+`Trac <https://trac.edgewall.org/>`__.
 The committee eventually settled on Jira
 and Roundup as the two candidates.  Jira is a commercial product that
 offers no-cost hosted instances to free-software projects; Roundup
@@ -217,7 +217,7 @@ the time required to finish the job.
 During the 2.6 development cycle, Georg Brandl put a lot of effort
 into building a new toolchain for processing the documentation.  The
 resulting package is called Sphinx, and is available from
-http://sphinx.pocoo.org/.
+http://sphinx-doc.org/.
 
 Sphinx concentrates on HTML output, producing attractively styled and
 modern HTML; printed output is still supported through conversion to
@@ -1431,7 +1431,7 @@ one, :func:`math.trunc`, that's been backported to Python 2.6.
    :pep:`3141` - A Type Hierarchy for Numbers
       PEP written by Jeffrey Yasskin.
 
-   `Scheme's numerical tower <http://www.gnu.org/software/guile/manual/html_node/Numerical-Tower.html#Numerical-Tower>`__, from the Guile manual.
+   `Scheme's numerical tower <https://www.gnu.org/software/guile/manual/html_node/Numerical-Tower.html#Numerical-Tower>`__, from the Guile manual.
 
    `Scheme's number datatypes <http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification.
 
@@ -1796,7 +1796,7 @@ changes, or look through the Subversion logs for all the details.
 * The :mod:`bsddb` module also has a new maintainer, Jesús Cea Avión, and the package
   is now available as a standalone package.  The web page for the package is
   `www.jcea.es/programacion/pybsddb.htm
-  <http://www.jcea.es/programacion/pybsddb.htm>`__.
+  <https://www.jcea.es/programacion/pybsddb.htm>`__.
   The plan is to remove the package from the standard library
   in Python 3.0, because its pace of releases is much more frequent than
   Python's.
@@ -1926,7 +1926,7 @@ changes, or look through the Subversion logs for all the details.
   the left to six places.  (Contributed by Skip Montanaro; :issue:`1158`.)
 
 * The :mod:`decimal` module was updated to version 1.66 of
-  `the General Decimal Specification <http://www2.hursley.ibm.com/decimal/decarith.html>`__.  New features
+  `the General Decimal Specification <http://speleotrove.com/decimal/decarith.html>`__.  New features
   include some methods for some basic mathematical functions such as
   :meth:`exp` and :meth:`log10`::
 
@@ -2889,7 +2889,7 @@ Improved SSL Support
 
 Bill Janssen made extensive improvements to Python 2.6's support for
 the Secure Sockets Layer by adding a new module, :mod:`ssl`, that's
-built atop the `OpenSSL <http://www.openssl.org/>`__ library.
+built atop the `OpenSSL <https://www.openssl.org/>`__ library.
 This new module provides more control over the protocol negotiated,
 the X.509 certificates used, and has better support for writing SSL
 servers (as opposed to clients) in Python.  The existing SSL support
@@ -3154,7 +3154,7 @@ Port-Specific Changes: Mac OS X
   :func:`macostools.touched` function to be removed because it depended on the
   :mod:`macfs` module.  (:issue:`1490190`)
 
-* Many other Mac OS modules have been deprecated and will removed in
+* Many other Mac OS modules have been deprecated and will be removed in
   Python 3.0:
   :mod:`_builtinSuites`,
   :mod:`aepack`,
index 3966cb4..702aeb4 100644 (file)
@@ -613,6 +613,9 @@ PEP 3137: The memoryview Object
 The :class:`memoryview` object provides a view of another object's
 memory content that matches the :class:`bytes` type's interface.
 
+.. doctest::
+    :options: +SKIP
+
     >>> import string
     >>> m = memoryview(string.letters)
     >>> m
@@ -628,6 +631,9 @@ memory content that matches the :class:`bytes` type's interface.
 The content of the view can be converted to a string of bytes or
 a list of integers:
 
+.. doctest::
+    :options: +SKIP
+
     >>> m2.tobytes()
     'abcdefghijklmnopqrstuvwxyz'
     >>> m2.tolist()
@@ -637,6 +643,9 @@ a list of integers:
 :class:`memoryview` objects allow modifying the underlying object if
 it's a mutable object.
 
+.. doctest::
+    :options: +SKIP
+
     >>> m2[0] = 75
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
@@ -671,6 +680,9 @@ Some smaller changes made to the core Python language are:
   ``{}`` continues to represent an empty dictionary; use
   ``set()`` for an empty set.
 
+  .. doctest::
+    :options: +SKIP
+
     >>> {1, 2, 3, 4, 5}
     set([1, 2, 3, 4, 5])
     >>> set() # empty set
@@ -684,6 +696,9 @@ Some smaller changes made to the core Python language are:
   3.x, generalizing list/generator comprehensions to use
   the literal syntax for sets and dictionaries.
 
+  .. doctest::
+    :options: +SKIP
+
     >>> {x: x*x for x in range(6)}
     {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
     >>> {('a'*x) for x in range(6)}
@@ -1029,7 +1044,7 @@ changes, or look through the Subversion logs for all the details.
 
 * Updated module: the :mod:`bsddb` module has been updated from 4.7.2devel9
   to version 4.8.4 of
-  `the pybsddb package <http://www.jcea.es/programacion/pybsddb.htm>`__.
+  `the pybsddb package <https://www.jcea.es/programacion/pybsddb.htm>`__.
   The new version features better Python 3.x compatibility, various bug fixes,
   and adds several new BerkeleyDB flags and methods.
   (Updated by Jesús Cea Avión; :issue:`8156`.  The pybsddb
@@ -1052,7 +1067,7 @@ changes, or look through the Subversion logs for all the details.
      >>> for letter in 'here is a sample of english text':
      ...   c[letter] += 1
      ...
-     >>> c
+     >>> c # doctest: +SKIP
      Counter({' ': 6, 'e': 5, 's': 3, 'a': 2, 'i': 2, 'h': 2,
      'l': 2, 't': 2, 'g': 1, 'f': 1, 'm': 1, 'o': 1, 'n': 1,
      'p': 1, 'r': 1, 'x': 1})
@@ -1157,7 +1172,7 @@ changes, or look through the Subversion logs for all the details.
 * The :mod:`ctypes` module now always converts ``None`` to a C NULL
   pointer for arguments declared as pointers.  (Changed by Thomas
   Heller; :issue:`4606`.)  The underlying `libffi library
-  <http://sourceware.org/libffi/>`__ has been updated to version
+  <https://sourceware.org/libffi/>`__ has been updated to version
   3.0.9, containing various fixes for different platforms.  (Updated
   by Matthias Klose; :issue:`8142`.)
 
@@ -1513,7 +1528,7 @@ changes, or look through the Subversion logs for all the details.
   (Contributed by Kristján Valur Jónsson; :issue:`6192` and :issue:`6267`.)
 
 * Updated module: the :mod:`sqlite3` module has been updated to
-  version 2.6.0 of the `pysqlite package <http://code.google.com/p/pysqlite/>`__. Version 2.6.0 includes a number of bugfixes, and adds
+  version 2.6.0 of the `pysqlite package <https://github.com/ghaering/pysqlite>`__. Version 2.6.0 includes a number of bugfixes, and adds
   the ability to load SQLite extensions from shared libraries.
   Call the ``enable_load_extension(True)`` method to enable extensions,
   and then call :meth:`~sqlite3.Connection.load_extension` to load a particular shared library.
@@ -1530,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
-  <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`__.
+  <https://www.openssl.org/docs/apps/ciphers.html#CIPHER-LIST-FORMAT>`__.
   (Added by Antoine Pitrou; :issue:`8322`.)
 
   Another change makes the extension load all of OpenSSL's ciphers and
@@ -1638,12 +1653,18 @@ changes, or look through the Subversion logs for all the details.
   worked around the old behaviour.  For example, Python 2.6.4 or 2.5
   will return the following:
 
+  .. doctest::
+    :options: +SKIP
+
     >>> import urlparse
     >>> urlparse.urlsplit('invented://host/filename?query')
     ('invented', '', '//host/filename?query', '', '')
 
   Python 2.7 (and Python 2.6.5) will return:
 
+  .. doctest::
+    :options: +SKIP
+
     >>> import urlparse
     >>> urlparse.urlsplit('invented://host/filename?query')
     ('invented', 'host', '/filename?query', '', '')
@@ -1652,7 +1673,10 @@ changes, or look through the Subversion logs for all the details.
   returns a named tuple instead of a standard tuple.)
 
   The :mod:`urlparse` module also supports IPv6 literal addresses as defined by
-  :rfc:`2732` (contributed by Senthil Kumaran; :issue:`2987`). ::
+  :rfc:`2732` (contributed by Senthil Kumaran; :issue:`2987`).
+
+  .. doctest::
+    :options: +SKIP
 
     >>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo')
     ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]',
@@ -1783,7 +1807,7 @@ on being added to Tcl/Tck release 8.5.
 To learn more, read the :mod:`ttk` module documentation.  You may also
 wish to read the Tcl/Tk manual page describing the
 Ttk theme engine, available at
-http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_intro.htm. Some
+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.
 
@@ -1820,12 +1844,12 @@ Consult the :mod:`unittest` module documentation for more details.
 
 The :func:`~unittest.main` function supports some other new options:
 
-* :option:`-b` or :option:`--buffer` will buffer the standard output
+* :option:`-b <unittest -b>` or :option:`--buffer` will buffer the standard output
   and standard error streams during each test.  If the test passes,
   any resulting output will be discarded; on failure, the buffered
   output will be displayed.
 
-* :option:`-c` or :option:`--catch` will cause the control-C interrupt
+* :option:`-c <unittest -c>` or :option:`--catch` will cause the control-C interrupt
   to be handled more gracefully.  Instead of interrupting the test
   process immediately, the currently running test will be completed
   and then the partial results up to the interruption will be reported.
@@ -1839,7 +1863,7 @@ The :func:`~unittest.main` function supports some other new options:
   :func:`~unittest.removeHandler` decorator that can be used to mark tests that
   should have the control-C handling disabled.
 
-* :option:`-f` or :option:`--failfast` makes
+* :option:`-f <unittest -f>` or :option:`--failfast` makes
   test execution stop immediately when a test fails instead of
   continuing to execute further tests.  (Suggested by Cliff Dyer and
   implemented by Michael Foord; :issue:`8074`.)
@@ -2079,7 +2103,7 @@ Changes to Python's build process and to the C API include:
 
 * The latest release of the GNU Debugger, GDB 7, can be `scripted
   using Python
-  <http://sourceware.org/gdb/current/onlinedocs/gdb/Python.html>`__.
+  <https://sourceware.org/gdb/current/onlinedocs/gdb/Python.html>`__.
   When you begin debugging an executable program P, GDB will look for
   a file named ``P-gdb.py`` and automatically read it.  Dave Malcolm
   contributed a :file:`python-gdb.py` that adds a number of
@@ -2149,7 +2173,7 @@ Changes to Python's build process and to the C API include:
   with *updatepath* set to false.
 
   Security issue reported as `CVE-2008-5983
-  <http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983>`_;
+  <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983>`_;
   discussed in :issue:`5753`, and fixed by Antoine Pitrou.
 
 * New macros: the Python header files now define the following macros:
@@ -2381,7 +2405,7 @@ Other Changes and Fixes
   takes an integer specifying how many tests run in parallel. This
   allows reducing the total runtime on multi-core machines.
   This option is compatible with several other options, including the
-  :option:`-R` switch which is known to produce long runtimes.
+  :option:`!-R` switch which is known to produce long runtimes.
   (Added by Antoine Pitrou, :issue:`6152`.)  This can also be used
   with a new :option:`-F` switch that runs selected tests in a loop
   until they fail.  (Added by Antoine Pitrou; :issue:`7312`.)
@@ -2475,12 +2499,18 @@ In the standard library:
   worked around the old behaviour.  For example, Python 2.6.4 or 2.5
   will return the following:
 
+  .. doctest::
+    :options: +SKIP
+
     >>> import urlparse
     >>> urlparse.urlsplit('invented://host/filename?query')
     ('invented', '', '//host/filename?query', '', '')
 
   Python 2.7 (and Python 2.6.5) will return:
 
+  .. doctest::
+    :options: +SKIP
+
     >>> import urlparse
     >>> urlparse.urlsplit('invented://host/filename?query')
     ('invented', 'host', '/filename?query', '', '')
index 9941130..044d7be 100644 (file)
@@ -204,11 +204,11 @@ Python 3.0 has simplified the rules for ordering comparisons:
 Integers
 --------
 
-* :pep:`0237`: Essentially, :class:`long` renamed to :class:`int`.
+* :pep:`237`: Essentially, :class:`long` renamed to :class:`int`.
   That is, there is only one built-in integral type, named
   :class:`int`; but it behaves mostly like the old :class:`long` type.
 
-* :pep:`0238`: An expression like ``1/2`` returns a float.  Use
+* :pep:`238`: An expression like ``1/2`` returns a float.  Use
   ``1//2`` to get the truncating behavior.  (The latter syntax has
   existed for years, at least since Python 2.2.)
 
@@ -384,7 +384,7 @@ New Syntax
 
 * Dictionary comprehensions: ``{k: v for k, v in stuff}`` means the
   same thing as ``dict(stuff)`` but is more flexible.  (This is
-  :pep:`0274` vindicated. :-)
+  :pep:`274` vindicated. :-)
 
 * Set literals, e.g. ``{1, 2}``.  Note that ``{}`` is an empty
   dictionary; use ``set()`` for an empty set.  Set comprehensions are
@@ -469,7 +469,7 @@ Removed Syntax
 
 * The only acceptable syntax for relative imports is :samp:`from .[{module}]
   import {name}`.  All :keyword:`import` forms not starting with ``.`` are
-  interpreted as absolute imports.  (:pep:`0328`)
+  interpreted as absolute imports.  (:pep:`328`)
 
 * Classic classes are gone.
 
@@ -555,9 +555,9 @@ review:
 
 * Many old modules were removed.  Some, like :mod:`gopherlib` (no
   longer used) and :mod:`md5` (replaced by :mod:`hashlib`), were
-  already deprecated by :pep:`0004`.  Others were removed as a result
+  already deprecated by :pep:`4`.  Others were removed as a result
   of the removal of support for various platforms such as Irix, BeOS
-  and Mac OS 9 (see :pep:`0011`).  Some modules were also selected for
+  and Mac OS 9 (see :pep:`11`).  Some modules were also selected for
   removal in Python 3.0 due to lack of use or because a better
   replacement exists.  See :pep:`3108` for an exhaustive list.
 
@@ -565,10 +565,10 @@ review:
   core standard library has proved over time to be a particular burden
   for the core developers due to testing instability and Berkeley DB's
   release schedule.  However, the package is alive and well,
-  externally maintained at http://www.jcea.es/programacion/pybsddb.htm.
+  externally maintained at https://www.jcea.es/programacion/pybsddb.htm.
 
 * Some modules were renamed because their old name disobeyed
-  :pep:`0008`, or for various other reasons.  Here's the list:
+  :pep:`8`, or for various other reasons.  Here's the list:
 
   =======================  =======================
   Old Name                 New Name
@@ -685,7 +685,7 @@ Changes To Exceptions
 The APIs for raising and catching exception have been cleaned up and
 new powerful features added:
 
-* :pep:`0352`: All exceptions must be derived (directly or indirectly)
+* :pep:`352`: All exceptions must be derived (directly or indirectly)
   from :exc:`BaseException`.  This is the root of the exception
   hierarchy.  This is not new as a recommendation, but the
   *requirement* to inherit from :exc:`BaseException` is new.  (Python
index 5822504..baaf797 100644 (file)
@@ -116,7 +116,7 @@ or more positional arguments is present, and making a required option::
 
 Example of calling the parser on a command string::
 
-    >>> cmd  = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
+    >>> cmd = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
     >>> result = parser.parse_args(cmd.split())
     >>> result.action
     'deploy'
@@ -212,7 +212,8 @@ loaded and called with code like this::
 
    >>> import json, logging.config
    >>> with open('conf.json') as f:
-           conf = json.load(f)
+   ...     conf = json.load(f)
+   ...
    >>> logging.config.dictConfig(conf)
    >>> logging.info("Transaction completed normally")
    INFO    : root           : Transaction completed normally
@@ -460,15 +461,15 @@ Some smaller changes made to the core Python language are:
     'The testing project status is green as of February 15, 2011'
 
     >>> class LowerCasedDict(dict):
-            def __getitem__(self, key):
-                return dict.__getitem__(self, key.lower())
+    ...     def __getitem__(self, key):
+    ...         return dict.__getitem__(self, key.lower())
     >>> lcd = LowerCasedDict(part='widgets', quantity=10)
     >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd)
     'There are 10 widgets in stock'
 
     >>> class PlaceholderDict(dict):
-            def __missing__(self, key):
-                return '<{}>'.format(key)
+    ...     def __missing__(self, key):
+    ...         return '<{}>'.format(key)
     >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict())
     'Hello <name>, welcome to <location>'
 
@@ -496,10 +497,10 @@ Some smaller changes made to the core Python language are:
   exceptions pass through::
 
     >>> class A:
-            @property
-            def f(self):
-                return 1 // 0
-
+    ...     @property
+    ...     def f(self):
+    ...         return 1 // 0
+    ...
     >>> a = A()
     >>> hasattr(a, 'f')
     Traceback (most recent call last):
@@ -537,7 +538,7 @@ Some smaller changes made to the core Python language are:
 
        def outer(x):
            def inner():
-              return x
+               return x
            inner()
            del x
 
@@ -547,12 +548,12 @@ Some smaller changes made to the core Python language are:
 
        def f():
            def print_error():
-              print(e)
+               print(e)
            try:
-              something
+               something
            except Exception as e:
-              print_error()
-              # implicit "del e" here
+               print_error()
+               # implicit "del e" here
 
   (See :issue:`4617`.)
 
@@ -769,8 +770,8 @@ functools
 
   (Contributed by Raymond Hettinger and incorporating design ideas from Jim
   Baker, Miki Tebeka, and Nick Coghlan; see `recipe 498245
-  <http://code.activestate.com/recipes/498245>`_\, `recipe 577479
-  <http://code.activestate.com/recipes/577479>`_\, :issue:`10586`, and
+  <https://code.activestate.com/recipes/498245>`_\, `recipe 577479
+  <https://code.activestate.com/recipes/577479>`_\, :issue:`10586`, and
   :issue:`10593`.)
 
 * The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
@@ -799,6 +800,7 @@ functools
         def __eq__(self, other):
             return ((self.lastname.lower(), self.firstname.lower()) ==
                     (other.lastname.lower(), other.firstname.lower()))
+
         def __lt__(self, other):
             return ((self.lastname.lower(), self.firstname.lower()) <
                     (other.lastname.lower(), other.firstname.lower()))
@@ -845,9 +847,9 @@ collections
 
 * The :class:`collections.Counter` class now has two forms of in-place
   subtraction, the existing *-=* operator for `saturating subtraction
-  <http://en.wikipedia.org/wiki/Saturation_arithmetic>`_ and the new
+  <https://en.wikipedia.org/wiki/Saturation_arithmetic>`_ and the new
   :meth:`~collections.Counter.subtract` method for regular subtraction.  The
-  former is suitable for `multisets <http://en.wikipedia.org/wiki/Multiset>`_
+  former is suitable for `multisets <https://en.wikipedia.org/wiki/Multiset>`_
   which only have positive counts, and the latter is more suitable for use cases
   that allow negative counts:
 
@@ -906,7 +908,7 @@ with multiple preconditions does not run until all of the predecessor tasks are
 complete.
 
 Barriers can work with an arbitrary number of threads.  This is a generalization
-of a `Rendezvous <http://en.wikipedia.org/wiki/Synchronous_rendezvous>`_ which
+of a `Rendezvous <https://en.wikipedia.org/wiki/Synchronous_rendezvous>`_ which
 is defined for only two threads.
 
 Implemented as a two-phase cyclic barrier, :class:`~threading.Barrier` objects
@@ -942,7 +944,7 @@ released and a :exc:`~threading.BrokenBarrierError` exception is raised::
     def get_votes(site):
         ballots = conduct_election(site)
         try:
-            all_polls_closed.wait(timeout = midnight - time.now())
+            all_polls_closed.wait(timeout=midnight - time.now())
         except BrokenBarrierError:
             lockbox = seal_ballots(ballots)
             queue.put(lockbox)
@@ -955,7 +957,7 @@ sites do not finish before midnight, the barrier times-out and the ballots are
 sealed and deposited in a queue for later handling.
 
 See `Barrier Synchronization Patterns
-<http://parlab.eecs.berkeley.edu/wiki/_media/patterns/paraplop_g1_3.pdf>`_ for
+<https://parlab.eecs.berkeley.edu/wiki/_media/patterns/paraplop_g1_3.pdf>`_ for
 more examples of how barriers can be used in parallel computing.  Also, there is
 a simple but thorough explanation of barriers in `The Little Book of Semaphores
 <http://greenteapress.com/semaphores/downey08semaphores.pdf>`_, *section 3.6*.
@@ -1043,7 +1045,7 @@ of nearly equal quantities:
 0.013765762467652909
 
 The :func:`~math.erf` function computes a probability integral or `Gaussian
-error function <http://en.wikipedia.org/wiki/Error_function>`_.  The
+error function <https://en.wikipedia.org/wiki/Error_function>`_.  The
 complementary error function, :func:`~math.erfc`, is ``1 - erf(x)``:
 
 >>> erf(1.0/sqrt(2.0))   # portion of normal distribution within 1 standard deviation
@@ -1054,7 +1056,7 @@ complementary error function, :func:`~math.erfc`, is ``1 - erf(x)``:
 1.0
 
 The :func:`~math.gamma` function is a continuous extension of the factorial
-function.  See http://en.wikipedia.org/wiki/Gamma_function for details.  Because
+function.  See https://en.wikipedia.org/wiki/Gamma_function for details.  Because
 the function is related to factorials, it grows large even for small values of
 *x*, so there is also a :func:`~math.lgamma` function for computing the natural
 logarithm of the gamma function:
@@ -1097,16 +1099,16 @@ for slice notation are well-suited to in-place editing::
     >>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11
 
     >>> def change_location(buffer, record_number, location):
-            start = record_number * REC_LEN + LOC_START
-            buffer[start: start+LOC_LEN] = location
+    ...     start = record_number * REC_LEN + LOC_START
+    ...     buffer[start: start+LOC_LEN] = location
 
     >>> import io
 
     >>> byte_stream = io.BytesIO(
-        b'G3805  storeroom  Main chassis    '
-        b'X7899  shipping   Reserve cog     '
-        b'L6988  receiving  Primary sprocket'
-    )
+    ...     b'G3805  storeroom  Main chassis    '
+    ...     b'X7899  shipping   Reserve cog     '
+    ...     b'L6988  receiving  Primary sprocket'
+    ... )
     >>> buffer = byte_stream.getbuffer()
     >>> change_location(buffer, 1, b'warehouse  ')
     >>> change_location(buffer, 0, b'showroom   ')
@@ -1131,10 +1133,10 @@ decorator, :func:`~reprlib.recursive_repr`, for detecting recursive calls to
 :meth:`__repr__` and substituting a placeholder string instead::
 
         >>> class MyList(list):
-                @recursive_repr()
-                def __repr__(self):
-                    return '<' + '|'.join(map(repr, self)) + '>'
-
+        ...     @recursive_repr()
+        ...     def __repr__(self):
+        ...         return '<' + '|'.join(map(repr, self)) + '>'
+        ...
         >>> m = MyList('abc')
         >>> m.append(m)
         >>> m.append('x')
@@ -1197,8 +1199,8 @@ the field names::
     >>> w.writeheader()
     "name","dept"
     >>> w.writerows([
-            {'name': 'tom', 'dept': 'accounting'},
-            {'name': 'susan', 'dept': 'Salesl'}])
+    ...     {'name': 'tom', 'dept': 'accounting'},
+    ...     {'name': 'susan', 'dept': 'Salesl'}])
     "tom","accounting"
     "susan","sales"
 
@@ -1423,14 +1425,14 @@ function can return *None*::
     >>> import tarfile, glob
 
     >>> def myfilter(tarinfo):
-           if tarinfo.isfile():             # only save real files
-                tarinfo.uname = 'monty'     # redact the user name
-                return tarinfo
+    ...     if tarinfo.isfile():             # only save real files
+    ...         tarinfo.uname = 'monty'      # redact the user name
+    ...         return tarinfo
 
     >>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:
-            for filename in glob.glob('*.txt'):
-                tf.add(filename, filter=myfilter)
-            tf.list()
+    ...     for filename in glob.glob('*.txt'):
+    ...         tf.add(filename, filter=myfilter)
+    ...     tf.list()
     -rw-r--r-- monty/501        902 2011-01-26 17:59:11 annotations.txt
     -rw-r--r-- monty/501        123 2011-01-26 17:59:11 general_questions.txt
     -rw-r--r-- monty/501       3514 2011-01-26 17:59:11 prion.txt
@@ -1536,26 +1538,26 @@ step is non-destructive (the original files are left unchanged).
 
     >>> import shutil, pprint
 
-    >>> os.chdir('mydata')                               # change to the source directory
+    >>> os.chdir('mydata')  # change to the source directory
     >>> f = shutil.make_archive('/var/backup/mydata',
-                                'zip')                   # archive the current directory
-    >>> f                                                # show the name of archive
+    ...                         'zip')      # archive the current directory
+    >>> f                                   # show the name of archive
     '/var/backup/mydata.zip'
-    >>> os.chdir('tmp')                                  # change to an unpacking
+    >>> os.chdir('tmp')                     # change to an unpacking
     >>> shutil.unpack_archive('/var/backup/mydata.zip')  # recover the data
 
-    >>> pprint.pprint(shutil.get_archive_formats())      # display known formats
+    >>> pprint.pprint(shutil.get_archive_formats())  # display known formats
     [('bztar', "bzip2'ed tar-file"),
      ('gztar', "gzip'ed tar-file"),
      ('tar', 'uncompressed tar file'),
      ('zip', 'ZIP file')]
 
-    >>> shutil.register_archive_format(                  # register a new archive format
-            name = 'xz',
-            function = xz.compress,                      # callable archiving function
-            extra_args = [('level', 8)],                 # arguments to the function
-            description = 'xz compression'
-    )
+    >>> shutil.register_archive_format(     # register a new archive format
+    ...     name='xz',
+    ...     function=xz.compress,           # callable archiving function
+    ...     extra_args=[('level', 8)],      # arguments to the function
+    ...     description='xz compression'
+    ... )
 
 (Contributed by Tarek Ziadé.)
 
@@ -1618,7 +1620,7 @@ for secure (encrypted, authenticated) internet connections:
 * The :func:`ssl.wrap_socket` constructor function now takes a *ciphers*
   argument.  The *ciphers* string lists the allowed encryption algorithms using
   the format described in the `OpenSSL documentation
-  <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`__.
+  <https://www.openssl.org/docs/apps/ciphers.html#CIPHER-LIST-FORMAT>`__.
 
 * When linked against recent versions of OpenSSL, the :mod:`ssl` module now
   supports the Server Name Indication extension to the TLS protocol, allowing
@@ -1854,7 +1856,7 @@ inspect
 
     >>> from inspect import getgeneratorstate
     >>> def gen():
-            yield 'demo'
+    ...     yield 'demo'
     >>> g = gen()
     >>> getgeneratorstate(g)
     'GEN_CREATED'
@@ -1874,11 +1876,11 @@ inspect
   change state while it is searching::
 
     >>> class A:
-            @property
-            def f(self):
-                print('Running')
-                return 10
-
+    ...     @property
+    ...     def f(self):
+    ...         print('Running')
+    ...         return 10
+    ...
     >>> a = A()
     >>> getattr(a, 'f')
     Running
@@ -2102,19 +2104,19 @@ Config parsers gained a new API based on the mapping protocol::
 
     >>> parser = ConfigParser()
     >>> parser.read_string("""
-    [DEFAULT]
-    location = upper left
-    visible = yes
-    editable = no
-    color = blue
-
-    [main]
-    title = Main Menu
-    color = green
-
-    [options]
-    title = Options
-    """)
+    ... [DEFAULT]
+    ... location = upper left
+    ... visible = yes
+    ... editable = no
+    ... color = blue
+    ...
+    ... [main]
+    ... title = Main Menu
+    ... color = green
+    ...
+    ... [options]
+    ... title = Options
+    ... """)
     >>> parser['main']['color']
     'green'
     >>> parser['main']['editable']
@@ -2138,24 +2140,24 @@ handler :class:`~configparser.ExtendedInterpolation`::
 
   >>> parser = ConfigParser(interpolation=ExtendedInterpolation())
   >>> parser.read_dict({'buildout': {'directory': '/home/ambv/zope9'},
-                        'custom': {'prefix': '/usr/local'}})
+  ...                   'custom': {'prefix': '/usr/local'}})
   >>> parser.read_string("""
-      [buildout]
-      parts =
-        zope9
-        instance
-      find-links =
-        ${buildout:directory}/downloads/dist
-
-      [zope9]
-      recipe = plone.recipe.zope9install
-      location = /opt/zope
-
-      [instance]
-      recipe = plone.recipe.zope9instance
-      zope9-location = ${zope9:location}
-      zope-conf = ${custom:prefix}/etc/zope.conf
-      """)
+  ... [buildout]
+  ... parts =
+  ...   zope9
+  ...   instance
+  ... find-links =
+  ...   ${buildout:directory}/downloads/dist
+  ...
+  ... [zope9]
+  ... recipe = plone.recipe.zope9install
+  ... location = /opt/zope
+  ...
+  ... [instance]
+  ... recipe = plone.recipe.zope9instance
+  ... zope9-location = ${zope9:location}
+  ... zope-conf = ${custom:prefix}/etc/zope.conf
+  ... """)
   >>> parser['buildout']['find-links']
   '\n/home/ambv/zope9/downloads/dist'
   >>> parser['instance']['zope-conf']
@@ -2180,7 +2182,7 @@ urllib.parse
 A number of usability improvements were made for the :mod:`urllib.parse` module.
 
 The :func:`~urllib.parse.urlparse` function now supports `IPv6
-<http://en.wikipedia.org/wiki/IPv6>`_ addresses as described in :rfc:`2732`:
+<https://en.wikipedia.org/wiki/IPv6>`_ addresses as described in :rfc:`2732`:
 
     >>> import urllib.parse
     >>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
@@ -2207,9 +2209,9 @@ string, then the *safe*, *encoding*, and *error* parameters are sent to
 :func:`~urllib.parse.quote_plus` for encoding::
 
     >>> urllib.parse.urlencode([
-             ('type', 'telenovela'),
-             ('name', '¿Dónde Está Elisa?')],
-             encoding='latin-1')
+    ...      ('type', 'telenovela'),
+    ...      ('name', '¿Dónde Está Elisa?')],
+    ...      encoding='latin-1')
     'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'
 
 As detailed in :ref:`parsing-ascii-encoded-bytes`, all the :mod:`urllib.parse`
@@ -2328,7 +2330,7 @@ A number of small performance enhancements have been added:
   (Contributed by Alexandre Vassalotti, Antoine Pitrou
   and the Unladen Swallow team in :issue:`9410` and :issue:`3873`.)
 
-* The `Timsort algorithm <http://en.wikipedia.org/wiki/Timsort>`_ used in
+* The `Timsort algorithm <https://en.wikipedia.org/wiki/Timsort>`_ used in
   :meth:`list.sort` and :func:`sorted` now runs faster and uses less memory
   when called with a :term:`key function`.  Previously, every element of
   a list was wrapped with a temporary object that remembered the key value
@@ -2380,7 +2382,7 @@ Unicode
 
 Python has been updated to `Unicode 6.0.0
 <http://unicode.org/versions/Unicode6.0.0/>`_.  The update to the standard adds
-over 2,000 new characters including `emoji <http://en.wikipedia.org/wiki/Emoji>`_
+over 2,000 new characters including `emoji <https://en.wikipedia.org/wiki/Emoji>`_
 symbols which are important for mobile phones.
 
 In addition, the updated standard has altered the character properties for two
@@ -2432,7 +2434,7 @@ The documentation continues to be improved.
     **Source code** :source:`Lib/functools.py`.
 
   (Contributed by Raymond Hettinger; see
-  `rationale <http://rhettinger.wordpress.com/2011/01/28/open-your-source-more/>`_.)
+  `rationale <https://rhettinger.wordpress.com/2011/01/28/open-your-source-more/>`_.)
 
 * The docs now contain more examples and recipes.  In particular, :mod:`re`
   module has an extensive section, :ref:`re-examples`.  Likewise, the
@@ -2468,7 +2470,7 @@ Code Repository
 ===============
 
 In addition to the existing Subversion code repository at http://svn.python.org
-there is now a `Mercurial <http://mercurial.selenic.com/>`_ repository at
+there is now a `Mercurial <https://www.mercurial-scm.org/>`_ repository at
 https://hg.python.org/\ .
 
 After the 3.2 release, there are plans to switch to Mercurial as the primary
@@ -2478,7 +2480,7 @@ members of the community to create and share external changesets.  See
 
 To learn to use the new version control system, see the `tutorial by Joel
 Spolsky <http://hginit.com>`_ or the `Guide to Mercurial Workflows
-<http://mercurial.selenic.com/guide>`_.
+<https://www.mercurial-scm.org/guide>`_.
 
 
 Build and C API Changes
@@ -2559,7 +2561,7 @@ Also, there were a number of updates to the Mac OS X build, see
 :source:`Mac/BuildScript/README.txt` for details.  For users running a 32/64-bit
 build, there is a known problem with the default Tcl/Tk on Mac OS X 10.6.
 Accordingly, we recommend installing an updated alternative such as
-`ActiveState Tcl/Tk 8.5.9 <http://www.activestate.com/activetcl/downloads>`_\.
+`ActiveState Tcl/Tk 8.5.9 <https://www.activestate.com/activetcl/downloads>`_\.
 See https://www.python.org/download/mac/tcltk/ for additional details.
 
 Porting to Python 3.2
index 094eff8..2096b0b 100644 (file)
@@ -440,15 +440,15 @@ return a final value to the outer generator::
     ...
     >>> tallies = []
     >>> acc = gather_tallies(tallies)
-    >>> next(acc) # Ensure the accumulator is ready to accept values
+    >>> next(acc)  # Ensure the accumulator is ready to accept values
     >>> for i in range(4):
     ...     acc.send(i)
     ...
-    >>> acc.send(None) # Finish the first tally
+    >>> acc.send(None)  # Finish the first tally
     >>> for i in range(5):
     ...     acc.send(i)
     ...
-    >>> acc.send(None) # Finish the second tally
+    >>> acc.send(None)  # Finish the second tally
     >>> tallies
     [6, 10]
 
@@ -1528,7 +1528,7 @@ by Petri Lehtinen in :issue:`12021`.)
 multiprocessing
 ---------------
 
-The new :func:`multiprocessing.connection.wait` function allows to poll
+The new :func:`multiprocessing.connection.wait` function allows polling
 multiple objects (such as connections, sockets and pipes) with a timeout.
 (Contributed by Richard Oudkerk in :issue:`12328`.)
 
@@ -1715,8 +1715,8 @@ pickle
 ------
 
 :class:`pickle.Pickler` objects now have an optional
-:attr:`~pickle.Pickler.dispatch_table` attribute allowing to set per-pickler
-reduction functions.
+:attr:`~pickle.Pickler.dispatch_table` attribute allowing per-pickler
+reduction functions to be set.
 
 (Contributed by Richard Oudkerk in :issue:`14166`.)
 
@@ -1884,13 +1884,13 @@ socket
   Heiko Wundram)
 
 * The :class:`~socket.socket` class now supports the PF_CAN protocol family
-  (http://en.wikipedia.org/wiki/Socketcan), on Linux
-  (http://lwn.net/Articles/253425).
+  (https://en.wikipedia.org/wiki/Socketcan), on Linux
+  (https://lwn.net/Articles/253425).
 
   (Contributed by Matthias Fuchs, updated by Tiago Gonçalves in :issue:`10141`.)
 
 * The :class:`~socket.socket` class now supports the PF_RDS protocol family
-  (http://en.wikipedia.org/wiki/Reliable_Datagram_Sockets and
+  (https://en.wikipedia.org/wiki/Reliable_Datagram_Sockets and
   https://oss.oracle.com/projects/rds/).
 
 * The :class:`~socket.socket` class now supports the ``PF_SYSTEM`` protocol
index 7d9bc0d..1e5c9d1 100644 (file)
@@ -144,7 +144,7 @@ Security improvements:
   all of the parent's inheritable handles, only the necessary ones.
 * A new :func:`hashlib.pbkdf2_hmac` function provides
   the `PKCS#5 password-based key derivation function 2
-  <http://en.wikipedia.org/wiki/PBKDF2>`_.
+  <https://en.wikipedia.org/wiki/PBKDF2>`_.
 * :ref:`TLSv1.1 and TLSv1.2 support <whatsnew-tls-11-12>` for :mod:`ssl`.
 * :ref:`Retrieving certificates from the Windows system cert store support
   <whatsnew34-win-cert-store>` for :mod:`ssl`.
@@ -746,7 +746,7 @@ optional *current_offset*), and the resulting object can be iterated to produce
 method, equivalent to calling :mod:`~dis.dis` on the constructor argument, but
 returned as a multi-line string::
 
-    >>> bytecode = dis.Bytecode(lambda x: x +1, current_offset=3)
+    >>> bytecode = dis.Bytecode(lambda x: x + 1, current_offset=3)
     >>> for instr in bytecode:
     ...     print('{} ({})'.format(instr.opname, instr.opcode))
     LOAD_FAST (124)
@@ -902,7 +902,7 @@ hashlib
 
 A new :func:`hashlib.pbkdf2_hmac` function provides
 the `PKCS#5 password-based key derivation function 2
-<http://en.wikipedia.org/wiki/PBKDF2>`_.  (Contributed by Christian
+<https://en.wikipedia.org/wiki/PBKDF2>`_.  (Contributed by Christian
 Heimes in :issue:`18582`.)
 
 The :attr:`~hashlib.hash.name` attribute of :mod:`hashlib` hash objects is now
@@ -1322,7 +1322,7 @@ kernel version of 2.6.36 or later and glibc of 2.13 or later, provides the
 ability to query or set the resource limits for processes other than the one
 making the call.  (Contributed by Christian Heimes in :issue:`16595`.)
 
-On Linux kernel version 2.6.36 or later, there are there are also some new
+On Linux kernel version 2.6.36 or later, there are also some new
 Linux specific constants: :attr:`~resource.RLIMIT_MSGQUEUE`,
 :attr:`~resource.RLIMIT_NICE`, :attr:`~resource.RLIMIT_RTPRIO`,
 :attr:`~resource.RLIMIT_RTTIME`, and :attr:`~resource.RLIMIT_SIGPENDING`.
@@ -1410,7 +1410,7 @@ sqlite3
 
 A new boolean parameter to the :func:`~sqlite3.connect` function, *uri*, can be
 used to indicate that the *database* parameter is a ``uri`` (see the `SQLite
-URI documentation <http://www.sqlite.org/uri.html>`_).  (Contributed by poq in
+URI documentation <https://www.sqlite.org/uri.html>`_).  (Contributed by poq in
 :issue:`13773`.)
 
 
@@ -1457,7 +1457,7 @@ s), as well as a :meth:`~ssl.SSLContext.get_ca_certs` method that returns a
 list of the loaded ``CA`` certificates.  (Contributed by Christian Heimes in
 :issue:`18147`.)
 
-If OpenSSL 0.9.8 or later is available, :class:`~ssl.SSLContext` has an new
+If OpenSSL 0.9.8 or later is available, :class:`~ssl.SSLContext` has a new
 attribute :attr:`~ssl.SSLContext.verify_flags` that can be used to control the
 certificate verification process by setting it to some combination of the new
 constants :data:`~ssl.VERIFY_DEFAULT`, :data:`~ssl.VERIFY_CRL_CHECK_LEAF`,
@@ -1917,8 +1917,8 @@ Other Build and C API Changes
   :issue:`18596`.)
 
 * The Windows build now uses `Address Space Layout Randomization
-  <http://en.wikipedia.org/wiki/ASLR>`_ and `Data Execution Prevention
-  <http://en.wikipedia.org/wiki/Data_Execution_Prevention>`_.  (Contributed by
+  <https://en.wikipedia.org/wiki/Address_space_layout_randomization>`_ and `Data Execution Prevention
+  <https://en.wikipedia.org/wiki/Data_Execution_Prevention>`_.  (Contributed by
   Christian Heimes in :issue:`16632`.)
 
 * New function :c:func:`PyObject_LengthHint` is the C API equivalent
index 73c851d..8fc2f6c 100644 (file)
@@ -247,6 +247,19 @@ be used inside a coroutine function declared with :keyword:`async def`.
 Coroutine functions are intended to be run inside a compatible event loop,
 such as the :ref:`asyncio loop <asyncio-event-loop>`.
 
+
+.. note::
+
+   .. versionchanged:: 3.5.2
+      Starting with CPython 3.5.2, ``__aiter__`` can directly return
+      :term:`asynchronous iterators <asynchronous iterator>`.  Returning
+      an :term:`awaitable` object will result in a
+      :exc:`PendingDeprecationWarning`.
+
+      See more details in the :ref:`async-iterators` documentation
+      section.
+
+
 .. seealso::
 
    :pep:`492` -- Coroutines with async and await syntax
@@ -307,7 +320,7 @@ PEP 448 - Additional Unpacking Generalizations
 
 :pep:`448` extends the allowed uses of the ``*`` iterable unpacking
 operator and ``**`` dictionary unpacking operator.  It is now possible
-to use an arbitrary number of unpackings in function calls::
+to use an arbitrary number of unpackings in :ref:`function calls <calls>`::
 
     >>> print(*[1], *[2], 3, *[4, 5])
     1 2 3 4 5
@@ -320,7 +333,7 @@ to use an arbitrary number of unpackings in function calls::
     1 2 3 4
 
 Similarly, tuple, list, set, and dictionary displays allow multiple
-unpackings::
+unpackings (see :ref:`exprlists` and :ref:`dict`)::
 
     >>> *range(4), 4
     (0, 1, 2, 3, 4)
@@ -343,8 +356,8 @@ unpackings::
 
 .. _whatsnew-pep-461:
 
-PEP 461 - % formatting support for bytes and bytearray
-------------------------------------------------------
+PEP 461 - percent formatting support for bytes and bytearray
+------------------------------------------------------------
 
 :pep:`461` adds support for the ``%``
 :ref:`interpolation operator <bytes-formatting>` to :class:`bytes`
@@ -748,7 +761,7 @@ Improved Modules
 argparse
 --------
 
-The :class:`~argparse.ArgumentParser` class now allows to disable
+The :class:`~argparse.ArgumentParser` class now allows disabling
 :ref:`abbreviated usage <prefix-matching>` of long options by setting
 :ref:`allow_abbrev` to ``False``.  (Contributed by Jonathan Paugh,
 Steven Bethard, paul j3 and Daniel Eriksson in :issue:`14910`.)
@@ -810,6 +823,46 @@ Updates in 3.5.1:
   now accept all kinds of :term:`awaitable objects <awaitable>`.
   (Contributed by Yury Selivanov.)
 
+* New :func:`~asyncio.run_coroutine_threadsafe` function to submit
+  coroutines to event loops from other threads.
+  (Contributed by Vincent Michel.)
+
+* New :meth:`Transport.is_closing() <asyncio.BaseTransport.is_closing>`
+  method to check if the transport is closing or closed.
+  (Contributed by Yury Selivanov.)
+
+* The :meth:`loop.create_server() <asyncio.BaseEventLoop.create_server>`
+  method can now accept a list of hosts.
+  (Contributed by Yann Sionneau.)
+
+Updates in 3.5.2:
+
+* New :meth:`loop.create_future() <asyncio.BaseEventLoop.create_future>`
+  method to create Future objects.  This allows alternative event
+  loop implementations, such as
+  `uvloop <https://github.com/MagicStack/uvloop>`_, to provide a faster
+  :class:`asyncio.Future` implementation.
+  (Contributed by Yury Selivanov.)
+
+* New :meth:`loop.get_exception_handler() <asyncio.BaseEventLoop.get_exception_handler>`
+  method to get the current exception handler.
+  (Contributed by Yury Selivanov.)
+
+* New :meth:`StreamReader.readuntil() <asyncio.StreamReader.readuntil>`
+  method to read data from the stream until a separator bytes
+  sequence appears.
+  (Contributed by Mark Korenberg.)
+
+* The :meth:`loop.create_connection() <asyncio.BaseEventLoop.create_connection>`
+  and :meth:`loop.create_server() <asyncio.BaseEventLoop.create_server>`
+  methods are optimized to avoid calling the system ``getaddrinfo``
+  function if the address is already resolved.
+  (Contributed by A. Jesse Jiryu Davis.)
+
+* The :meth:`loop.sock_connect(sock, address) <asyncio.BaseEventLoop.sock_connect>`
+  no longer requires the *address* to be resolved prior to the call.
+  (Contributed by A. Jesse Jiryu Davis.)
+
 
 bz2
 ---
@@ -901,12 +954,12 @@ external `PyPI package <https://pypi.python.org/pypi/backports_abc>`_.
 compileall
 ----------
 
-A new :mod:`compileall` option, :samp:`-j {N}`, allows to run *N* workers
-sumultaneously to perform parallel bytecode compilation.
+A new :mod:`compileall` option, :samp:`-j {N}`, allows running *N* workers
+simultaneously to perform parallel bytecode compilation.
 The :func:`~compileall.compile_dir` function has a corresponding ``workers``
 parameter.  (Contributed by Claudiu Popa in :issue:`16104`.)
 
-Another new option, ``-r``, allows to control the maximum recursion
+Another new option, ``-r``, allows controlling the maximum recursion
 level for subdirectories.  (Contributed by Claudiu Popa in :issue:`19628`.)
 
 The ``-q`` command line option can now be specified more than once, in
@@ -1441,8 +1494,8 @@ or newer, and ``getentropy()`` on OpenBSD 5.6 and newer, removing the need to
 use ``/dev/urandom`` and avoiding failures due to potential file descriptor
 exhaustion.  (Contributed by Victor Stinner in :issue:`22181`.)
 
-New :func:`~os.get_blocking` and :func:`~os.set_blocking` functions allow to
-get and set a file descriptor's blocking mode (:data:`~os.O_NONBLOCK`.)
+New :func:`~os.get_blocking` and :func:`~os.set_blocking` functions allow
+getting and setting a file descriptor's blocking mode (:data:`~os.O_NONBLOCK`.)
 (Contributed by Victor Stinner in :issue:`22054`.)
 
 The :func:`~os.truncate` and :func:`~os.ftruncate` functions are now supported
@@ -1651,7 +1704,7 @@ messages. (Contributed by Gavin Chappell and Maciej Szulik in :issue:`16914`.)
 
 Both the :meth:`SMTP.sendmail() <smtplib.SMTP.sendmail>` and
 :meth:`SMTP.send_message() <smtplib.SMTP.send_message>` methods now
-support support :rfc:`6531` (SMTPUTF8).
+support :rfc:`6531` (SMTPUTF8).
 (Contributed by Milan Oberkirch and R. David Murray in :issue:`22027`.)
 
 
@@ -1669,8 +1722,8 @@ socket
 Functions with timeouts now use a monotonic clock, instead of a system clock.
 (Contributed by Victor Stinner in :issue:`22043`.)
 
-A new :meth:`socket.sendfile() <socket.socket.sendfile>` method allows to
-send a file over a socket by using the high-performance :func:`os.sendfile`
+A new :meth:`socket.sendfile() <socket.socket.sendfile>` method allows
+sending a file over a socket by using the high-performance :func:`os.sendfile`
 function on UNIX, resulting in uploads being from 2 to 3 times faster than when
 using plain :meth:`socket.send() <socket.socket.send>`.
 (Contributed by Giampaolo Rodola' in :issue:`17552`.)
@@ -2157,7 +2210,7 @@ for details.)
 The :c:member:`PyTypeObject.tp_finalize` slot is now part of the stable ABI.
 
 Windows builds now require Microsoft Visual C++ 14.0, which
-is available as part of `Visual Studio 2015 <http://www.visualstudio.com>`_.
+is available as part of `Visual Studio 2015 <https://www.visualstudio.com/>`_.
 
 Extension modules now include a platform information tag in their filename on
 some platforms (the tag is optional, and CPython will import extensions without
@@ -2259,9 +2312,8 @@ class has been deprecated.
 (Contributed by Serhiy Storchaka in :issue:`23671`.)
 
 The :func:`platform.dist` and :func:`platform.linux_distribution` functions
-are now deprecated and will be removed in Python 3.7.  Linux distributions use
-too many different ways of describing themselves, so the functionality is
-left to a package.
+are now deprecated.  Linux distributions use too many different ways of
+describing themselves, so the functionality is left to a package.
 (Contributed by Vajrasky Kok and Berker Peksag in :issue:`1322`.)
 
 The previously undocumented ``from_function`` and ``from_builtin`` methods of
index 6afba09..4ff79f2 100644 (file)
@@ -192,8 +192,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
      int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v);
 
      Set the value of the attribute named attr_name, for object o,
-     to the value, v. Returns -1 on failure.  This is
-     the equivalent of the Python statement: o.attr_name=v.
+     to the value v. Raise an exception and return -1 on failure; return 0 on
+     success.  This is the equivalent of the Python statement o.attr_name=v.
 
        */
 
@@ -202,8 +202,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
      int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v);
 
      Set the value of the attribute named attr_name, for object o,
-     to the value, v. Returns -1 on failure.  This is
-     the equivalent of the Python statement: o.attr_name=v.
+     to the value v. Raise an exception and return -1 on failure; return 0 on
+     success.  This is the equivalent of the Python statement o.attr_name=v.
 
        */
 
@@ -435,9 +435,9 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
      PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v);
 
        /*
-     Map the object, key, to the value, v.  Returns
-     -1 on failure.  This is the equivalent of the Python
-     statement: o[key]=v.
+     Map the object key to the value v.  Raise an exception and return -1
+     on failure; return 0 on success.  This is the equivalent of the Python
+     statement o[key]=v.
        */
 
      PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key);
@@ -993,9 +993,9 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
      PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v);
 
        /*
-     Assign object v to the ith element of o.  Returns
-     -1 on failure.  This is the equivalent of the Python
-     statement: o[i]=v.
+     Assign object v to the ith element of o.  Raise an exception and return
+     -1 on failure; return 0 on success.  This is the equivalent of the
+     Python statement o[i]=v.
        */
 
      PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i);
@@ -1216,23 +1216,23 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
      PyAPI_FUNC(PyObject *) PyMapping_Keys(PyObject *o);
 
        /*
-     On success, return a list or tuple of the keys in object o.
-     On failure, return NULL.
+     On success, return a list, a tuple or a dictionary view in case of a dict,
+     of the keys in object o. On failure, return NULL.
        */
 
      PyAPI_FUNC(PyObject *) PyMapping_Values(PyObject *o);
 
        /*
-     On success, return a list or tuple of the values in object o.
-     On failure, return NULL.
+     On success, return a list, a tuple or a dictionary view in case of a dict,
+     of the values in object o. On failure, return NULL.
        */
 
      PyAPI_FUNC(PyObject *) PyMapping_Items(PyObject *o);
 
        /*
-     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.
+     On success, return a list, a tuple or a dictionary view in case of a dict,
+     of the items in object o, where each item is a tuple containing a key-value
+     pair. On failure, return NULL.
 
        */
 
index e379bac..6c1e0c3 100644 (file)
@@ -82,7 +82,7 @@ PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x);
 #endif
 
 /* Provides access to the internal data buffer and size of a string
-   object or the default encoded version of an Unicode object. Passing
+   object or the default encoded version of a Unicode object. Passing
    NULL as *len parameter will force the string buffer to be
    0-terminated (passing a string with embedded NULL characters will
    cause an exception).  */
index 56e6ec1..8ecf38a 100644 (file)
@@ -108,12 +108,21 @@ typedef struct _addr_pair {
         int ap_upper;
 } PyAddrPair;
 
+#ifndef Py_LIMITED_API
 /* Update *bounds to describe the first and one-past-the-last instructions in the
    same line as lasti.  Return the number of that line.
 */
-#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyCode_CheckLineNumber(PyCodeObject* co,
                                         int lasti, PyAddrPair *bounds);
+
+/* Create a comparable key used to compare constants taking in account the
+ * object type. It is used to make sure types are not coerced (e.g., float and
+ * complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms
+ *
+ * Return (type(obj), obj, ...): a tuple with variable size (at least 2 items)
+ * depending on the type and the value. The type is the first item to not
+ * compare bytes and str which can raise a BytesWarning exception. */
+PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj);
 #endif
 
 PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
index 80bd330..ba90aaf 100644 (file)
@@ -98,7 +98,7 @@ PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
 PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
 PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
 Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
-PyObject *_PyDict_SizeOf(PyDictObject *);
+Py_ssize_t _PyDict_SizeOf(PyDictObject *);
 PyObject *_PyDict_Pop(PyDictObject *, PyObject *, PyObject *);
 PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
 #define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
index 966ff1f..00c5093 100644 (file)
@@ -28,13 +28,13 @@ typedef struct _frame {
     PyObject **f_stacktop;
     PyObject *f_trace;          /* Trace function */
 
-        /* In a generator, we need to be able to swap between the exception
-           state inside the generator and the exception state of the calling
-           frame (which shouldn't be impacted when the generator "yields"
-           from an except handler).
-           These three fields exist exactly for that, and are unused for
-           non-generator frames. See the save_exc_state and swap_exc_state
-           functions in ceval.c for details of their use. */
+    /* In a generator, we need to be able to swap between the exception
+       state inside the generator and the exception state of the calling
+       frame (which shouldn't be impacted when the generator "yields"
+       from an except handler).
+       These three fields exist exactly for that, and are unused for
+       non-generator frames. See the save_exc_state and swap_exc_state
+       functions in ceval.c for details of their use. */
     PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
     /* Borrowed reference to a generator, or NULL */
     PyObject *f_gen;
index 4c71861..1ff32a8 100644 (file)
@@ -43,6 +43,7 @@ PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(struct _frame *,
 PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);
 PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
 PyObject *_PyGen_Send(PyGenObject *, PyObject *);
+PyObject *_PyGen_yf(PyGenObject *);
 PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self);
 
 #ifndef Py_LIMITED_API
@@ -53,6 +54,9 @@ typedef struct {
 PyAPI_DATA(PyTypeObject) PyCoro_Type;
 PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type;
 
+PyAPI_DATA(PyTypeObject) _PyAIterWrapper_Type;
+PyObject *_PyAIterWrapper_New(PyObject *aiter);
+
 #define PyCoro_CheckExact(op) (Py_TYPE(op) == &PyCoro_Type)
 PyObject *_PyCoro_GetAwaitableIter(PyObject *o);
 PyAPI_FUNC(PyObject *) PyCoro_New(struct _frame *,
index daa513f..31843b5 100644 (file)
@@ -2,7 +2,7 @@
 /* List object interface */
 
 /*
-Another generally useful object type is an list of object pointers.
+Another generally useful object type is a list of object pointers.
 This is a mutable type: the list items can be changed, and items can be
 added or removed.  Out-of-range indices or non-list objects are ignored.
 
index 4d286ef..50d9747 100644 (file)
@@ -134,7 +134,7 @@ typedef struct {
    usage, the string "foo" is interned, and the structures are linked. On interpreter
    shutdown, all strings are released (through _PyUnicode_ClearStaticStrings).
 
-   Alternatively, _Py_static_string allows to choose the variable name.
+   Alternatively, _Py_static_string allows choosing the variable name.
    _PyUnicode_FromId returns a borrowed reference to the interned string.
    _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
 */
@@ -846,6 +846,42 @@ PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
             Py_DECREF(_py_xdecref_tmp);               \
     } while (0)
 
+#ifndef Py_LIMITED_API
+/* Safely decref `op` and set `op` to `op2`.
+ *
+ * As in case of Py_CLEAR "the obvious" code can be deadly:
+ *
+ *     Py_DECREF(op);
+ *     op = op2;
+ *
+ * The safe way is:
+ *
+ *      Py_SETREF(op, op2);
+ *
+ * That arranges to set `op` to `op2` _before_ decref'ing, so that any code
+ * triggered as a side-effect of `op` getting torn down no longer believes
+ * `op` points to a valid object.
+ *
+ * Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of
+ * Py_DECREF.
+ */
+
+#define Py_SETREF(op, op2)                      \
+    do {                                        \
+        PyObject *_py_tmp = (PyObject *)(op);   \
+        (op) = (op2);                           \
+        Py_DECREF(_py_tmp);                     \
+    } while (0)
+
+#define Py_XSETREF(op, op2)                     \
+    do {                                        \
+        PyObject *_py_tmp = (PyObject *)(op);   \
+        (op) = (op2);                           \
+        Py_XDECREF(_py_tmp);                    \
+    } while (0)
+
+#endif /* ifndef Py_LIMITED_API */
+
 /*
 These are provided as conveniences to Python runtime embedders, so that
 they can have object code that is not dependent on Python compilation flags.
index bca4b3f..60851c1 100644 (file)
 /*--start constants--*/
 #define PY_MAJOR_VERSION       3
 #define PY_MINOR_VERSION       5
-#define PY_MICRO_VERSION       1
+#define PY_MICRO_VERSION       2
 #define PY_RELEASE_LEVEL       PY_RELEASE_LEVEL_FINAL
 #define PY_RELEASE_SERIAL      0
 
 /* Version as a string */
-#define PY_VERSION             "3.5.1"
+#define PY_VERSION             "3.5.2"
 /*--end constants--*/
 
 /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
index 892a217..89028ef 100644 (file)
@@ -30,7 +30,7 @@ typedef enum _Py_memory_order {
 } _Py_memory_order;
 
 typedef struct _Py_atomic_address {
-    _Atomic void *_value;
+    atomic_uintptr_t _value;
 } _Py_atomic_address;
 
 typedef struct _Py_atomic_int {
@@ -61,7 +61,7 @@ typedef enum _Py_memory_order {
 } _Py_memory_order;
 
 typedef struct _Py_atomic_address {
-    void *_value;
+    Py_uintptr_t _value;
 } _Py_atomic_address;
 
 typedef struct _Py_atomic_int {
@@ -98,7 +98,7 @@ typedef enum _Py_memory_order {
 } _Py_memory_order;
 
 typedef struct _Py_atomic_address {
-    void *_value;
+    Py_uintptr_t _value;
 } _Py_atomic_address;
 
 typedef struct _Py_atomic_int {
index 24e7b8d..0c28f5c 100644 (file)
@@ -66,7 +66,7 @@
       * Therefore surpress the toolbox-glue in 64-bit mode.
       */
 
-    /* In 64-bit mode setpgrp always has no argments, in 32-bit
+    /* In 64-bit mode setpgrp always has no arguments, in 32-bit
      * mode that depends on the compilation environment
      */
 #       undef SETPGRP_HAVE_ARG
index 6000b81..0499a74 100644 (file)
@@ -168,7 +168,15 @@ PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
 PyAPI_FUNC(void) _PyGILState_Reinit(void);
 #endif
 
+/* Return the current thread state. The global interpreter lock must be held.
+ * When the current thread state is NULL, this issues a fatal error (so that
+ * the caller needn't check for NULL). */
 PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);
+
+/* Similar to PyThreadState_Get(), but don't issue a fatal error
+ * if it is NULL. */
+PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
+
 PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);
 PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void);
 PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *);
index f92148d..9c2e813 100644 (file)
@@ -176,7 +176,7 @@ PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState;
 
 /* Stack size, in "pointers" (so we get extra safety margins
    on 64-bit platforms).  On a 32-bit platform, this translates
-   to a 8k margin. */
+   to an 8k margin. */
 #define PYOS_STACK_MARGIN 2048
 
 #if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1300
index 891000c..c3ecbe2 100644 (file)
@@ -48,7 +48,7 @@ PyAPI_DATA(PyTypeObject) PyTraceBack_Type;
 
    This function is signal safe. */
 
-PyAPI_DATA(void) _Py_DumpTraceback(
+PyAPI_FUNC(void) _Py_DumpTraceback(
     int fd,
     PyThreadState *tstate);
 
@@ -62,7 +62,7 @@ PyAPI_DATA(void) _Py_DumpTraceback(
 
    This function is signal safe. */
 
-PyAPI_DATA(const char*) _Py_DumpTracebackThreads(
+PyAPI_FUNC(const char*) _Py_DumpTracebackThreads(
     int fd, PyInterpreterState *interp,
     PyThreadState *current_thread);
 
index 09c9b21..533dd75 100644 (file)
@@ -823,7 +823,7 @@ PyAPI_FUNC(int) PyUnicode_WriteChar(
 PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void);
 #endif
 
-/* Resize an Unicode object. The length is the number of characters, except
+/* Resize a Unicode object. The length is the number of characters, except
    if the kind of the string is PyUnicode_WCHAR_KIND: in this case, the length
    is the number of Py_UNICODE characters.
 
@@ -844,17 +844,13 @@ PyAPI_FUNC(int) PyUnicode_Resize(
     Py_ssize_t length           /* New length */
     );
 
-/* Coerce obj to an Unicode object and return a reference with
-   *incremented* refcount.
+/* Decode obj to a Unicode object.
 
-   Coercion is done in the following way:
+   bytes, bytearray and other bytes-like objects are decoded according to the
+   given encoding and error handler. The encoding and error handler can be
+   NULL to have the interface use UTF-8 and "strict".
 
-   1. bytes, bytearray and other bytes-like objects are decoded
-      under the assumptions that they contain data using the UTF-8
-      encoding. Decoding is done in "strict" mode.
-
-   2. All other objects (including Unicode objects) raise an
-      exception.
+   All other objects (including Unicode objects) raise an exception.
 
    The API returns NULL in case of an error. The caller is responsible
    for decref'ing the returned objects.
@@ -867,13 +863,9 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromEncodedObject(
     const char *errors          /* error handling */
     );
 
-/* Coerce obj to an Unicode object and return a reference with
-   *incremented* refcount.
-
-   Unicode objects are passed back as-is (subclasses are converted to
-   true Unicode objects), all other objects are delegated to
-   PyUnicode_FromEncodedObject(obj, NULL, "strict") which results in
-   using UTF-8 encoding as basis for decoding the object.
+/* Copy an instance of a Unicode subtype to a new true Unicode object if
+   necessary. If obj is already a true Unicode object (not a subtype), return
+   the reference with *incremented* refcount.
 
    The API returns NULL in case of an error. The caller is responsible
    for decref'ing the returned objects.
@@ -981,7 +973,7 @@ _PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
     Py_ssize_t len             /* length in bytes */
     );
 
-/* Get the value of the writer as an Unicode string. Clear the
+/* Get the value of the writer as a Unicode string. Clear the
    buffer of the writer. Raise an exception and return NULL
    on error. */
 PyAPI_FUNC(PyObject *)
@@ -2052,7 +2044,7 @@ PyAPI_FUNC(PyObject *) PyUnicode_Format(
 /* Checks whether element is contained in container and return 1/0
    accordingly.
 
-   element has to coerce to an one element Unicode string. -1 is
+   element has to coerce to a one element Unicode string. -1 is
    returned in case of an error. */
 
 PyAPI_FUNC(int) PyUnicode_Contains(
diff --git a/LICENSE b/LICENSE
index 88251f5..84a3337 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -74,8 +74,9 @@ analyze, test, perform and/or display publicly, prepare derivative works,
 distribute, and otherwise use Python alone or in any derivative version,
 provided, however, that PSF's License Agreement and PSF's notice of copyright,
 i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved"
-are retained in Python alone or in any derivative version prepared by Licensee.
+2011, 2012, 2013, 2014, 2015, 2016 Python Software Foundation; All Rights
+Reserved" are retained in Python alone or in any derivative version prepared by
+Licensee.
 
 3. In the event Licensee prepares a derivative work that is based on
 or incorporates Python or any part thereof, and wants to make
index f89bb6f..fc9c9f1 100644 (file)
@@ -156,7 +156,7 @@ class AsyncIterable(metaclass=ABCMeta):
     __slots__ = ()
 
     @abstractmethod
-    async def __aiter__(self):
+    def __aiter__(self):
         return AsyncIterator()
 
     @classmethod
@@ -176,7 +176,7 @@ class AsyncIterator(AsyncIterable):
         """Return the next item or raise StopAsyncIteration when exhausted."""
         raise StopAsyncIteration
 
-    async def __aiter__(self):
+    def __aiter__(self):
         return self
 
     @classmethod
index 6e39d4a..c0e0443 100644 (file)
@@ -177,6 +177,13 @@ IMPORT_MAPPING.update({
     'DocXMLRPCServer': 'xmlrpc.server',
     'SimpleHTTPServer': 'http.server',
     'CGIHTTPServer': 'http.server',
+    # For compatibility with broken pickles saved in old Python 3 versions
+    'UserDict': 'collections',
+    'UserList': 'collections',
+    'UserString': 'collections',
+    'whichdb': 'dbm',
+    'StringIO':  'io',
+    'cStringIO': 'io',
 })
 
 REVERSE_IMPORT_MAPPING.update({
index b07e75d..13fcd8b 100644 (file)
@@ -151,13 +151,13 @@ def _find_appropriate_compiler(_config_vars):
     #    can only be found inside Xcode.app if the "Command Line Tools"
     #    are not installed.
     #
-    #    Futhermore, the compiler that can be used varies between
+    #    Furthermore, the compiler that can be used varies between
     #    Xcode releases. Up to Xcode 4 it was possible to use 'gcc-4.2'
     #    as the compiler, after that 'clang' should be used because
     #    gcc-4.2 is either not present, or a copy of 'llvm-gcc' that
     #    miscompiles Python.
 
-    # skip checks if the compiler was overriden with a CC env variable
+    # skip checks if the compiler was overridden with a CC env variable
     if 'CC' in os.environ:
         return _config_vars
 
@@ -193,7 +193,7 @@ def _find_appropriate_compiler(_config_vars):
     if cc != oldcc:
         # Found a replacement compiler.
         # Modify config vars using new compiler, if not already explicitly
-        # overriden by an env variable, preserving additional arguments.
+        # overridden by an env variable, preserving additional arguments.
         for cv in _COMPILER_CONFIG_VARS:
             if cv in _config_vars and cv not in os.environ:
                 cv_split = _config_vars[cv].split()
@@ -207,7 +207,7 @@ def _remove_universal_flags(_config_vars):
     """Remove all universal build arguments from config vars"""
 
     for cv in _UNIVERSAL_CONFIG_VARS:
-        # Do not alter a config var explicitly overriden by env var
+        # Do not alter a config var explicitly overridden by env var
         if cv in _config_vars and cv not in os.environ:
             flags = _config_vars[cv]
             flags = re.sub('-arch\s+\w+\s', ' ', flags, re.ASCII)
@@ -228,7 +228,7 @@ def _remove_unsupported_archs(_config_vars):
     # build extensions on OSX 10.7 and later with the prebuilt
     # 32-bit installer on the python.org website.
 
-    # skip checks if the compiler was overriden with a CC env variable
+    # skip checks if the compiler was overridden with a CC env variable
     if 'CC' in os.environ:
         return _config_vars
 
@@ -244,7 +244,7 @@ def _remove_unsupported_archs(_config_vars):
             # across Xcode and compiler versions, there is no reliable way
             # to be sure why it failed.  Assume here it was due to lack of
             # PPC support and remove the related '-arch' flags from each
-            # config variables not explicitly overriden by an environment
+            # config variables not explicitly overridden by an environment
             # variable.  If the error was for some other reason, we hope the
             # failure will show up again when trying to compile an extension
             # module.
@@ -292,7 +292,7 @@ def _check_for_unavailable_sdk(_config_vars):
         sdk = m.group(1)
         if not os.path.exists(sdk):
             for cv in _UNIVERSAL_CONFIG_VARS:
-                # Do not alter a config var explicitly overriden by env var
+                # Do not alter a config var explicitly overridden by env var
                 if cv in _config_vars and cv not in os.environ:
                     flags = _config_vars[cv]
                     flags = re.sub(r'-isysroot\s+\S+(?:\s|$)', ' ', flags)
index 05ba4ee..c719424 100644 (file)
@@ -252,7 +252,7 @@ class InvalidOperation(DecimalException):
 class ConversionSyntax(InvalidOperation):
     """Trying to convert badly formed string.
 
-    This occurs and signals invalid-operation if an string is being
+    This occurs and signals invalid-operation if a string is being
     converted to a number and it does not conform to the numeric string
     syntax.  The result is [0,qNaN].
     """
@@ -1102,7 +1102,7 @@ class Decimal(object):
     def __pos__(self, context=None):
         """Returns a copy, unless it is a sNaN.
 
-        Rounds the number (if more then precision digits)
+        Rounds the number (if more than precision digits)
         """
         if self._is_special:
             ans = self._check_nans(context=context)
index 37157d5..0d98b74 100644 (file)
@@ -296,8 +296,9 @@ class IOBase(metaclass=abc.ABCMeta):
     called.
 
     The basic type used for binary data read from or written to a file is
-    bytes. bytearrays are accepted too, and in some cases (such as
-    readinto) needed. Text I/O classes work with str data.
+    bytes. Other bytes-like objects are accepted as method arguments too. In
+    some cases (such as readinto), a writable object is required. Text I/O
+    classes work with str data.
 
     Note that calling any method (even inquiries) on a closed stream is
     undefined. Implementations may raise OSError in this case.
@@ -390,7 +391,7 @@ class IOBase(metaclass=abc.ABCMeta):
     def seekable(self):
         """Return a bool indicating whether object supports random access.
 
-        If False, seek(), tell() and truncate() will raise UnsupportedOperation.
+        If False, seek(), tell() and truncate() will raise OSError.
         This method may need to do a test seek().
         """
         return False
@@ -405,7 +406,7 @@ class IOBase(metaclass=abc.ABCMeta):
     def readable(self):
         """Return a bool indicating whether object was opened for reading.
 
-        If False, read() will raise UnsupportedOperation.
+        If False, read() will raise OSError.
         """
         return False
 
@@ -419,7 +420,7 @@ class IOBase(metaclass=abc.ABCMeta):
     def writable(self):
         """Return a bool indicating whether object was opened for writing.
 
-        If False, write() and truncate() will raise UnsupportedOperation.
+        If False, write() and truncate() will raise OSError.
         """
         return False
 
@@ -439,7 +440,7 @@ class IOBase(metaclass=abc.ABCMeta):
         return self.__closed
 
     def _checkClosed(self, msg=None):
-        """Internal: raise an ValueError if file is closed
+        """Internal: raise a ValueError if file is closed
         """
         if self.closed:
             raise ValueError("I/O operation on closed file."
@@ -596,7 +597,7 @@ class RawIOBase(IOBase):
             return data
 
     def readinto(self, b):
-        """Read up to len(b) bytes into bytearray b.
+        """Read bytes into a pre-allocated bytes-like object b.
 
         Returns an int representing the number of bytes read (0 for EOF), or
         None if the object is set not to block and has no data to read.
@@ -606,7 +607,8 @@ class RawIOBase(IOBase):
     def write(self, b):
         """Write the given buffer to the IO stream.
 
-        Returns the number of bytes written, which may be less than len(b).
+        Returns the number of bytes written, which may be less than the
+        length of b in bytes.
         """
         self._unsupported("write")
 
@@ -659,7 +661,7 @@ class BufferedIOBase(IOBase):
         self._unsupported("read1")
 
     def readinto(self, b):
-        """Read up to len(b) bytes into bytearray b.
+        """Read bytes into a pre-allocated bytes-like object b.
 
         Like read(), this may issue multiple reads to the underlying raw
         stream, unless the latter is 'interactive'.
@@ -673,7 +675,7 @@ class BufferedIOBase(IOBase):
         return self._readinto(b, read1=False)
 
     def readinto1(self, b):
-        """Read up to len(b) bytes into *b*, using at most one system call
+        """Read bytes into buffer *b*, using at most one system call
 
         Returns an int representing the number of bytes read (0 for EOF).
 
@@ -701,8 +703,8 @@ class BufferedIOBase(IOBase):
     def write(self, b):
         """Write the given bytes buffer to the IO stream.
 
-        Return the number of bytes written, which is never less than
-        len(b).
+        Return the number of bytes written, which is always the length of b
+        in bytes.
 
         Raises BlockingIOError if the buffer is full and the
         underlying raw stream cannot accept more data at the moment.
@@ -787,12 +789,6 @@ class _BufferedIOMixin(BufferedIOBase):
     def seekable(self):
         return self.raw.seekable()
 
-    def readable(self):
-        return self.raw.readable()
-
-    def writable(self):
-        return self.raw.writable()
-
     @property
     def raw(self):
         return self._raw
@@ -890,7 +886,8 @@ class BytesIO(BufferedIOBase):
             raise ValueError("write to closed file")
         if isinstance(b, str):
             raise TypeError("can't write str to binary stream")
-        n = len(b)
+        with memoryview(b) as view:
+            n = view.nbytes  # Size of any bytes-like object
         if n == 0:
             return 0
         pos = self._pos
@@ -982,6 +979,9 @@ class BufferedReader(_BufferedIOMixin):
         self._reset_read_buf()
         self._read_lock = Lock()
 
+    def readable(self):
+        return self.raw.readable()
+
     def _reset_read_buf(self):
         self._read_buf = b""
         self._read_pos = 0
@@ -1043,7 +1043,7 @@ class BufferedReader(_BufferedIOMixin):
                 break
             avail += len(chunk)
             chunks.append(chunk)
-        # n is more then avail only when an EOF occurred or when
+        # n is more than avail only when an EOF occurred or when
         # read() would have blocked.
         n = min(n, avail)
         out = b"".join(chunks)
@@ -1093,14 +1093,13 @@ class BufferedReader(_BufferedIOMixin):
     def _readinto(self, buf, read1):
         """Read data into *buf* with at most one system call."""
 
-        if len(buf) == 0:
-            return 0
-
         # Need to create a memoryview object of type 'b', otherwise
         # we may not be able to assign bytes to it, and slicing it
         # would create a new object.
         if not isinstance(buf, memoryview):
             buf = memoryview(buf)
+        if buf.nbytes == 0:
+            return 0
         buf = buf.cast('B')
 
         written = 0
@@ -1170,6 +1169,9 @@ class BufferedWriter(_BufferedIOMixin):
         self._write_buf = bytearray()
         self._write_lock = Lock()
 
+    def writable(self):
+        return self.raw.writable()
+
     def write(self, b):
         if self.closed:
             raise ValueError("write to closed file")
index 374923d..f84227b 100644 (file)
@@ -77,6 +77,8 @@ class LocaleTime(object):
         self.__calc_date_time()
         if _getlang() != self.lang:
             raise ValueError("locale changed during initialization")
+        if time.tzname != self.tzname or time.daylight != self.daylight:
+            raise ValueError("timezone changed during initialization")
 
     def __pad(self, seq, front):
         # Add '' to seq to either the front (is True), else the back.
@@ -161,15 +163,17 @@ class LocaleTime(object):
 
     def __calc_timezone(self):
         # Set self.timezone by using time.tzname.
-        # Do not worry about possibility of time.tzname[0] == timetzname[1]
-        # and time.daylight; handle that in strptime .
+        # Do not worry about possibility of time.tzname[0] == time.tzname[1]
+        # and time.daylight; handle that in strptime.
         try:
             time.tzset()
         except AttributeError:
             pass
-        no_saving = frozenset({"utc", "gmt", time.tzname[0].lower()})
-        if time.daylight:
-            has_saving = frozenset({time.tzname[1].lower()})
+        self.tzname = time.tzname
+        self.daylight = time.daylight
+        no_saving = frozenset({"utc", "gmt", self.tzname[0].lower()})
+        if self.daylight:
+            has_saving = frozenset({self.tzname[1].lower()})
         else:
             has_saving = frozenset()
         self.timezone = (no_saving, has_saving)
@@ -307,13 +311,15 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
 
     global _TimeRE_cache, _regex_cache
     with _cache_lock:
-
-        if _getlang() != _TimeRE_cache.locale_time.lang:
+        locale_time = _TimeRE_cache.locale_time
+        if (_getlang() != locale_time.lang or
+            time.tzname != locale_time.tzname or
+            time.daylight != locale_time.daylight):
             _TimeRE_cache = TimeRE()
             _regex_cache.clear()
+            locale_time = _TimeRE_cache.locale_time
         if len(_regex_cache) > _CACHE_MAX_SIZE:
             _regex_cache.clear()
-        locale_time = _TimeRE_cache.locale_time
         format_regex = _regex_cache.get(format)
         if not format_regex:
             try:
@@ -456,6 +462,10 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
         week_starts_Mon = True if week_of_year_start == 0 else False
         julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
                                             week_starts_Mon)
+        if julian <= 0:
+            year -= 1
+            yday = 366 if calendar.isleap(year) else 365
+            julian += yday
     # Cannot pre-calculate datetime_date() since can change in Julian
     # calculation and thus could have different value for the day of the week
     # calculation.
index c5ffad4..172a463 100644 (file)
@@ -52,6 +52,12 @@ _MIN_SCHEDULED_TIMER_HANDLES = 100
 # before cleanup of cancelled handles is performed.
 _MIN_CANCELLED_TIMER_HANDLES_FRACTION = 0.5
 
+# Exceptions which must not call the exception handler in fatal error
+# methods (_fatal_error())
+_FATAL_ERROR_IGNORE = (BrokenPipeError,
+                       ConnectionResetError, ConnectionAbortedError)
+
+
 def _format_handle(handle):
     cb = handle._callback
     if inspect.ismethod(cb) and isinstance(cb.__self__, tasks.Task):
@@ -70,49 +76,89 @@ def _format_pipe(fd):
         return repr(fd)
 
 
-def _check_resolved_address(sock, address):
-    # Ensure that the address is already resolved to avoid the trap of hanging
-    # the entire event loop when the address requires doing a DNS lookup.
-    #
-    # getaddrinfo() is slow (around 10 us per call): this function should only
-    # be called in debug mode
-    family = sock.family
+# Linux's sock.type is a bitmask that can include extra info about socket.
+_SOCKET_TYPE_MASK = 0
+if hasattr(socket, 'SOCK_NONBLOCK'):
+    _SOCKET_TYPE_MASK |= socket.SOCK_NONBLOCK
+if hasattr(socket, 'SOCK_CLOEXEC'):
+    _SOCKET_TYPE_MASK |= socket.SOCK_CLOEXEC
 
-    if family == socket.AF_INET:
-        host, port = address
-    elif family == socket.AF_INET6:
-        host, port = address[:2]
-    else:
+
+def _ipaddr_info(host, port, family, type, proto):
+    # Try to skip getaddrinfo if "host" is already an IP. Users might have
+    # handled name resolution in their own code and pass in resolved IPs.
+    if not hasattr(socket, 'inet_pton'):
         return
 
-    # On Windows, socket.inet_pton() is only available since Python 3.4
-    if hasattr(socket, 'inet_pton'):
-        # getaddrinfo() is slow and has known issue: prefer inet_pton()
-        # if available
-        try:
-            socket.inet_pton(family, host)
-        except OSError as exc:
-            raise ValueError("address must be resolved (IP address), "
-                             "got host %r: %s"
-                             % (host, exc))
+    if proto not in {0, socket.IPPROTO_TCP, socket.IPPROTO_UDP} or \
+            host is None:
+        return None
+
+    type &= ~_SOCKET_TYPE_MASK
+    if type == socket.SOCK_STREAM:
+        proto = socket.IPPROTO_TCP
+    elif type == socket.SOCK_DGRAM:
+        proto = socket.IPPROTO_UDP
     else:
-        # Use getaddrinfo(flags=AI_NUMERICHOST) to ensure that the address is
-        # already resolved.
-        type_mask = 0
-        if hasattr(socket, 'SOCK_NONBLOCK'):
-            type_mask |= socket.SOCK_NONBLOCK
-        if hasattr(socket, 'SOCK_CLOEXEC'):
-            type_mask |= socket.SOCK_CLOEXEC
+        return None
+
+    if port is None:
+        port = 0
+    elif isinstance(port, bytes):
+        if port == b'':
+            port = 0
+        else:
+            try:
+                port = int(port)
+            except ValueError:
+                # Might be a service name like b"http".
+                port = socket.getservbyname(port.decode('ascii'))
+    elif isinstance(port, str):
+        if port == '':
+            port = 0
+        else:
+            try:
+                port = int(port)
+            except ValueError:
+                # Might be a service name like "http".
+                port = socket.getservbyname(port)
+
+    if family == socket.AF_UNSPEC:
+        afs = [socket.AF_INET, socket.AF_INET6]
+    else:
+        afs = [family]
+
+    if isinstance(host, bytes):
+        host = host.decode('idna')
+    if '%' in host:
+        # Linux's inet_pton doesn't accept an IPv6 zone index after host,
+        # like '::1%lo0'.
+        return None
+
+    for af in afs:
         try:
-            socket.getaddrinfo(host, port,
-                               family=family,
-                               type=(sock.type & ~type_mask),
-                               proto=sock.proto,
-                               flags=socket.AI_NUMERICHOST)
-        except socket.gaierror as err:
-            raise ValueError("address must be resolved (IP address), "
-                             "got host %r: %s"
-                             % (host, err))
+            socket.inet_pton(af, host)
+            # The host has already been resolved.
+            return af, type, proto, '', (host, port)
+        except OSError:
+            pass
+
+    # "host" is not an IP address.
+    return None
+
+
+def _ensure_resolved(address, *, family=0, type=socket.SOCK_STREAM, proto=0,
+                     flags=0, loop):
+    host, port = address[:2]
+    info = _ipaddr_info(host, port, family, type, proto)
+    if info is not None:
+        # "host" is already a resolved IP.
+        fut = loop.create_future()
+        fut.set_result([info])
+        return fut
+    else:
+        return loop.getaddrinfo(host, port, family=family, type=type,
+                                proto=proto, flags=flags)
 
 
 def _run_until_complete_cb(fut):
@@ -167,7 +213,7 @@ class Server(events.AbstractServer):
     def wait_closed(self):
         if self.sockets is None or self._waiters is None:
             return
-        waiter = futures.Future(loop=self._loop)
+        waiter = self._loop.create_future()
         self._waiters.append(waiter)
         yield from waiter
 
@@ -201,6 +247,10 @@ class BaseEventLoop(events.AbstractEventLoop):
                 % (self.__class__.__name__, self.is_running(),
                    self.is_closed(), self.get_debug()))
 
+    def create_future(self):
+        """Create a Future object attached to the loop."""
+        return futures.Future(loop=self)
+
     def create_task(self, coro):
         """Schedule a coroutine object.
 
@@ -494,7 +544,7 @@ class BaseEventLoop(events.AbstractEventLoop):
             assert not args
             assert not isinstance(func, events.TimerHandle)
             if func._cancelled:
-                f = futures.Future(loop=self)
+                f = self.create_future()
                 f.set_result(None)
                 return f
             func, args = func._callback, func._args
@@ -584,14 +634,14 @@ class BaseEventLoop(events.AbstractEventLoop):
                 raise ValueError(
                     'host/port and sock can not be specified at the same time')
 
-            f1 = self.getaddrinfo(
-                host, port, family=family,
-                type=socket.SOCK_STREAM, proto=proto, flags=flags)
+            f1 = _ensure_resolved((host, port), family=family,
+                                  type=socket.SOCK_STREAM, proto=proto,
+                                  flags=flags, loop=self)
             fs = [f1]
             if local_addr is not None:
-                f2 = self.getaddrinfo(
-                    *local_addr, family=family,
-                    type=socket.SOCK_STREAM, proto=proto, flags=flags)
+                f2 = _ensure_resolved(local_addr, family=family,
+                                      type=socket.SOCK_STREAM, proto=proto,
+                                      flags=flags, loop=self)
                 fs.append(f2)
             else:
                 f2 = None
@@ -673,7 +723,7 @@ class BaseEventLoop(events.AbstractEventLoop):
     def _create_connection_transport(self, sock, protocol_factory, ssl,
                                      server_hostname):
         protocol = protocol_factory()
-        waiter = futures.Future(loop=self)
+        waiter = self.create_future()
         if ssl:
             sslcontext = None if isinstance(ssl, bool) else ssl
             transport = self._make_ssl_transport(
@@ -726,9 +776,9 @@ class BaseEventLoop(events.AbstractEventLoop):
                         assert isinstance(addr, tuple) and len(addr) == 2, (
                             '2-tuple is expected')
 
-                        infos = yield from self.getaddrinfo(
-                            *addr, family=family, type=socket.SOCK_DGRAM,
-                            proto=proto, flags=flags)
+                        infos = yield from _ensure_resolved(
+                            addr, family=family, type=socket.SOCK_DGRAM,
+                            proto=proto, flags=flags, loop=self)
                         if not infos:
                             raise OSError('getaddrinfo() returned empty list')
 
@@ -793,7 +843,7 @@ class BaseEventLoop(events.AbstractEventLoop):
                 raise exceptions[0]
 
         protocol = protocol_factory()
-        waiter = futures.Future(loop=self)
+        waiter = self.create_future()
         transport = self._make_datagram_transport(
             sock, protocol, r_addr, waiter)
         if self._debug:
@@ -816,9 +866,9 @@ class BaseEventLoop(events.AbstractEventLoop):
 
     @coroutine
     def _create_server_getaddrinfo(self, host, port, family, flags):
-        infos = yield from self.getaddrinfo(host, port, family=family,
+        infos = yield from _ensure_resolved((host, port), family=family,
                                             type=socket.SOCK_STREAM,
-                                            flags=flags)
+                                            flags=flags, loop=self)
         if not infos:
             raise OSError('getaddrinfo({!r}) returned empty list'.format(host))
         return infos
@@ -839,7 +889,10 @@ class BaseEventLoop(events.AbstractEventLoop):
         to host and port.
 
         The host parameter can also be a sequence of strings and in that case
-        the TCP server is bound to all hosts of the sequence.
+        the TCP server is bound to all hosts of the sequence. If a host
+        appears multiple times (possibly indirectly e.g. when hostnames
+        resolve to the same IP address), the server is only bound once to that
+        host.
 
         Return a Server object which can be used to stop the service.
 
@@ -868,7 +921,7 @@ class BaseEventLoop(events.AbstractEventLoop):
                                                   flags=flags)
                   for host in hosts]
             infos = yield from tasks.gather(*fs, loop=self)
-            infos = itertools.chain.from_iterable(infos)
+            infos = set(itertools.chain.from_iterable(infos))
 
             completed = False
             try:
@@ -929,7 +982,7 @@ class BaseEventLoop(events.AbstractEventLoop):
     @coroutine
     def connect_read_pipe(self, protocol_factory, pipe):
         protocol = protocol_factory()
-        waiter = futures.Future(loop=self)
+        waiter = self.create_future()
         transport = self._make_read_pipe_transport(pipe, protocol, waiter)
 
         try:
@@ -946,7 +999,7 @@ class BaseEventLoop(events.AbstractEventLoop):
     @coroutine
     def connect_write_pipe(self, protocol_factory, pipe):
         protocol = protocol_factory()
-        waiter = futures.Future(loop=self)
+        waiter = self.create_future()
         transport = self._make_write_pipe_transport(pipe, protocol, waiter)
 
         try:
@@ -1028,6 +1081,11 @@ class BaseEventLoop(events.AbstractEventLoop):
             logger.info('%s: %r' % (debug_log, transport))
         return transport, protocol
 
+    def get_exception_handler(self):
+        """Return an exception handler, or None if the default one is in use.
+        """
+        return self._exception_handler
+
     def set_exception_handler(self, handler):
         """Set handler as the new event loop exception handler.
 
index 73425d9..8fc253c 100644 (file)
@@ -210,6 +210,10 @@ class BaseSubprocessTransport(transports.SubprocessTransport):
             logger.info('%r exited with return code %r',
                         self, returncode)
         self._returncode = returncode
+        if self._proc.returncode is None:
+            # asyncio uses a child watcher: copy the status into the Popen
+            # object. On Python 3.6, it is required to avoid a ResourceWarning.
+            self._proc.returncode = returncode
         self._call(self._protocol.process_exited)
         self._try_finish()
 
@@ -227,7 +231,7 @@ class BaseSubprocessTransport(transports.SubprocessTransport):
         if self._returncode is not None:
             return self._returncode
 
-        waiter = futures.Future(loop=self._loop)
+        waiter = self._loop.create_future()
         self._exit_waiters.append(waiter)
         return (yield from waiter)
 
index 660b7e7..4790bb4 100644 (file)
@@ -4,6 +4,7 @@ import sys
 
 PY34 = sys.version_info >= (3, 4)
 PY35 = sys.version_info >= (3, 5)
+PY352 = sys.version_info >= (3, 5, 2)
 
 
 def flatten_list_bytes(list_of_data):
index 3a92c7d..71bc6fb 100644 (file)
@@ -27,8 +27,8 @@ _YIELD_FROM = opcode.opmap['YIELD_FROM']
 # before you define your coroutines.  A downside of using this feature
 # is that tracebacks show entries for the CoroWrapper.__next__ method
 # when _DEBUG is true.
-_DEBUG = (not sys.flags.ignore_environment
-          and bool(os.environ.get('PYTHONASYNCIODEBUG')))
+_DEBUG = (not sys.flags.ignore_environment and
+          bool(os.environ.get('PYTHONASYNCIODEBUG')))
 
 
 try:
@@ -86,7 +86,7 @@ class CoroWrapper:
     def __init__(self, gen, func=None):
         assert inspect.isgenerator(gen) or inspect.iscoroutine(gen), gen
         self.gen = gen
-        self.func = func # Used to unwrap @coroutine decorator
+        self.func = func  # Used to unwrap @coroutine decorator
         self._source_traceback = traceback.extract_stack(sys._getframe(1))
         self.__name__ = getattr(gen, '__name__', None)
         self.__qualname__ = getattr(gen, '__qualname__', None)
@@ -204,7 +204,8 @@ def coroutine(func):
         @functools.wraps(func)
         def coro(*args, **kw):
             res = func(*args, **kw)
-            if isinstance(res, futures.Future) or inspect.isgenerator(res):
+            if isinstance(res, futures.Future) or inspect.isgenerator(res) or \
+                    isinstance(res, CoroWrapper):
                 res = yield from res
             elif _AwaitableABC is not None:
                 # If 'func' returns an Awaitable (new in 3.5) we
@@ -283,10 +284,13 @@ def _format_coroutine(coro):
         coro_frame = coro.cr_frame
 
     filename = coro_code.co_filename
-    if (isinstance(coro, CoroWrapper)
-    and not inspect.isgeneratorfunction(coro.func)
-    and coro.func is not None):
-        filename, lineno = events._get_function_source(coro.func)
+    lineno = 0
+    if (isinstance(coro, CoroWrapper) and
+            not inspect.isgeneratorfunction(coro.func) and
+            coro.func is not None):
+        source = events._get_function_source(coro.func)
+        if source is not None:
+            filename, lineno = source
         if coro_frame is None:
             coro_repr = ('%s done, defined at %s:%s'
                          % (coro_name, filename, lineno))
index 176a846..c48c5be 100644 (file)
@@ -266,6 +266,9 @@ class AbstractEventLoop:
     def time(self):
         raise NotImplementedError
 
+    def create_future(self):
+        raise NotImplementedError
+
     # Method scheduling a coroutine object: create a task.
 
     def create_task(self, coro):
@@ -484,6 +487,9 @@ class AbstractEventLoop:
 
     # Error handlers.
 
+    def get_exception_handler(self):
+        raise NotImplementedError
+
     def set_exception_handler(self, handler):
         raise NotImplementedError
 
index 4dcb654..1feba4d 100644 (file)
@@ -142,7 +142,7 @@ class Future:
     def __init__(self, *, loop=None):
         """Initialize the future.
 
-        The optional event_loop argument allows to explicitly set the event
+        The optional event_loop argument allows explicitly setting the event
         loop object used by the future. If it's not provided, the future uses
         the default event loop.
         """
@@ -341,6 +341,9 @@ class Future:
             raise InvalidStateError('{}: {!r}'.format(self._state, self))
         if isinstance(exception, type):
             exception = exception()
+        if type(exception) is StopIteration:
+            raise TypeError("StopIteration interacts badly with generators "
+                            "and cannot be raised into a Future")
         self._exception = exception
         self._state = _FINISHED
         self._schedule_callbacks()
@@ -448,6 +451,8 @@ def wrap_future(future, *, loop=None):
         return future
     assert isinstance(future, concurrent.futures.Future), \
         'concurrent.futures.Future is expected, got {!r}'.format(future)
-    new_future = Future(loop=loop)
+    if loop is None:
+        loop = events.get_event_loop()
+    new_future = loop.create_future()
     _chain_future(future, new_future)
     return new_future
index 34f6bc1..741aaf2 100644 (file)
@@ -111,7 +111,7 @@ class Lock(_ContextManagerMixin):
     acquire() is a coroutine and should be called with 'yield from'.
 
     Locks also support the context management protocol.  '(yield from lock)'
-    should be used as context manager expression.
+    should be used as the context manager expression.
 
     Usage:
 
@@ -170,7 +170,7 @@ class Lock(_ContextManagerMixin):
             self._locked = True
             return True
 
-        fut = futures.Future(loop=self._loop)
+        fut = self._loop.create_future()
         self._waiters.append(fut)
         try:
             yield from fut
@@ -258,7 +258,7 @@ class Event:
         if self._value:
             return True
 
-        fut = futures.Future(loop=self._loop)
+        fut = self._loop.create_future()
         self._waiters.append(fut)
         try:
             yield from fut
@@ -320,7 +320,7 @@ class Condition(_ContextManagerMixin):
 
         self.release()
         try:
-            fut = futures.Future(loop=self._loop)
+            fut = self._loop.create_future()
             self._waiters.append(fut)
             try:
                 yield from fut
@@ -329,7 +329,13 @@ class Condition(_ContextManagerMixin):
                 self._waiters.remove(fut)
 
         finally:
-            yield from self.acquire()
+            # Must reacquire lock even if wait is cancelled
+            while True:
+                try:
+                    yield from self.acquire()
+                    break
+                except futures.CancelledError:
+                    pass
 
     @coroutine
     def wait_for(self, predicate):
@@ -433,7 +439,7 @@ class Semaphore(_ContextManagerMixin):
         True.
         """
         while self._value <= 0:
-            fut = futures.Future(loop=self._loop)
+            fut = self._loop.create_future()
             self._waiters.append(fut)
             try:
                 yield from fut
index 7eac41e..3ac314c 100644 (file)
@@ -90,7 +90,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin,
                 self.close()
 
     def _fatal_error(self, exc, message='Fatal error on pipe transport'):
-        if isinstance(exc, (BrokenPipeError, ConnectionResetError)):
+        if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
             if self._loop.get_debug():
                 logger.debug("%r: %s", self, message, exc_info=True)
         else:
@@ -440,15 +440,7 @@ class BaseProactorEventLoop(base_events.BaseEventLoop):
         return self._proactor.send(sock, data)
 
     def sock_connect(self, sock, address):
-        try:
-            if self._debug:
-                base_events._check_resolved_address(sock, address)
-        except ValueError as err:
-            fut = futures.Future(loop=self)
-            fut.set_exception(err)
-            return fut
-        else:
-            return self._proactor.connect(sock, address)
+        return self._proactor.connect(sock, address)
 
     def sock_accept(self, sock):
         return self._proactor.accept(sock)
index e3a1d5e..c453f02 100644 (file)
@@ -128,7 +128,7 @@ class Queue:
         This method is a coroutine.
         """
         while self.full():
-            putter = futures.Future(loop=self._loop)
+            putter = self._loop.create_future()
             self._putters.append(putter)
             try:
                 yield from putter
@@ -162,7 +162,7 @@ class Queue:
         This method is a coroutine.
         """
         while self.empty():
-            getter = futures.Future(loop=self._loop)
+            getter = self._loop.create_future()
             self._getters.append(getter)
             try:
                 yield from getter
index a05f81c..9564d01 100644 (file)
@@ -196,7 +196,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
         transport = None
         try:
             protocol = protocol_factory()
-            waiter = futures.Future(loop=self)
+            waiter = self.create_future()
             if sslcontext:
                 transport = self._make_ssl_transport(
                     conn, protocol, sslcontext, waiter=waiter,
@@ -314,7 +314,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
         """
         if self._debug and sock.gettimeout() != 0:
             raise ValueError("the socket must be non-blocking")
-        fut = futures.Future(loop=self)
+        fut = self.create_future()
         self._sock_recv(fut, False, sock, n)
         return fut
 
@@ -352,7 +352,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
         """
         if self._debug and sock.gettimeout() != 0:
             raise ValueError("the socket must be non-blocking")
-        fut = futures.Future(loop=self)
+        fut = self.create_future()
         if data:
             self._sock_sendall(fut, False, sock, data)
         else:
@@ -385,25 +385,28 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
     def sock_connect(self, sock, address):
         """Connect to a remote socket at address.
 
-        The address must be already resolved to avoid the trap of hanging the
-        entire event loop when the address requires doing a DNS lookup. For
-        example, it must be an IP address, not an hostname, for AF_INET and
-        AF_INET6 address families. Use getaddrinfo() to resolve the hostname
-        asynchronously.
-
         This method is a coroutine.
         """
         if self._debug and sock.gettimeout() != 0:
             raise ValueError("the socket must be non-blocking")
-        fut = futures.Future(loop=self)
+
+        fut = self.create_future()
+        if hasattr(socket, 'AF_UNIX') and sock.family == socket.AF_UNIX:
+            self._sock_connect(fut, sock, address)
+        else:
+            resolved = base_events._ensure_resolved(address, loop=self)
+            resolved.add_done_callback(
+                lambda resolved: self._on_resolved(fut, sock, resolved))
+
+        return fut
+
+    def _on_resolved(self, fut, sock, resolved):
         try:
-            if self._debug:
-                base_events._check_resolved_address(sock, address)
-        except ValueError as err:
-            fut.set_exception(err)
+            _, _, _, _, address = resolved.result()[0]
+        except Exception as exc:
+            fut.set_exception(exc)
         else:
             self._sock_connect(fut, sock, address)
-        return fut
 
     def _sock_connect(self, fut, sock, address):
         fd = sock.fileno()
@@ -454,7 +457,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
         """
         if self._debug and sock.gettimeout() != 0:
             raise ValueError("the socket must be non-blocking")
-        fut = futures.Future(loop=self)
+        fut = self.create_future()
         self._sock_accept(fut, False, sock)
         return fut
 
@@ -566,6 +569,7 @@ class _SelectorTransport(transports._FlowControlMixin,
         self._loop.remove_reader(self._sock_fd)
         if not self._buffer:
             self._conn_lost += 1
+            self._loop.remove_writer(self._sock_fd)
             self._loop.call_soon(self._call_connection_lost, None)
 
     # On Python 3.3 and older, objects with a destructor part of a reference
@@ -579,8 +583,7 @@ class _SelectorTransport(transports._FlowControlMixin,
 
     def _fatal_error(self, exc, message='Fatal error on transport'):
         # Should be called from exception handler only.
-        if isinstance(exc, (BrokenPipeError,
-                            ConnectionResetError, ConnectionAbortedError)):
+        if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
             if self._loop.get_debug():
                 logger.debug("%r: %s", self, message, exc_info=True)
         else:
@@ -660,6 +663,8 @@ class _SelectorSocketTransport(_SelectorTransport):
             logger.debug("%r resumes reading", self)
 
     def _read_ready(self):
+        if self._conn_lost:
+            return
         try:
             data = self._sock.recv(self.max_size)
         except (BlockingIOError, InterruptedError):
@@ -683,8 +688,8 @@ class _SelectorSocketTransport(_SelectorTransport):
 
     def write(self, data):
         if not isinstance(data, (bytes, bytearray, memoryview)):
-            raise TypeError('data argument must be byte-ish (%r)',
-                            type(data))
+            raise TypeError('data argument must be a bytes-like object, '
+                            'not %r' % type(data).__name__)
         if self._eof:
             raise RuntimeError('Cannot call write() after write_eof()')
         if not data:
@@ -719,6 +724,8 @@ class _SelectorSocketTransport(_SelectorTransport):
     def _write_ready(self):
         assert self._buffer, 'Data should not be empty'
 
+        if self._conn_lost:
+            return
         try:
             n = self._sock.send(self._buffer)
         except (BlockingIOError, InterruptedError):
@@ -889,6 +896,8 @@ class _SelectorSslTransport(_SelectorTransport):
             logger.debug("%r resumes reading", self)
 
     def _read_ready(self):
+        if self._conn_lost:
+            return
         if self._write_wants_read:
             self._write_wants_read = False
             self._write_ready()
@@ -921,6 +930,8 @@ class _SelectorSslTransport(_SelectorTransport):
                     self.close()
 
     def _write_ready(self):
+        if self._conn_lost:
+            return
         if self._read_wants_write:
             self._read_wants_write = False
             self._read_ready()
@@ -955,8 +966,8 @@ class _SelectorSslTransport(_SelectorTransport):
 
     def write(self, data):
         if not isinstance(data, (bytes, bytearray, memoryview)):
-            raise TypeError('data argument must be byte-ish (%r)',
-                            type(data))
+            raise TypeError('data argument must be a bytes-like object, '
+                            'not %r' % type(data).__name__)
         if not data:
             return
 
@@ -998,6 +1009,8 @@ class _SelectorDatagramTransport(_SelectorTransport):
         return sum(len(data) for data, _ in self._buffer)
 
     def _read_ready(self):
+        if self._conn_lost:
+            return
         try:
             data, addr = self._sock.recvfrom(self.max_size)
         except (BlockingIOError, InterruptedError):
@@ -1011,8 +1024,8 @@ class _SelectorDatagramTransport(_SelectorTransport):
 
     def sendto(self, data, addr=None):
         if not isinstance(data, (bytes, bytearray, memoryview)):
-            raise TypeError('data argument must be byte-ish (%r)',
-                            type(data))
+            raise TypeError('data argument must be a bytes-like object, '
+                            'not %r' % type(data).__name__)
         if not data:
             return
 
index dde980b..f58b5ac 100644 (file)
@@ -603,7 +603,7 @@ class SSLProtocol(protocols.Protocol):
         self._wakeup_waiter()
         self._session_established = True
         # In case transport.write() was already called. Don't call
-        # immediatly _process_write_backlog(), but schedule it:
+        # immediately _process_write_backlog(), but schedule it:
         # _on_handshake_complete() can be called indirectly from
         # _process_write_backlog(), and _process_write_backlog() is not
         # reentrant.
@@ -655,7 +655,7 @@ class SSLProtocol(protocols.Protocol):
 
     def _fatal_error(self, exc, message='Fatal error on transport'):
         # Should be called from exception handler only.
-        if isinstance(exc, (BrokenPipeError, ConnectionResetError)):
+        if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
             if self._loop.get_debug():
                 logger.debug("%r: %s", self, message, exc_info=True)
         else:
index 6b5e96a..c88a87c 100644 (file)
@@ -3,6 +3,7 @@
 __all__ = ['StreamReader', 'StreamWriter', 'StreamReaderProtocol',
            'open_connection', 'start_server',
            'IncompleteReadError',
+           'LimitOverrunError',
            ]
 
 import socket
@@ -13,13 +14,12 @@ if hasattr(socket, 'AF_UNIX'):
 from . import coroutines
 from . import compat
 from . import events
-from . import futures
 from . import protocols
 from .coroutines import coroutine
 from .log import logger
 
 
-_DEFAULT_LIMIT = 2**16
+_DEFAULT_LIMIT = 2 ** 16
 
 
 class IncompleteReadError(EOFError):
@@ -27,15 +27,26 @@ class IncompleteReadError(EOFError):
     Incomplete read error. Attributes:
 
     - partial: read bytes string before the end of stream was reached
-    - expected: total number of expected bytes
+    - expected: total number of expected bytes (or None if unknown)
     """
     def __init__(self, partial, expected):
-        EOFError.__init__(self, "%s bytes read on a total of %s expected bytes"
-                                % (len(partial), expected))
+        super().__init__("%d bytes read on a total of %r expected bytes"
+                         % (len(partial), expected))
         self.partial = partial
         self.expected = expected
 
 
+class LimitOverrunError(Exception):
+    """Reached the buffer limit while looking for a separator.
+
+    Attributes:
+    - consumed: total number of to be consumed bytes.
+    """
+    def __init__(self, message, consumed):
+        super().__init__(message)
+        self.consumed = consumed
+
+
 @coroutine
 def open_connection(host=None, port=None, *,
                     loop=None, limit=_DEFAULT_LIMIT, **kwds):
@@ -118,7 +129,6 @@ if hasattr(socket, 'AF_UNIX'):
         writer = StreamWriter(transport, protocol, reader, loop)
         return reader, writer
 
-
     @coroutine
     def start_unix_server(client_connected_cb, path=None, *,
                           loop=None, limit=_DEFAULT_LIMIT, **kwds):
@@ -196,7 +206,7 @@ class FlowControlMixin(protocols.Protocol):
             return
         waiter = self._drain_waiter
         assert waiter is None or waiter.cancelled()
-        waiter = futures.Future(loop=self._loop)
+        waiter = self._loop.create_future()
         self._drain_waiter = waiter
         yield from waiter
 
@@ -215,9 +225,11 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol):
         self._stream_reader = stream_reader
         self._stream_writer = None
         self._client_connected_cb = client_connected_cb
+        self._over_ssl = False
 
     def connection_made(self, transport):
         self._stream_reader.set_transport(transport)
+        self._over_ssl = transport.get_extra_info('sslcontext') is not None
         if self._client_connected_cb is not None:
             self._stream_writer = StreamWriter(transport, self,
                                                self._stream_reader,
@@ -228,17 +240,25 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol):
                 self._loop.create_task(res)
 
     def connection_lost(self, exc):
-        if exc is None:
-            self._stream_reader.feed_eof()
-        else:
-            self._stream_reader.set_exception(exc)
+        if self._stream_reader is not None:
+            if exc is None:
+                self._stream_reader.feed_eof()
+            else:
+                self._stream_reader.set_exception(exc)
         super().connection_lost(exc)
+        self._stream_reader = None
+        self._stream_writer = None
 
     def data_received(self, data):
         self._stream_reader.feed_data(data)
 
     def eof_received(self):
         self._stream_reader.feed_eof()
+        if self._over_ssl:
+            # Prevent a warning in SSLProtocol.eof_received:
+            # "returning true from eof_received()
+            # has no effect when using ssl"
+            return False
         return True
 
 
@@ -318,6 +338,10 @@ class StreamReader:
     def __init__(self, limit=_DEFAULT_LIMIT, loop=None):
         # The line length limit is  a security feature;
         # it also doubles as half the buffer limit.
+
+        if limit <= 0:
+            raise ValueError('Limit cannot be <= 0')
+
         self._limit = limit
         if loop is None:
             self._loop = events.get_event_loop()
@@ -361,7 +385,7 @@ class StreamReader:
                 waiter.set_exception(exc)
 
     def _wakeup_waiter(self):
-        """Wakeup read() or readline() function waiting for data or EOF."""
+        """Wakeup read*() functions waiting for data or EOF."""
         waiter = self._waiter
         if waiter is not None:
             self._waiter = None
@@ -395,8 +419,8 @@ class StreamReader:
         self._wakeup_waiter()
 
         if (self._transport is not None and
-            not self._paused and
-            len(self._buffer) > 2*self._limit):
+                not self._paused and
+                len(self._buffer) > 2 * self._limit):
             try:
                 self._transport.pause_reading()
             except NotImplementedError:
@@ -409,7 +433,10 @@ class StreamReader:
 
     @coroutine
     def _wait_for_data(self, func_name):
-        """Wait until feed_data() or feed_eof() is called."""
+        """Wait until feed_data() or feed_eof() is called.
+
+        If stream was paused, automatically resume it.
+        """
         # StreamReader uses a future to link the protocol feed_data() method
         # to a read coroutine. Running two read coroutines at the same time
         # would have an unexpected behaviour. It would not possible to know
@@ -418,7 +445,14 @@ class StreamReader:
             raise RuntimeError('%s() called while another coroutine is '
                                'already waiting for incoming data' % func_name)
 
-        self._waiter = futures.Future(loop=self._loop)
+        assert not self._eof, '_wait_for_data after EOF'
+
+        # Waiting for data while paused will make deadlock, so prevent it.
+        if self._paused:
+            self._paused = False
+            self._transport.resume_reading()
+
+        self._waiter = self._loop.create_future()
         try:
             yield from self._waiter
         finally:
@@ -426,43 +460,154 @@ class StreamReader:
 
     @coroutine
     def readline(self):
+        """Read chunk of data from the stream until newline (b'\n') is found.
+
+        On success, return chunk that ends with newline. If only partial
+        line can be read due to EOF, return incomplete line without
+        terminating newline. When EOF was reached while no bytes read, empty
+        bytes object is returned.
+
+        If limit is reached, ValueError will be raised. In that case, if
+        newline was found, complete line including newline will be removed
+        from internal buffer. Else, internal buffer will be cleared. Limit is
+        compared against part of the line without newline.
+
+        If stream was paused, this function will automatically resume it if
+        needed.
+        """
+        sep = b'\n'
+        seplen = len(sep)
+        try:
+            line = yield from self.readuntil(sep)
+        except IncompleteReadError as e:
+            return e.partial
+        except LimitOverrunError as e:
+            if self._buffer.startswith(sep, e.consumed):
+                del self._buffer[:e.consumed + seplen]
+            else:
+                self._buffer.clear()
+            self._maybe_resume_transport()
+            raise ValueError(e.args[0])
+        return line
+
+    @coroutine
+    def readuntil(self, separator=b'\n'):
+        """Read data from the stream until ``separator`` is found.
+
+        On success, the data and separator will be removed from the
+        internal buffer (consumed). Returned data will include the
+        separator at the end.
+
+        Configured stream limit is used to check result. Limit sets the
+        maximal length of data that can be returned, not counting the
+        separator.
+
+        If an EOF occurs and the complete separator is still not found,
+        an IncompleteReadError exception will be raised, and the internal
+        buffer will be reset.  The IncompleteReadError.partial attribute
+        may contain the separator partially.
+
+        If the data cannot be read because of over limit, a
+        LimitOverrunError exception  will be raised, and the data
+        will be left in the internal buffer, so it can be read again.
+        """
+        seplen = len(separator)
+        if seplen == 0:
+            raise ValueError('Separator should be at least one-byte string')
+
         if self._exception is not None:
             raise self._exception
 
-        line = bytearray()
-        not_enough = True
-
-        while not_enough:
-            while self._buffer and not_enough:
-                ichar = self._buffer.find(b'\n')
-                if ichar < 0:
-                    line.extend(self._buffer)
-                    self._buffer.clear()
-                else:
-                    ichar += 1
-                    line.extend(self._buffer[:ichar])
-                    del self._buffer[:ichar]
-                    not_enough = False
-
-                if len(line) > self._limit:
-                    self._maybe_resume_transport()
-                    raise ValueError('Line is too long')
+        # Consume whole buffer except last bytes, which length is
+        # one less than seplen. Let's check corner cases with
+        # separator='SEPARATOR':
+        # * we have received almost complete separator (without last
+        #   byte). i.e buffer='some textSEPARATO'. In this case we
+        #   can safely consume len(separator) - 1 bytes.
+        # * last byte of buffer is first byte of separator, i.e.
+        #   buffer='abcdefghijklmnopqrS'. We may safely consume
+        #   everything except that last byte, but this require to
+        #   analyze bytes of buffer that match partial separator.
+        #   This is slow and/or require FSM. For this case our
+        #   implementation is not optimal, since require rescanning
+        #   of data that is known to not belong to separator. In
+        #   real world, separator will not be so long to notice
+        #   performance problems. Even when reading MIME-encoded
+        #   messages :)
+
+        # `offset` is the number of bytes from the beginning of the buffer
+        # where there is no occurrence of `separator`.
+        offset = 0
+
+        # Loop until we find `separator` in the buffer, exceed the buffer size,
+        # or an EOF has happened.
+        while True:
+            buflen = len(self._buffer)
+
+            # Check if we now have enough data in the buffer for `separator` to
+            # fit.
+            if buflen - offset >= seplen:
+                isep = self._buffer.find(separator, offset)
+
+                if isep != -1:
+                    # `separator` is in the buffer. `isep` will be used later
+                    # to retrieve the data.
+                    break
 
+                # see upper comment for explanation.
+                offset = buflen + 1 - seplen
+                if offset > self._limit:
+                    raise LimitOverrunError(
+                        'Separator is not found, and chunk exceed the limit',
+                        offset)
+
+            # Complete message (with full separator) may be present in buffer
+            # even when EOF flag is set. This may happen when the last chunk
+            # adds data which makes separator be found. That's why we check for
+            # EOF *ater* inspecting the buffer.
             if self._eof:
-                break
+                chunk = bytes(self._buffer)
+                self._buffer.clear()
+                raise IncompleteReadError(chunk, None)
 
-            if not_enough:
-                yield from self._wait_for_data('readline')
+            # _wait_for_data() will resume reading if stream was paused.
+            yield from self._wait_for_data('readuntil')
 
+        if isep > self._limit:
+            raise LimitOverrunError(
+                'Separator is found, but chunk is longer than limit', isep)
+
+        chunk = self._buffer[:isep + seplen]
+        del self._buffer[:isep + seplen]
         self._maybe_resume_transport()
-        return bytes(line)
+        return bytes(chunk)
 
     @coroutine
     def read(self, n=-1):
+        """Read up to `n` bytes from the stream.
+
+        If n is not provided, or set to -1, read until EOF and return all read
+        bytes. If the EOF was received and the internal buffer is empty, return
+        an empty bytes object.
+
+        If n is zero, return empty bytes object immediatelly.
+
+        If n is positive, this function try to read `n` bytes, and may return
+        less or equal bytes than requested, but at least one byte. If EOF was
+        received before any byte is read, this function returns empty byte
+        object.
+
+        Returned value is not limited with limit, configured at stream
+        creation.
+
+        If stream was paused, this function will automatically resume it if
+        needed.
+        """
+
         if self._exception is not None:
             raise self._exception
 
-        if not n:
+        if n == 0:
             return b''
 
         if n < 0:
@@ -477,26 +622,42 @@ class StreamReader:
                     break
                 blocks.append(block)
             return b''.join(blocks)
-        else:
-            if not self._buffer and not self._eof:
-                yield from self._wait_for_data('read')
 
-        if n < 0 or len(self._buffer) <= n:
-            data = bytes(self._buffer)
-            self._buffer.clear()
-        else:
-            # n > 0 and len(self._buffer) > n
-            data = bytes(self._buffer[:n])
-            del self._buffer[:n]
+        if not self._buffer and not self._eof:
+            yield from self._wait_for_data('read')
+
+        # This will work right even if buffer is less than n bytes
+        data = bytes(self._buffer[:n])
+        del self._buffer[:n]
 
         self._maybe_resume_transport()
         return data
 
     @coroutine
     def readexactly(self, n):
+        """Read exactly `n` bytes.
+
+        Raise an IncompleteReadError if EOF is reached before `n` bytes can be
+        read. The IncompleteReadError.partial attribute of the exception will
+        contain the partial read bytes.
+
+        if n is zero, return empty bytes object.
+
+        Returned value is not limited with limit, configured at stream
+        creation.
+
+        If stream was paused, this function will automatically resume it if
+        needed.
+        """
+        if n < 0:
+            raise ValueError('readexactly size can not be less than zero')
+
         if self._exception is not None:
             raise self._exception
 
+        if n == 0:
+            return b''
+
         # There used to be "optimized" code here.  It created its own
         # Future and waited until self._buffer had at least the n
         # bytes, then called read(n).  Unfortunately, this could pause
@@ -513,6 +674,8 @@ class StreamReader:
             blocks.append(block)
             n -= len(block)
 
+        assert n == 0
+
         return b''.join(blocks)
 
     if compat.PY35:
@@ -526,3 +689,9 @@ class StreamReader:
             if val == b'':
                 raise StopAsyncIteration
             return val
+
+    if compat.PY352:
+        # In Python 3.5.2 and greater, __aiter__ should return
+        # the asynchronous iterator directly.
+        def __aiter__(self):
+            return self
index ead4039..b2f5304 100644 (file)
@@ -166,7 +166,7 @@ class Process:
 
     @coroutine
     def communicate(self, input=None):
-        if input:
+        if input is not None:
             stdin = self._feed_stdin(input)
         else:
             stdin = self._noop()
index e6389d8..0cca8e3 100644 (file)
@@ -251,7 +251,13 @@ class Task(futures.Future):
         else:
             if isinstance(result, futures.Future):
                 # Yielded Future must come from Future.__iter__().
-                if result._blocking:
+                if result._loop is not self._loop:
+                    self._loop.call_soon(
+                        self._step,
+                        RuntimeError(
+                            'Task {!r} got Future {!r} attached to a '
+                            'different loop'.format(self, result)))
+                elif result._blocking:
                     result._blocking = False
                     result.add_done_callback(self._wakeup)
                     self._fut_waiter = result
@@ -366,7 +372,7 @@ def wait_for(fut, timeout, *, loop=None):
     if timeout is None:
         return (yield from fut)
 
-    waiter = futures.Future(loop=loop)
+    waiter = loop.create_future()
     timeout_handle = loop.call_later(timeout, _release_waiter, waiter)
     cb = functools.partial(_release_waiter, waiter)
 
@@ -394,12 +400,12 @@ def wait_for(fut, timeout, *, loop=None):
 
 @coroutine
 def _wait(fs, timeout, return_when, loop):
-    """Internal helper for wait() and _wait_for().
+    """Internal helper for wait() and wait_for().
 
     The fs argument must be a collection of Futures.
     """
     assert fs, 'Set of Futures is empty.'
-    waiter = futures.Future(loop=loop)
+    waiter = loop.create_future()
     timeout_handle = None
     if timeout is not None:
         timeout_handle = loop.call_later(timeout, _release_waiter, waiter)
@@ -500,7 +506,9 @@ def sleep(delay, result=None, *, loop=None):
         yield
         return result
 
-    future = futures.Future(loop=loop)
+    if loop is None:
+        loop = events.get_event_loop()
+    future = loop.create_future()
     h = future._loop.call_later(delay,
                                 futures._set_result_unless_cancelled,
                                 future, result)
@@ -597,7 +605,9 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False):
     be cancelled.)
     """
     if not coros_or_futures:
-        outer = futures.Future(loop=loop)
+        if loop is None:
+            loop = events.get_event_loop()
+        outer = loop.create_future()
         outer.set_result([])
         return outer
 
@@ -685,7 +695,7 @@ def shield(arg, *, loop=None):
         # Shortcut.
         return inner
     loop = inner._loop
-    outer = futures.Future(loop=loop)
+    outer = loop.create_future()
 
     def _done_callback(inner):
         if outer.cancelled():
index 8170533..396e6ae 100644 (file)
@@ -446,9 +446,14 @@ def disable_logger():
     finally:
         logger.setLevel(old_level)
 
-def mock_nonblocking_socket():
+
+def mock_nonblocking_socket(proto=socket.IPPROTO_TCP, type=socket.SOCK_STREAM,
+                            family=socket.AF_INET):
     """Create a mock of a non-blocking socket."""
-    sock = mock.Mock(socket.socket)
+    sock = mock.MagicMock(socket.socket)
+    sock.proto = proto
+    sock.type = type
+    sock.family = family
     sock.gettimeout.return_value = 0.0
     return sock
 
index 7747ff4..d712749 100644 (file)
@@ -177,7 +177,7 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
                                    stdin, stdout, stderr, bufsize,
                                    extra=None, **kwargs):
         with events.get_child_watcher() as watcher:
-            waiter = futures.Future(loop=self)
+            waiter = self.create_future()
             transp = _UnixSubprocessTransport(self, protocol, args, shell,
                                               stdin, stdout, stderr, bufsize,
                                               waiter=waiter, extra=extra,
@@ -329,14 +329,17 @@ class _UnixReadPipeTransport(transports.ReadTransport):
         elif self._closing:
             info.append('closing')
         info.append('fd=%s' % self._fileno)
-        if self._pipe is not None:
+        selector = getattr(self._loop, '_selector', None)
+        if self._pipe is not None and selector is not None:
             polling = selector_events._test_selector_event(
-                          self._loop._selector,
+                          selector,
                           self._fileno, selectors.EVENT_READ)
             if polling:
                 info.append('polling')
             else:
                 info.append('idle')
+        elif self._pipe is not None:
+            info.append('open')
         else:
             info.append('closed')
         return '<%s>' % ' '.join(info)
@@ -453,9 +456,10 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
         elif self._closing:
             info.append('closing')
         info.append('fd=%s' % self._fileno)
-        if self._pipe is not None:
+        selector = getattr(self._loop, '_selector', None)
+        if self._pipe is not None and selector is not None:
             polling = selector_events._test_selector_event(
-                          self._loop._selector,
+                          selector,
                           self._fileno, selectors.EVENT_WRITE)
             if polling:
                 info.append('polling')
@@ -464,6 +468,8 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
 
             bufsize = self.get_write_buffer_size()
             info.append('bufsize=%s' % bufsize)
+        elif self._pipe is not None:
+            info.append('open')
         else:
             info.append('closed')
         return '<%s>' % ' '.join(info)
@@ -575,7 +581,7 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
 
     def _fatal_error(self, exc, message='Fatal error on pipe transport'):
         # should be called by exception handler only
-        if isinstance(exc, (BrokenPipeError, ConnectionResetError)):
+        if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
             if self._loop.get_debug():
                 logger.debug("%r: %s", self, message, exc_info=True)
         else:
index 922594f..668fe14 100644 (file)
@@ -197,7 +197,7 @@ class _WaitHandleFuture(_BaseWaitHandleFuture):
         #
         # If the IocpProactor already received the event, it's safe to call
         # _unregister() because we kept a reference to the Overlapped object
-        # which is used as an unique key.
+        # which is used as a unique key.
         self._proactor._unregister(self._ov)
         self._proactor = None
 
@@ -366,7 +366,7 @@ class ProactorEventLoop(proactor_events.BaseProactorEventLoop):
     def _make_subprocess_transport(self, protocol, args, shell,
                                    stdin, stdout, stderr, bufsize,
                                    extra=None, **kwargs):
-        waiter = futures.Future(loop=self)
+        waiter = self.create_future()
         transp = _WindowsSubprocessTransport(self, protocol, args, shell,
                                              stdin, stdout, stderr, bufsize,
                                              waiter=waiter, extra=extra,
@@ -417,7 +417,7 @@ class IocpProactor:
         return tmp
 
     def _result(self, value):
-        fut = futures.Future(loop=self._loop)
+        fut = self._loop.create_future()
         fut.set_result(value)
         return fut
 
index 640f787..adaec1d 100755 (executable)
@@ -12,7 +12,7 @@ import binascii
 
 
 __all__ = [
-    # Legacy interface exports traditional RFC 1521 Base64 encodings
+    # Legacy interface exports traditional RFC 2045 Base64 encodings
     'encode', 'decode', 'encodebytes', 'decodebytes',
     # Generalized interface for other encodings
     'b64encode', 'b64decode', 'b32encode', 'b32decode',
@@ -49,14 +49,11 @@ def _bytes_from_decode_data(s):
 # Base64 encoding/decoding uses binascii
 
 def b64encode(s, altchars=None):
-    """Encode a byte string using Base64.
+    """Encode the bytes-like object s using Base64 and return a bytes object.
 
-    s is the byte string to encode.  Optional altchars must be a byte
-    string of length 2 which specifies an alternative alphabet for the
-    '+' and '/' characters.  This allows an application to
-    e.g. generate url or filesystem safe Base64 strings.
-
-    The encoded byte string is returned.
+    Optional altchars should be a byte string of length 2 which specifies an
+    alternative alphabet for the '+' and '/' characters.  This allows an
+    application to e.g. generate url or filesystem safe Base64 strings.
     """
     # Strip off the trailing newline
     encoded = binascii.b2a_base64(s)[:-1]
@@ -67,18 +64,19 @@ def b64encode(s, altchars=None):
 
 
 def b64decode(s, altchars=None, validate=False):
-    """Decode a Base64 encoded byte string.
+    """Decode the Base64 encoded bytes-like object or ASCII string s.
 
-    s is the byte string to decode.  Optional altchars must be a
-    string of length 2 which specifies the alternative alphabet used
-    instead of the '+' and '/' characters.
+    Optional altchars must be a bytes-like object or ASCII string of length 2
+    which specifies the alternative alphabet used instead of the '+' and '/'
+    characters.
 
-    The decoded string is returned.  A binascii.Error is raised if s is
-    incorrectly padded.
+    The result is returned as a bytes object.  A binascii.Error is raised if
+    s is incorrectly padded.
 
-    If validate is False (the default), non-base64-alphabet characters are
-    discarded prior to the padding check.  If validate is True,
-    non-base64-alphabet characters in the input result in a binascii.Error.
+    If validate is False (the default), characters that are neither in the
+    normal base-64 alphabet nor the alternative alphabet are discarded prior
+    to the padding check.  If validate is True, these non-alphabet characters
+    in the input result in a binascii.Error.
     """
     s = _bytes_from_decode_data(s)
     if altchars is not None:
@@ -91,19 +89,19 @@ def b64decode(s, altchars=None, validate=False):
 
 
 def standard_b64encode(s):
-    """Encode a byte string using the standard Base64 alphabet.
+    """Encode bytes-like object s using the standard Base64 alphabet.
 
-    s is the byte string to encode.  The encoded byte string is returned.
+    The result is returned as a bytes object.
     """
     return b64encode(s)
 
 def standard_b64decode(s):
-    """Decode a byte string encoded with the standard Base64 alphabet.
+    """Decode bytes encoded with the standard Base64 alphabet.
 
-    s is the byte string to decode.  The decoded byte string is
-    returned.  binascii.Error is raised if the input is incorrectly
-    padded or if there are non-alphabet characters present in the
-    input.
+    Argument s is a bytes-like object or ASCII string to decode.  The result
+    is returned as a bytes object.  A binascii.Error is raised if the input
+    is incorrectly padded.  Characters that are not in the standard alphabet
+    are discarded prior to the padding check.
     """
     return b64decode(s)
 
@@ -112,21 +110,22 @@ _urlsafe_encode_translation = bytes.maketrans(b'+/', b'-_')
 _urlsafe_decode_translation = bytes.maketrans(b'-_', b'+/')
 
 def urlsafe_b64encode(s):
-    """Encode a byte string using a url-safe Base64 alphabet.
+    """Encode bytes using the URL- and filesystem-safe Base64 alphabet.
 
-    s is the byte string to encode.  The encoded byte string is
-    returned.  The alphabet uses '-' instead of '+' and '_' instead of
+    Argument s is a bytes-like object to encode.  The result is returned as a
+    bytes object.  The alphabet uses '-' instead of '+' and '_' instead of
     '/'.
     """
     return b64encode(s).translate(_urlsafe_encode_translation)
 
 def urlsafe_b64decode(s):
-    """Decode a byte string encoded with the standard Base64 alphabet.
+    """Decode bytes using the URL- and filesystem-safe Base64 alphabet.
 
-    s is the byte string to decode.  The decoded byte string is
-    returned.  binascii.Error is raised if the input is incorrectly
-    padded or if there are non-alphabet characters present in the
-    input.
+    Argument s is a bytes-like object or ASCII string to decode.  The result
+    is returned as a bytes object.  A binascii.Error is raised if the input
+    is incorrectly padded.  Characters that are not in the URL-safe base-64
+    alphabet, and are not a plus '+' or slash '/', are discarded prior to the
+    padding check.
 
     The alphabet uses '-' instead of '+' and '_' instead of '/'.
     """
@@ -142,9 +141,7 @@ _b32tab2 = None
 _b32rev = None
 
 def b32encode(s):
-    """Encode a byte string using Base32.
-
-    s is the byte string to encode.  The encoded byte string is returned.
+    """Encode the bytes-like object s using Base32 and return a bytes object.
     """
     global _b32tab2
     # Delay the initialization of the table to not waste memory
@@ -182,11 +179,10 @@ def b32encode(s):
     return bytes(encoded)
 
 def b32decode(s, casefold=False, map01=None):
-    """Decode a Base32 encoded byte string.
+    """Decode the Base32 encoded bytes-like object or ASCII string s.
 
-    s is the byte string to decode.  Optional casefold is a flag
-    specifying whether a lowercase alphabet is acceptable as input.
-    For security purposes, the default is False.
+    Optional casefold is a flag specifying whether a lowercase alphabet is
+    acceptable as input.  For security purposes, the default is False.
 
     RFC 3548 allows for optional mapping of the digit 0 (zero) to the
     letter O (oh), and for optional mapping of the digit 1 (one) to
@@ -196,7 +192,7 @@ def b32decode(s, casefold=False, map01=None):
     the letter O).  For security purposes the default is None, so that
     0 and 1 are not allowed in the input.
 
-    The decoded byte string is returned.  binascii.Error is raised if
+    The result is returned as a bytes object.  A binascii.Error is raised if
     the input is incorrectly padded or if there are non-alphabet
     characters present in the input.
     """
@@ -257,23 +253,20 @@ def b32decode(s, casefold=False, map01=None):
 # lowercase.  The RFC also recommends against accepting input case
 # insensitively.
 def b16encode(s):
-    """Encode a byte string using Base16.
-
-    s is the byte string to encode.  The encoded byte string is returned.
+    """Encode the bytes-like object s using Base16 and return a bytes object.
     """
     return binascii.hexlify(s).upper()
 
 
 def b16decode(s, casefold=False):
-    """Decode a Base16 encoded byte string.
+    """Decode the Base16 encoded bytes-like object or ASCII string s.
 
-    s is the byte string to decode.  Optional casefold is a flag
-    specifying whether a lowercase alphabet is acceptable as input.
-    For security purposes, the default is False.
+    Optional casefold is a flag specifying whether a lowercase alphabet is
+    acceptable as input.  For security purposes, the default is False.
 
-    The decoded byte string is returned.  binascii.Error is raised if
-    s were incorrectly padded or if there are non-alphabet characters
-    present in the string.
+    The result is returned as a bytes object.  A binascii.Error is raised if
+    s is incorrectly padded or if there are non-alphabet characters present
+    in the input.
     """
     s = _bytes_from_decode_data(s)
     if casefold:
@@ -316,19 +309,17 @@ def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False):
     return b''.join(chunks)
 
 def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False):
-    """Encode a byte string using Ascii85.
-
-    b is the byte string to encode. The encoded byte string is returned.
+    """Encode bytes-like object b using Ascii85 and return a bytes object.
 
     foldspaces is an optional flag that uses the special short sequence 'y'
     instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This
     feature is not supported by the "standard" Adobe encoding.
 
-    wrapcol controls whether the output should have newline ('\\n') characters
+    wrapcol controls whether the output should have newline (b'\\n') characters
     added to it. If this is non-zero, each output line will be at most this
     many characters long.
 
-    pad controls whether the input string is padded to a multiple of 4 before
+    pad controls whether the input is padded to a multiple of 4 before
     encoding. Note that the btoa implementation always pads.
 
     adobe controls whether the encoded byte sequence is framed with <~ and ~>,
@@ -359,9 +350,7 @@ def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False):
     return result
 
 def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'):
-    """Decode an Ascii85 encoded byte string.
-
-    s is the byte string to decode.
+    """Decode the Ascii85 encoded bytes-like object or ASCII string b.
 
     foldspaces is a flag that specifies whether the 'y' short sequence should be
     accepted as shorthand for 4 consecutive spaces (ASCII 0x20). This feature is
@@ -373,13 +362,20 @@ def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'):
     ignorechars should be a byte string containing characters to ignore from the
     input. This should only contain whitespace characters, and by default
     contains all whitespace characters in ASCII.
+
+    The result is returned as a bytes object.
     """
     b = _bytes_from_decode_data(b)
     if adobe:
-        if not (b.startswith(_A85START) and b.endswith(_A85END)):
-            raise ValueError("Ascii85 encoded byte sequences must be bracketed "
-                             "by {!r} and {!r}".format(_A85START, _A85END))
-        b = b[2:-2] # Strip off start/end markers
+        if not b.endswith(_A85END):
+            raise ValueError(
+                "Ascii85 encoded byte sequences must end "
+                "with {!r}".format(_A85END)
+                )
+        if b.startswith(_A85START):
+            b = b[2:-2]  # Strip off start/end markers
+        else:
+            b = b[:-2]
     #
     # We have to go through this stepwise, so as to ignore spaces and handle
     # special short sequences
@@ -432,10 +428,10 @@ _b85chars2 = None
 _b85dec = None
 
 def b85encode(b, pad=False):
-    """Encode an ASCII-encoded byte array in base85 format.
+    """Encode bytes-like object b in base85 format and return a bytes object.
 
-    If pad is true, the input is padded with "\\0" so its length is a multiple of
-    4 characters before encoding.
+    If pad is true, the input is padded with b'\\0' so its length is a multiple of
+    4 bytes before encoding.
     """
     global _b85chars, _b85chars2
     # Delay the initialization of tables to not waste memory
@@ -446,7 +442,10 @@ def b85encode(b, pad=False):
     return _85encode(b, _b85chars, _b85chars2, pad)
 
 def b85decode(b):
-    """Decode base85-encoded byte array"""
+    """Decode the base85-encoded bytes-like object or ASCII string b
+
+    The result is returned as a bytes object.
+    """
     global _b85dec
     # Delay the initialization of tables to not waste memory
     # if the function is never called
@@ -531,7 +530,7 @@ def _input_type_check(s):
 
 
 def encodebytes(s):
-    """Encode a bytestring into a bytestring containing multiple lines
+    """Encode a bytestring into a bytes object containing multiple lines
     of base-64 data."""
     _input_type_check(s)
     pieces = []
@@ -549,7 +548,7 @@ def encodestring(s):
 
 
 def decodebytes(s):
-    """Decode a bytestring of base-64 data into a bytestring."""
+    """Decode a bytestring of base-64 data into a bytes object."""
     _input_type_check(s)
     return binascii.a2b_base64(s)
 
index 26d2544..189c6d5 100755 (executable)
@@ -184,7 +184,7 @@ def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
 
 
 # parse query string function called from urlparse,
-# this is done in order to maintain backward compatiblity.
+# this is done in order to maintain backward compatibility.
 
 def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
     """Parse a query given as a string argument."""
index e8312a9..ebe8ee7 100644 (file)
@@ -1,3 +1,19 @@
+'''This module implements specialized container datatypes providing
+alternatives to Python's general purpose built-in containers, dict,
+list, set, and tuple.
+
+* namedtuple   factory function for creating tuple subclasses with named fields
+* deque        list-like container with fast appends and pops on either end
+* ChainMap     dict-like class for creating a single view of multiple mappings
+* Counter      dict subclass for counting hashable objects
+* OrderedDict  dict subclass that remembers the order entries were added
+* defaultdict  dict subclass that calls a factory function to supply missing values
+* UserDict     wrapper around dictionary objects for easier dict subclassing
+* UserList     wrapper around list objects for easier list subclassing
+* UserString   wrapper around string objects for easier string subclassing
+
+'''
+
 __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',
             'UserString', 'Counter', 'OrderedDict', 'ChainMap']
 
@@ -349,7 +365,7 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
     >>> x, y = p                        # unpack like a regular tuple
     >>> x, y
     (11, 22)
-    >>> p.x + p.y                       # fields also accessable by name
+    >>> p.x + p.y                       # fields also accessible by name
     33
     >>> d = p._asdict()                 # convert to a dictionary
     >>> d['x']
@@ -834,7 +850,8 @@ class ChainMap(MutableMapping):
     to create a single, updateable view.
 
     The underlying mappings are stored in a list.  That list is public and can
-    accessed or updated using the *maps* attribute.  There is no other state.
+    be accessed or updated using the *maps* attribute.  There is no other
+    state.
 
     Lookups search the underlying mappings successively until a key is found.
     In contrast, writes, updates, and deletions only operate on the first
index 64c0a9a..0cc0c1d 100644 (file)
@@ -238,9 +238,6 @@ def main():
     args = parser.parse_args()
     compile_dests = args.compile_dest
 
-    if (args.ddir and (len(compile_dests) != 1
-            or not os.path.isdir(compile_dests[0]))):
-        parser.exit('-d destdir requires exactly one directory argument')
     if args.rx:
         import re
         args.rx = re.compile(args.rx)
index 3a45fdf..972b94a 100644 (file)
@@ -207,7 +207,6 @@ try:
 except AttributeError:
     pass
 d[type] = _deepcopy_atomic
-d[range] = _deepcopy_atomic
 d[types.BuiltinFunctionType] = _deepcopy_atomic
 d[types.FunctionType] = _deepcopy_atomic
 d[weakref.ref] = _deepcopy_atomic
@@ -279,7 +278,7 @@ def _reconstruct(x, info, deep, memo=None):
     if n > 2:
         state = info[2]
     else:
-        state = {}
+        state = None
     if n > 3:
         listiter = info[3]
     else:
@@ -293,7 +292,7 @@ def _reconstruct(x, info, deep, memo=None):
     y = callable(*args)
     memo[id(x)] = y
 
-    if state:
+    if state is not None:
         if deep:
             state = deepcopy(state, memo)
         if hasattr(y, '__setstate__'):
index 4cb6d0d..0d86078 100644 (file)
@@ -47,7 +47,7 @@ from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
 def create_string_buffer(init, size=None):
     """create_string_buffer(aBytes) -> character array
     create_string_buffer(anInteger) -> character array
-    create_string_buffer(aString, anInteger) -> character array
+    create_string_buffer(aBytes, anInteger) -> character array
     """
     if isinstance(init, bytes):
         if size is None:
@@ -368,8 +368,8 @@ class CDLL(object):
         return func
 
 class PyDLL(CDLL):
-    """This class represents the Python library itself.  It allows to
-    access Python API functions.  The GIL is not released, and
+    """This class represents the Python library itself.  It allows
+    accessing Python API functions.  The GIL is not released, and
     Python exceptions are handled correctly.
     """
     _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
index 4e10cbe..2866e9f 100644 (file)
@@ -1,4 +1,4 @@
-Files in this directory from from Bob Ippolito's py2app.
+Files in this directory come from Bob Ippolito's py2app.
 
 License: Any components of the py2app suite may be distributed under
 the MIT or PSF open source licenses.
index 8ca77e0..4ed566b 100644 (file)
@@ -24,20 +24,24 @@ class ArrayTestCase(unittest.TestCase):
             self.assertEqual(len(ia), alen)
 
             # slot values ok?
-            values = [ia[i] for i in range(len(init))]
+            values = [ia[i] for i in range(alen)]
             self.assertEqual(values, init)
 
+            # out-of-bounds accesses should be caught
+            with self.assertRaises(IndexError): ia[alen]
+            with self.assertRaises(IndexError): ia[-alen-1]
+
             # change the items
             from operator import setitem
             new_values = list(range(42, 42+alen))
             [setitem(ia, n, new_values[n]) for n in range(alen)]
-            values = [ia[i] for i in range(len(init))]
+            values = [ia[i] for i in range(alen)]
             self.assertEqual(values, new_values)
 
             # are the items initialized to 0?
             ia = int_array()
-            values = [ia[i] for i in range(len(init))]
-            self.assertEqual(values, [0] * len(init))
+            values = [ia[i] for i in range(alen)]
+            self.assertEqual(values, [0] * alen)
 
             # Too many initializers should be caught
             self.assertRaises(IndexError, int_array, *range(alen*2))
index 225b9d1..751f85f 100644 (file)
@@ -56,9 +56,13 @@ class PointersTestCase(unittest.TestCase):
         # C code:
         #   int x = 12321;
         #   res = &x
-        res.contents = c_int(12321)
+        x = c_int(12321)
+        res.contents = x
         self.assertEqual(i.value, 54345)
 
+        x.value = -99
+        self.assertEqual(res.contents.value, -99)
+
     def test_callbacks_with_pointers(self):
         # a function type receiving a pointer
         PROTOTYPE = CFUNCTYPE(c_int, POINTER(c_int))
@@ -131,9 +135,10 @@ class PointersTestCase(unittest.TestCase):
 
     def test_basic(self):
         p = pointer(c_int(42))
-        # Although a pointer can be indexed, it ha no length
+        # Although a pointer can be indexed, it has no length
         self.assertRaises(TypeError, len, p)
         self.assertEqual(p[0], 42)
+        self.assertEqual(p[0:1], [42])
         self.assertEqual(p.contents.value, 42)
 
     def test_charpp(self):
index 9551e7a..5a3a47f 100644 (file)
@@ -28,8 +28,7 @@ class ValuesTestCase(unittest.TestCase):
         ctdll = CDLL(_ctypes_test.__file__)
         self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
 
-@unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test')
-class Win_ValuesTestCase(unittest.TestCase):
+class PythonValuesTestCase(unittest.TestCase):
     """This test only works when python itself is a dll/shared library"""
 
     def test_optimizeflag(self):
@@ -76,15 +75,16 @@ class Win_ValuesTestCase(unittest.TestCase):
             if entry.name in bootstrap_expected:
                 bootstrap_seen.append(entry.name)
                 self.assertTrue(entry.size,
-                    "{} was reported as having no size".format(entry.name))
+                    "{!r} was reported as having no size".format(entry.name))
                 continue
-            items.append((entry.name, entry.size))
+            items.append((entry.name.decode("ascii"), entry.size))
 
-        expected = [(b"__hello__", 161),
-                    (b"__phello__", -161),
-                    (b"__phello__.spam", 161),
+        expected = [("__hello__", 161),
+                    ("__phello__", -161),
+                    ("__phello__.spam", 161),
                     ]
-        self.assertEqual(items, expected)
+        self.assertEqual(items, expected, "PyImport_FrozenModules example "
+            "in Doc/library/ctypes.rst may be out of date")
 
         self.assertEqual(sorted(bootstrap_seen), bootstrap_expected,
             "frozen bootstrap modules did not match PyImport_FrozenModules")
index 9e74ccd..8ff4aff 100644 (file)
@@ -184,6 +184,7 @@ elif os.name == "posix":
             else:
                 cmd = 'env LC_ALL=C /usr/bin/crle 2>/dev/null'
 
+            paths = None
             with contextlib.closing(os.popen(cmd)) as f:
                 for line in f.readlines():
                     line = line.strip()
index b9719cb..2f94218 100644 (file)
@@ -896,6 +896,7 @@ class date:
 
         ISO calendar algorithm taken from
         http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
+        (used with permission)
         """
         year = self._year
         week1monday = _isoweek1monday(year)
index af37cdf..f7e3c7f 100644 (file)
@@ -13,7 +13,8 @@ __all__ = ["code_info", "dis", "disassemble", "distb", "disco",
            "get_instructions", "Instruction", "Bytecode"] + _opcodes_all
 del _opcodes_all
 
-_have_code = (types.MethodType, types.FunctionType, types.CodeType, type)
+_have_code = (types.MethodType, types.FunctionType, types.CodeType,
+              classmethod, staticmethod, type)
 
 def _try_compile(source, name):
     """Attempts to compile the given source, first as an expression and
@@ -274,33 +275,19 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
 
     """
     labels = findlabels(code)
-    extended_arg = 0
     starts_line = None
     free = None
-    # enumerate() is not an option, since we sometimes process
-    # multiple elements on a single pass through the loop
-    n = len(code)
-    i = 0
-    while i < n:
-        op = code[i]
-        offset = i
+    for offset, op, arg in _unpack_opargs(code):
         if linestarts is not None:
-            starts_line = linestarts.get(i, None)
+            starts_line = linestarts.get(offset, None)
             if starts_line is not None:
                 starts_line += line_offset
-        is_jump_target = i in labels
-        i = i+1
-        arg = None
+        is_jump_target = offset in labels
         argval = None
         argrepr = ''
-        if op >= HAVE_ARGUMENT:
-            arg = code[i] + code[i+1]*256 + extended_arg
-            extended_arg = 0
-            i = i+2
-            if op == EXTENDED_ARG:
-                extended_arg = arg*65536
+        if arg is not None:
             #  Set argval to the dereferenced value of the argument when
-            #  availabe, and argrepr to the string representation of argval.
+            #  available, and argrepr to the string representation of argval.
             #    _disassemble_bytes needs the string repr of the
             #    raw name index for LOAD_GLOBAL, LOAD_CONST, etc.
             argval = arg
@@ -309,7 +296,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
             elif op in hasname:
                 argval, argrepr = _get_name_info(arg, names)
             elif op in hasjrel:
-                argval = i + arg
+                argval = offset + 3 + arg
                 argrepr = "to " + repr(argval)
             elif op in haslocal:
                 argval, argrepr = _get_name_info(arg, varnames)
@@ -319,7 +306,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
             elif op in hasfree:
                 argval, argrepr = _get_name_info(arg, cells)
             elif op in hasnargs:
-                argrepr = "%d positional, %d keyword pair" % (code[i-2], code[i-1])
+                argrepr = "%d positional, %d keyword pair" % (arg%256, arg//256)
         yield Instruction(opname[op], op,
                           arg, argval, argrepr,
                           offset, starts_line, is_jump_target)
@@ -355,26 +342,37 @@ def _disassemble_str(source, *, file=None):
 
 disco = disassemble                     # XXX For backwards compatibility
 
-def findlabels(code):
-    """Detect all offsets in a byte code which are jump targets.
-
-    Return the list of offsets.
-
-    """
-    labels = []
+def _unpack_opargs(code):
     # enumerate() is not an option, since we sometimes process
     # multiple elements on a single pass through the loop
+    extended_arg = 0
     n = len(code)
     i = 0
     while i < n:
         op = code[i]
+        offset = i
         i = i+1
+        arg = None
         if op >= HAVE_ARGUMENT:
-            arg = code[i] + code[i+1]*256
+            arg = code[i] + code[i+1]*256 + extended_arg
+            extended_arg = 0
             i = i+2
+            if op == EXTENDED_ARG:
+                extended_arg = arg*65536
+        yield (offset, op, arg)
+
+def findlabels(code):
+    """Detect all offsets in a byte code which are jump targets.
+
+    Return the list of offsets.
+
+    """
+    labels = []
+    for offset, op, arg in _unpack_opargs(code):
+        if arg is not None:
             label = -1
             if op in hasjrel:
-                label = i+arg
+                label = offset + 3 + arg
             elif op in hasjabs:
                 label = arg
             if label >= 0:
index 10a9ffd..d0ba7d6 100644 (file)
@@ -125,11 +125,11 @@ def _find_exe(exe, paths=None):
     return exe
 
 # A map keyed by get_platform() return values to values accepted by
-# 'vcvarsall.bat'.  Note a cross-compile may combine these (eg, 'x86_amd64' is
-# the param to cross-compile on x86 targetting amd64.)
+# 'vcvarsall.bat'. Always cross-compile from x86 to work with the
+# lighter-weight MSVC installs that do not include native 64-bit tools.
 PLAT_TO_VCVARS = {
     'win32' : 'x86',
-    'win-amd64' : 'amd64',
+    'win-amd64' : 'x86_amd64',
 }
 
 # A map keyed by get_platform() return values to the file under
@@ -193,19 +193,8 @@ class MSVCCompiler(CCompiler) :
             raise DistutilsPlatformError("--plat-name must be one of {}"
                                          .format(tuple(PLAT_TO_VCVARS)))
 
-        # On x86, 'vcvarsall.bat amd64' creates an env that doesn't work;
-        # to cross compile, you use 'x86_amd64'.
-        # On AMD64, 'vcvarsall.bat amd64' is a native build env; to cross
-        # compile use 'x86' (ie, it runs the x86 compiler directly)
-        if plat_name == get_platform() or plat_name == 'win32':
-            # native build or cross-compile to win32
-            plat_spec = PLAT_TO_VCVARS[plat_name]
-        else:
-            # cross compile from win32 -> some 64bit
-            plat_spec = '{}_{}'.format(
-                PLAT_TO_VCVARS[get_platform()],
-                PLAT_TO_VCVARS[plat_name]
-            )
+        # Get the vcvarsall.bat spec for the requested platform.
+        plat_spec = PLAT_TO_VCVARS[plat_name]
 
         vc_env = _get_vc_env(plat_spec)
         if not vc_env:
index 82fd7d5..b71d1d3 100644 (file)
@@ -875,9 +875,9 @@ main (int argc, char **argv) {
     def library_filename(self, libname, lib_type='static',     # or 'shared'
                          strip_dir=0, output_dir=''):
         assert output_dir is not None
-        if lib_type not in ("static", "shared", "dylib"):
+        if lib_type not in ("static", "shared", "dylib", "xcode_stub"):
             raise ValueError(
-                  "'lib_type' must be \"static\", \"shared\" or \"dylib\"")
+                  "'lib_type' must be \"static\", \"shared\", \"dylib\", or \"xcode_stub\"")
         fmt = getattr(self, lib_type + "_lib_format")
         ext = getattr(self, lib_type + "_lib_extension")
 
index d4cb11e..f03a4e3 100644 (file)
@@ -748,7 +748,7 @@ class build_ext(Command):
             if sysconfig.get_config_var('Py_ENABLE_SHARED'):
                 pythonlib = 'python{}.{}{}'.format(
                     sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff,
-                    sys.abiflags)
+                    sysconfig.get_config_var('ABIFLAGS'))
                 return ext.libraries + [pythonlib]
             else:
                 return ext.libraries
index b49f86f..86343c8 100644 (file)
@@ -296,9 +296,9 @@ Your selection [default 1]: ''', log.INFO)
             result = 500, str(e)
         else:
             if self.show_response:
-                data = result.read()
+                data = self._read_pypi_response(result)
             result = 200, 'OK'
         if self.show_response:
-            dashes = '-' * 75
-            self.announce('%s%r%s' % (dashes, data, dashes))
+            msg = '\n'.join(('-' * 75, data, '-' * 75))
+            self.announce(msg, log.INFO)
         return result
index 1c4fc48..0afcbf2 100644 (file)
@@ -181,21 +181,21 @@ class upload(PyPIRCCommand):
             result = urlopen(request)
             status = result.getcode()
             reason = result.msg
-        except OSError as e:
-            self.announce(str(e), log.ERROR)
-            raise
         except HTTPError as e:
             status = e.code
             reason = e.msg
+        except OSError as e:
+            self.announce(str(e), log.ERROR)
+            raise
 
         if status == 200:
             self.announce('Server response (%s): %s' % (status, reason),
                           log.INFO)
+            if self.show_response:
+                text = self._read_pypi_response(result)
+                msg = '\n'.join(('-' * 75, text, '-' * 75))
+                self.announce(msg, log.INFO)
         else:
             msg = 'Upload failed (%s): %s' % (status, reason)
             self.announce(msg, log.ERROR)
             raise DistutilsError(msg)
-        if self.show_response:
-            text = self._read_pypi_response(result)
-            msg = '\n'.join(('-' * 75, text, '-' * 75))
-            self.announce(msg, log.INFO)
index 7a5e78d..2229954 100644 (file)
Binary files a/Lib/distutils/command/wininst-14.0-amd64.exe and b/Lib/distutils/command/wininst-14.0-amd64.exe differ
index cc43296..0dac110 100644 (file)
Binary files a/Lib/distutils/command/wininst-14.0.exe and b/Lib/distutils/command/wininst-14.0.exe differ
index 382aca8..f0c7373 100644 (file)
@@ -4,7 +4,7 @@ Provides the PyPIRCCommand class, the base class for the command classes
 that uses .pypirc in the distutils.command package.
 """
 import os
-from configparser import ConfigParser
+from configparser import RawConfigParser
 
 from distutils.cmd import Command
 
@@ -53,7 +53,7 @@ class PyPIRCCommand(Command):
             repository = self.repository or self.DEFAULT_REPOSITORY
             realm = self.realm or self.DEFAULT_REALM
 
-            config = ConfigParser()
+            config = RawConfigParser()
             config.read(rc)
             sections = config.sections()
             if 'distutils' in sections:
index da4b21d..0b1fd19 100644 (file)
@@ -51,7 +51,7 @@ else:
 
 # A map keyed by get_platform() return values to values accepted by
 # 'vcvarsall.bat'.  Note a cross-compile may combine these (eg, 'x86_amd64' is
-# the param to cross-compile on x86 targetting amd64.)
+# the param to cross-compile on x86 targeting amd64.)
 PLAT_TO_VCVARS = {
     'win32' : 'x86',
     'win-amd64' : 'amd64',
index 366ffbe..8f62b1a 100644 (file)
@@ -279,7 +279,7 @@ class BuildExtTestCase(TempdirManager,
 
     def test_compiler_option(self):
         # cmd.compiler is an option and
-        # should not be overriden by a compiler instance
+        # should not be overridden by a compiler instance
         # when the command is run
         dist = Distribution()
         cmd = self.build_ext(dist)
index 6180133..01acf23 100644 (file)
@@ -301,6 +301,20 @@ class RegisterTestCase(PyPIRCCommandTestCase):
         results = self.get_logs(INFO)
         self.assertEqual(results, ['running check', 'xxx'])
 
+    def test_show_response(self):
+        # test that the --show-response option return a well formatted response
+        cmd = self._get_cmd()
+        inputs = Inputs('1', 'tarek', 'y')
+        register_module.input = inputs.__call__
+        cmd.show_response = 1
+        try:
+            cmd.run()
+        finally:
+            del register_module.input
+
+        results = self.get_logs(INFO)
+        self.assertEqual(results[3], 75 * '-' + '\nxxx\n' + 75 * '-')
+
 
 def test_suite():
     return unittest.makeSuite(RegisterTestCase)
index 3d14e12..e171ee9 100644 (file)
@@ -127,7 +127,7 @@ class UnixCCompilerTestCase(unittest.TestCase):
         self.assertEqual(self.cc.linker_so[0], 'my_cc')
 
     @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for OS X')
-    def test_osx_explict_ldshared(self):
+    def test_osx_explicit_ldshared(self):
         # Issue #18080:
         # ensure that setting CC env variable does not change
         #   explicit LDSHARED setting for linker
index dccaf77..964aac7 100644 (file)
@@ -1,13 +1,16 @@
 """Tests for distutils.command.upload."""
 import os
 import unittest
+import unittest.mock as mock
+from urllib.request import HTTPError
+
 from test.support import run_unittest
 
 from distutils.command import upload as upload_mod
 from distutils.command.upload import upload
 from distutils.core import Distribution
 from distutils.errors import DistutilsError
-from distutils.log import INFO
+from distutils.log import ERROR, INFO
 
 from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
 
@@ -137,13 +140,39 @@ class uploadTestCase(PyPIRCCommandTestCase):
 
         # The PyPI response body was echoed
         results = self.get_logs(INFO)
-        self.assertIn('xyzzy\n', results[-1])
+        self.assertEqual(results[-1], 75 * '-' + '\nxyzzy\n' + 75 * '-')
 
     def test_upload_fails(self):
         self.next_msg = "Not Found"
         self.next_code = 404
         self.assertRaises(DistutilsError, self.test_upload)
 
+    def test_wrong_exception_order(self):
+        tmp = self.mkdtemp()
+        path = os.path.join(tmp, 'xxx')
+        self.write_file(path)
+        dist_files = [('xxx', '2.6', path)]  # command, pyversion, filename
+        self.write_file(self.rc, PYPIRC_LONG_PASSWORD)
+
+        pkg_dir, dist = self.create_dist(dist_files=dist_files)
+        tests = [
+            (OSError('oserror'), 'oserror', OSError),
+            (HTTPError('url', 400, 'httperror', {}, None),
+             'Upload failed (400): httperror', DistutilsError),
+        ]
+        for exception, expected, raised_exception in tests:
+            with self.subTest(exception=type(exception).__name__):
+                with mock.patch('distutils.command.upload.urlopen',
+                                new=mock.Mock(side_effect=exception)):
+                    with self.assertRaises(raised_exception):
+                        cmd = upload(dist)
+                        cmd.ensure_finalized()
+                        cmd.run()
+                    results = self.get_logs(ERROR)
+                    self.assertIn(expected, results[-1])
+                    self.clear_logs()
+
+
 def test_suite():
     return unittest.makeSuite(uploadTestCase)
 
index 094a2f0..92d14df 100644 (file)
@@ -76,7 +76,9 @@ class UnixCCompiler(CCompiler):
     static_lib_extension = ".a"
     shared_lib_extension = ".so"
     dylib_lib_extension = ".dylib"
+    xcode_stub_lib_extension = ".tbd"
     static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s"
+    xcode_stub_lib_format = dylib_lib_format
     if sys.platform == "cygwin":
         exe_extension = ".exe"
 
@@ -255,12 +257,28 @@ class UnixCCompiler(CCompiler):
     def find_library_file(self, dirs, lib, debug=0):
         shared_f = self.library_filename(lib, lib_type='shared')
         dylib_f = self.library_filename(lib, lib_type='dylib')
+        xcode_stub_f = self.library_filename(lib, lib_type='xcode_stub')
         static_f = self.library_filename(lib, lib_type='static')
 
         if sys.platform == 'darwin':
             # On OSX users can specify an alternate SDK using
             # '-isysroot', calculate the SDK root if it is specified
             # (and use it further on)
+            #
+            # Note that, as of Xcode 7, Apple SDKs may contain textual stub
+            # libraries with .tbd extensions rather than the normal .dylib
+            # shared libraries installed in /.  The Apple compiler tool
+            # chain handles this transparently but it can cause problems
+            # for programs that are being built with an SDK and searching
+            # for specific libraries.  Callers of find_library_file need to
+            # keep in mind that the base filename of the returned SDK library
+            # file might have a different extension from that of the library
+            # file installed on the running system, for example:
+            #   /Applications/Xcode.app/Contents/Developer/Platforms/
+            #       MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/
+            #       usr/lib/libedit.tbd
+            # vs
+            #   /usr/lib/libedit.dylib
             cflags = sysconfig.get_config_var('CFLAGS')
             m = re.search(r'-isysroot\s+(\S+)', cflags)
             if m is None:
@@ -274,6 +292,7 @@ class UnixCCompiler(CCompiler):
             shared = os.path.join(dir, shared_f)
             dylib = os.path.join(dir, dylib_f)
             static = os.path.join(dir, static_f)
+            xcode_stub = os.path.join(dir, xcode_stub_f)
 
             if sys.platform == 'darwin' and (
                 dir.startswith('/System/') or (
@@ -282,6 +301,7 @@ class UnixCCompiler(CCompiler):
                 shared = os.path.join(sysroot, dir[1:], shared_f)
                 dylib = os.path.join(sysroot, dir[1:], dylib_f)
                 static = os.path.join(sysroot, dir[1:], static_f)
+                xcode_stub = os.path.join(sysroot, dir[1:], xcode_stub_f)
 
             # We're second-guessing the linker here, with not much hard
             # data to go on: GCC seems to prefer the shared library, so I'm
@@ -289,6 +309,8 @@ class UnixCCompiler(CCompiler):
             # ignoring even GCC's "-static" option.  So sue me.
             if os.path.exists(dylib):
                 return dylib
+            elif os.path.exists(xcode_stub):
+                return xcode_stub
             elif os.path.exists(shared):
                 return shared
             elif os.path.exists(static):
index 4094723..38fdd80 100644 (file)
@@ -399,8 +399,9 @@ def _module_relative_path(module, path):
             basedir = os.curdir
     else:
         # A module w/o __file__ (this includes builtins)
-        raise ValueError("Can't resolve paths relative to the module " +
-                         module + " (it has no __file__)")
+        raise ValueError("Can't resolve paths relative to the module "
+                         "%r (it has no __file__)"
+                         % module.__name__)
 
     # Combine the base directory and the path.
     return os.path.join(basedir, *(path.split('/')))
index f264191..2226e13 100644 (file)
@@ -1522,7 +1522,7 @@ def get_qp_ctext(value):
     This is not the RFC ctext, since we are handling nested comments in comment
     and unquoting quoted-pairs here.  We allow anything except the '()'
     characters, but if we find any ASCII other than the RFC defined printable
-    ASCII an NonPrintableDefect is added to the token's defects list.  Since
+    ASCII, a NonPrintableDefect is added to the token's defects list.  Since
     quoted pairs are converted to their unquoted values, what is returned is
     a 'ptext' token.  In this case it is a WhiteSpaceTerminal, so it's value
     is ' '.
@@ -1537,7 +1537,7 @@ def get_qcontent(value):
     """qcontent = qtext / quoted-pair
 
     We allow anything except the DQUOTE character, but if we find any ASCII
-    other than the RFC defined printable ASCII an NonPrintableDefect is
+    other than the RFC defined printable ASCII, a NonPrintableDefect is
     added to the token's defects list.  Any quoted pairs are converted to their
     unquoted values, so what is returned is a 'ptext' token.  In this case it
     is a ValueTerminal.
@@ -1882,7 +1882,7 @@ def get_dtext(value):
         obs-dtext = obs-NO-WS-CTL / quoted-pair
 
     We allow anything except the excluded characters, but if we find any
-    ASCII other than the RFC defined printable ASCII an NonPrintableDefect is
+    ASCII other than the RFC defined printable ASCII, a NonPrintableDefect is
     added to the token's defects list.  Quoted pairs are converted to their
     unquoted values, so what is returned is a ptext token, in this case a
     ValueTerminal.  If there were quoted-printables, an ObsoleteHeaderDefect is
@@ -2872,7 +2872,7 @@ def parse_content_type_header(value):
         _find_mime_parameters(ctype, value)
         return ctype
     ctype.append(token)
-    # XXX: If we really want to follow the formal grammer we should make
+    # XXX: If we really want to follow the formal grammar we should make
     # mantype and subtype specialized TokenLists here.  Probably not worth it.
     if not value or value[0] != '/':
         ctype.defects.append(errors.InvalidHeaderDefect(
index 468ca9e..0fc2231 100644 (file)
@@ -16,7 +16,7 @@ from email import _header_value_parser as parser
 class Address:
 
     def __init__(self, display_name='', username='', domain='', addr_spec=None):
-        """Create an object represeting a full email address.
+        """Create an object representing a full email address.
 
         An address can have a 'display_name', a 'username', and a 'domain'.  In
         addition to specifying the username and domain separately, they may be
@@ -109,7 +109,7 @@ class Group:
     def __init__(self, display_name=None, addresses=None):
         """Create an object representing an address group.
 
-        An address group consists of a display_name followed by colon and an
+        An address group consists of a display_name followed by colon and a
         list of addresses (see Address) terminated by a semi-colon.  The Group
         is created by specifying a display_name and a possibly empty list of
         Address objects.  A Group can also be used to represent a single
index a892012..aefaf57 100644 (file)
@@ -710,7 +710,7 @@ class Message:
         message, it will be set to "text/plain" and the new parameter and
         value will be appended as per RFC 2045.
 
-        An alternate header can specified in the header argument, and all
+        An alternate header can be specified in the header argument, and all
         parameters will be quoted as necessary unless requote is False.
 
         If charset is specified, the parameter will be encoded according to RFC
index 8c9bc9e..555b172 100644 (file)
@@ -23,7 +23,7 @@ class Parser:
         textual representation of the message.
 
         The string must be formatted as a block of RFC 2822 headers and header
-        continuation lines, optionally preceeded by a `Unix-from' header.  The
+        continuation lines, optionally preceded by a `Unix-from' header.  The
         header block is terminated either by the end of the string or by a
         blank line.
 
@@ -87,7 +87,7 @@ class BytesParser:
         textual representation of the message.
 
         The input must be formatted as a block of RFC 2822 headers and header
-        continuation lines, optionally preceeded by a `Unix-from' header.  The
+        continuation lines, optionally preceded by a `Unix-from' header.  The
         header block is terminated either by the end of the input or by a
         blank line.
 
index 5080d81..a759d23 100644 (file)
@@ -87,7 +87,7 @@ def formataddr(pair, charset='utf-8'):
     'utf-8'.
     """
     name, address = pair
-    # The address MUST (per RFC) be ascii, so raise an UnicodeError if it isn't.
+    # The address MUST (per RFC) be ascii, so raise a UnicodeError if it isn't.
     address.encode('ascii')
     if name:
         try:
index 2334208..58de103 100644 (file)
@@ -5,6 +5,8 @@
     Original source: LaserJet IIP Printer User's Manual HP part no
     33471-90901, Hewlet-Packard, June 1989.
 
+    (Used with permission)
+
 """#"
 
 import codecs
index 809bc9a..c612482 100644 (file)
@@ -73,7 +73,7 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
         self.decoder = None
 
     def getstate(self):
-        # additonal state info from the base class must be None here,
+        # additional state info from the base class must be None here,
         # as it isn't passed along to the caller
         state = codecs.BufferedIncrementalDecoder.getstate(self)[0]
         # additional state info we pass to the caller:
index c052928..cdf84d1 100644 (file)
@@ -68,7 +68,7 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
         self.decoder = None
 
     def getstate(self):
-        # additonal state info from the base class must be None here,
+        # additional state info from the base class must be None here,
         # as it isn't passed along to the caller
         state = codecs.BufferedIncrementalDecoder.getstate(self)[0]
         # additional state info we pass to the caller:
index 1258833..08aedf9 100644 (file)
@@ -8,9 +8,9 @@ import tempfile
 __all__ = ["version", "bootstrap"]
 
 
-_SETUPTOOLS_VERSION = "18.2"
+_SETUPTOOLS_VERSION = "20.10.1"
 
-_PIP_VERSION = "7.1.2"
+_PIP_VERSION = "8.1.1"
 
 # pip currently requires ssl support, so we try to provide a nicer
 # error message when that is missing (http://bugs.python.org/issue19744)
diff --git a/Lib/ensurepip/_bundled/pip-7.1.2-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-7.1.2-py2.py3-none-any.whl
deleted file mode 100644 (file)
index 5e49015..0000000
Binary files a/Lib/ensurepip/_bundled/pip-7.1.2-py2.py3-none-any.whl and /dev/null differ
diff --git a/Lib/ensurepip/_bundled/pip-8.1.1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-8.1.1-py2.py3-none-any.whl
new file mode 100644 (file)
index 0000000..8632eb7
Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-8.1.1-py2.py3-none-any.whl differ
similarity index 60%
rename from Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl
rename to Lib/ensurepip/_bundled/setuptools-20.10.1-py2.py3-none-any.whl
index f4288d6..9d1319a 100644 (file)
Binary files a/Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl and b/Lib/ensurepip/_bundled/setuptools-20.10.1-py2.py3-none-any.whl differ
index c28f345..b8787d1 100644 (file)
@@ -118,7 +118,7 @@ class EnumMeta(type):
 
         # save attributes from super classes so we know if we can take
         # the shortcut of storing members in the class dict
-        base_attributes = {a for b in bases for a in b.__dict__}
+        base_attributes = {a for b in enum_class.mro() for a in b.__dict__}
 
         # Reverse value->name map for hashable values.
         enum_class._value2member_map_ = {}
@@ -206,6 +206,12 @@ class EnumMeta(type):
             enum_class.__new__ = Enum.__new__
         return enum_class
 
+    def __bool__(self):
+        """
+        classes/types should always be True.
+        """
+        return True
+
     def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1):
         """Either returns an existing member, or creates a new enum class.
 
index c41b94a..d2b5206 100644 (file)
@@ -64,13 +64,6 @@ deleted when the output file is closed.  In-place filtering is
 disabled when standard input is read.  XXX The current implementation
 does not work for MS-DOS 8+3 filesystems.
 
-Performance: this module is unfortunately one of the slower ways of
-processing large numbers of input lines.  Nevertheless, a significant
-speed-up has been obtained by using readlines(bufsize) instead of
-readline().  A new keyword argument, bufsize=N, is present on the
-input() function and the FileInput() class to override the default
-buffer size.
-
 XXX Possible additions:
 
 - optional getopt argument processing
@@ -86,6 +79,7 @@ __all__ = ["input", "close", "nextfile", "filename", "lineno", "filelineno",
 
 _state = None
 
+# No longer used
 DEFAULT_BUFSIZE = 8*1024
 
 def input(files=None, inplace=False, backup="", bufsize=0,
@@ -207,17 +201,14 @@ class FileInput:
         self._files = files
         self._inplace = inplace
         self._backup = backup
-        self._bufsize = bufsize or DEFAULT_BUFSIZE
         self._savestdout = None
         self._output = None
         self._filename = None
-        self._lineno = 0
+        self._startlineno = 0
         self._filelineno = 0
         self._file = None
         self._isstdin = False
         self._backupfilename = None
-        self._buffer = []
-        self._bufindex = 0
         # restrict mode argument to reading modes
         if mode not in ('r', 'rU', 'U', 'rb'):
             raise ValueError("FileInput opening mode must be one of "
@@ -253,22 +244,18 @@ class FileInput:
         return self
 
     def __next__(self):
-        try:
-            line = self._buffer[self._bufindex]
-        except IndexError:
-            pass
-        else:
-            self._bufindex += 1
-            self._lineno += 1
-            self._filelineno += 1
-            return line
-        line = self.readline()
-        if not line:
-            raise StopIteration
-        return line
+        while True:
+            line = self._readline()
+            if line:
+                self._filelineno += 1
+                return line
+            if not self._file:
+                raise StopIteration
+            self.nextfile()
+            # repeat with next file
 
     def __getitem__(self, i):
-        if i != self._lineno:
+        if i != self.lineno():
             raise RuntimeError("accessing lines out of order")
         try:
             return self.__next__()
@@ -290,6 +277,10 @@ class FileInput:
             file = self._file
             self._file = None
             try:
+                del self._readline  # restore FileInput._readline
+            except AttributeError:
+                pass
+            try:
                 if file and not self._isstdin:
                     file.close()
             finally:
@@ -300,85 +291,81 @@ class FileInput:
                     except OSError: pass
 
                 self._isstdin = False
-                self._buffer = []
-                self._bufindex = 0
 
     def readline(self):
-        try:
-            line = self._buffer[self._bufindex]
-        except IndexError:
-            pass
+        while True:
+            line = self._readline()
+            if line:
+                self._filelineno += 1
+                return line
+            if not self._file:
+                return line
+            self.nextfile()
+            # repeat with next file
+
+    def _readline(self):
+        if not self._files:
+            if 'b' in self._mode:
+                return b''
+            else:
+                return ''
+        self._filename = self._files[0]
+        self._files = self._files[1:]
+        self._startlineno = self.lineno()
+        self._filelineno = 0
+        self._file = None
+        self._isstdin = False
+        self._backupfilename = 0
+        if self._filename == '-':
+            self._filename = '<stdin>'
+            if 'b' in self._mode:
+                self._file = getattr(sys.stdin, 'buffer', sys.stdin)
+            else:
+                self._file = sys.stdin
+            self._isstdin = True
         else:
-            self._bufindex += 1
-            self._lineno += 1
-            self._filelineno += 1
-            return line
-        if not self._file:
-            if not self._files:
-                if 'b' in self._mode:
-                    return b''
+            if self._inplace:
+                self._backupfilename = (
+                    self._filename + (self._backup or ".bak"))
+                try:
+                    os.unlink(self._backupfilename)
+                except OSError:
+                    pass
+                # The next few lines may raise OSError
+                os.rename(self._filename, self._backupfilename)
+                self._file = open(self._backupfilename, self._mode)
+                try:
+                    perm = os.fstat(self._file.fileno()).st_mode
+                except OSError:
+                    self._output = open(self._filename, "w")
                 else:
-                    return ''
-            self._filename = self._files[0]
-            self._files = self._files[1:]
-            self._filelineno = 0
-            self._file = None
-            self._isstdin = False
-            self._backupfilename = 0
-            if self._filename == '-':
-                self._filename = '<stdin>'
-                if 'b' in self._mode:
-                    self._file = sys.stdin.buffer
-                else:
-                    self._file = sys.stdin
-                self._isstdin = True
-            else:
-                if self._inplace:
-                    self._backupfilename = (
-                        self._filename + (self._backup or ".bak"))
+                    mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
+                    if hasattr(os, 'O_BINARY'):
+                        mode |= os.O_BINARY
+
+                    fd = os.open(self._filename, mode, perm)
+                    self._output = os.fdopen(fd, "w")
                     try:
-                        os.unlink(self._backupfilename)
+                        if hasattr(os, 'chmod'):
+                            os.chmod(self._filename, perm)
                     except OSError:
                         pass
-                    # The next few lines may raise OSError
-                    os.rename(self._filename, self._backupfilename)
-                    self._file = open(self._backupfilename, self._mode)
-                    try:
-                        perm = os.fstat(self._file.fileno()).st_mode
-                    except OSError:
-                        self._output = open(self._filename, "w")
-                    else:
-                        mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
-                        if hasattr(os, 'O_BINARY'):
-                            mode |= os.O_BINARY
-
-                        fd = os.open(self._filename, mode, perm)
-                        self._output = os.fdopen(fd, "w")
-                        try:
-                            if hasattr(os, 'chmod'):
-                                os.chmod(self._filename, perm)
-                        except OSError:
-                            pass
-                    self._savestdout = sys.stdout
-                    sys.stdout = self._output
+                self._savestdout = sys.stdout
+                sys.stdout = self._output
+            else:
+                # This may raise OSError
+                if self._openhook:
+                    self._file = self._openhook(self._filename, self._mode)
                 else:
-                    # This may raise OSError
-                    if self._openhook:
-                        self._file = self._openhook(self._filename, self._mode)
-                    else:
-                        self._file = open(self._filename, self._mode)
-        self._buffer = self._file.readlines(self._bufsize)
-        self._bufindex = 0
-        if not self._buffer:
-            self.nextfile()
-        # Recursive call
-        return self.readline()
+                    self._file = open(self._filename, self._mode)
+        self._readline = self._file.readline  # hide FileInput._readline
+        return self._readline()
 
     def filename(self):
         return self._filename
 
     def lineno(self):
-        return self._lineno
+        return self._startlineno + self._filelineno
 
     def filelineno(self):
         return self._filelineno
index 45152e4..da4479e 100644 (file)
@@ -133,7 +133,7 @@ class GzipFile(_compression.BaseStream):
         a file object.
 
         When fileobj is not None, the filename argument is only used to be
-        included in the gzip file header, which may includes the original
+        included in the gzip file header, which may include the original
         filename of the uncompressed file.  It defaults to the filename of
         fileobj, if discernible; otherwise, it defaults to the empty string,
         and in this case the original filename is not included in the header.
@@ -210,7 +210,7 @@ class GzipFile(_compression.BaseStream):
 
     def _init_write(self, filename):
         self.name = filename
-        self.crc = zlib.crc32(b"") & 0xffffffff
+        self.crc = zlib.crc32(b"")
         self.size = 0
         self.writebuf = []
         self.bufsize = 0
@@ -261,7 +261,7 @@ class GzipFile(_compression.BaseStream):
         if length > 0:
             self.fileobj.write(self.compress.compress(data))
             self.size += length
-            self.crc = zlib.crc32(data, self.crc) & 0xffffffff
+            self.crc = zlib.crc32(data, self.crc)
             self.offset += length
 
         return length
@@ -381,7 +381,7 @@ class _GzipReader(_compression.DecompressReader):
         self._last_mtime = None
 
     def _init_read(self):
-        self._crc = zlib.crc32(b"") & 0xffffffff
+        self._crc = zlib.crc32(b"")
         self._stream_size = 0  # Decompressed size of unconcatenated stream
 
     def _read_exact(self, n):
@@ -485,7 +485,7 @@ class _GzipReader(_compression.DecompressReader):
         return uncompress
 
     def _add_read_data(self, data):
-        self._crc = zlib.crc32(data, self._crc) & 0xffffffff
+        self._crc = zlib.crc32(data, self._crc)
         self._stream_size = self._stream_size + len(data)
 
     def _read_eof(self):
index 07af37e..0b3e89a 100644 (file)
@@ -54,7 +54,7 @@ representation for a tournament.  The numbers below are `k', not a[k]:
 
 
 In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'.  In
-an usual binary tournament we see in sports, each cell is the winner
+a usual binary tournament we see in sports, each cell is the winner
 over the two cells it tops, and we can trace the winner down the tree
 to see all opponents s/he had.  However, in many computer applications
 of such tournaments, we do not need to trace the history of a winner.
index 43e6411..b781c63 100644 (file)
@@ -143,7 +143,7 @@ class HTMLParser(_markupbase.ParserBase):
                     # or there's more text incoming.  If the latter is True,
                     # we can't pass the text to handle_data in case we have
                     # a charref cut in half at end.  Try to determine if
-                    # this is the case before proceding by looking for an
+                    # this is the case before proceeding by looking for an
                     # & near the end and see if it's followed by a space or ;.
                     amppos = rawdata.rfind('&', max(i, n-34))
                     if (amppos >= 0 and
index 80c80cf..350313e 100644 (file)
@@ -146,6 +146,21 @@ _is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search
 _METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'}
 
 
+def _encode(data, name='data'):
+    """Call data.encode("latin-1") but show a better error message."""
+    try:
+        return data.encode("latin-1")
+    except UnicodeEncodeError as err:
+        raise UnicodeEncodeError(
+            err.encoding,
+            err.object,
+            err.start,
+            err.end,
+            "%s (%.20r) is not valid Latin-1. Use %s.encode('utf-8') "
+            "if you want to send it encoded in UTF-8." %
+            (name.title(), data[err.start:err.end], name)) from None
+
+
 class HTTPMessage(email.message.Message):
     # XXX The only usage of this method is in
     # http.server.CGIHTTPRequestHandler.  Maybe move the code there so
@@ -620,6 +635,8 @@ class HTTPResponse(io.BufferedIOBase):
             return b""
         if self.chunked:
             return self._read1_chunked(n)
+        if self.length is not None and (n < 0 or n > self.length):
+            n = self.length
         try:
             result = self.fp.read1(n)
         except ValueError:
@@ -630,6 +647,8 @@ class HTTPResponse(io.BufferedIOBase):
             result = self.fp.read1(16*1024)
         if not result and n:
             self._close_conn()
+        elif self.length is not None:
+            self.length -= len(result)
         return result
 
     def peek(self, n=-1):
@@ -647,9 +666,13 @@ class HTTPResponse(io.BufferedIOBase):
         if self.chunked:
             # Fallback to IOBase readline which uses peek() and read()
             return super().readline(limit)
+        if self.length is not None and (limit < 0 or limit > self.length):
+            limit = self.length
         result = self.fp.readline(limit)
         if not result and limit:
             self._close_conn()
+        elif self.length is not None:
+            self.length -= len(result)
         return result
 
     def _read1_chunked(self, n):
@@ -1124,7 +1147,7 @@ class HTTPConnection:
         if isinstance(body, str):
             # RFC 2616 Section 3.7.1 says that text default has a
             # default charset of iso-8859-1.
-            body = body.encode('iso-8859-1')
+            body = _encode(body, 'body')
         self.endheaders(body)
 
     def getresponse(self):
@@ -1132,7 +1155,7 @@ class HTTPConnection:
 
         If the HTTPConnection is in the correct state, returns an
         instance of HTTPResponse or of whatever object is returned by
-        class the response_class variable.
+        the response_class variable.
 
         If a request has not been sent or if a previous response has
         not be handled, ResponseNotReady is raised.  If the HTTP
index ac5e667..265ccf9 100644 (file)
@@ -143,6 +143,10 @@ def offset_from_tz_string(tz):
     return offset
 
 def _str2time(day, mon, yr, hr, min, sec, tz):
+    yr = int(yr)
+    if yr > datetime.MAXYEAR:
+        return None
+
     # translate month name to number
     # month numbers start with 1 (January)
     try:
@@ -163,7 +167,6 @@ def _str2time(day, mon, yr, hr, min, sec, tz):
     if min is None: min = 0
     if sec is None: sec = 0
 
-    yr = int(yr)
     day = int(day)
     hr = int(hr)
     min = int(min)
@@ -1838,7 +1841,7 @@ def lwp_cookie_str(cookie):
 class LWPCookieJar(FileCookieJar):
     """
     The LWPCookieJar saves a sequence of "Set-Cookie3" lines.
-    "Set-Cookie3" is the format used by the libwww-perl libary, not known
+    "Set-Cookie3" is the format used by the libwww-perl library, not known
     to be compatible with any browser, but which is easy to read and
     doesn't lose information about RFC 2965 cookies.
 
index fda02b7..a73fe38 100644 (file)
@@ -156,7 +156,7 @@ class CookieError(Exception):
 # a two-way quoting algorithm.  Any non-text character is translated
 # into a 4 character sequence: a forward-slash followed by the
 # three-digit octal equivalent of the character.  Any '\' or '"' is
-# quoted with a preceeding '\' slash.
+# quoted with a preceding '\' slash.
 # Because of the way browsers really handle cookies (as opposed to what
 # the RFC says) we also encode "," and ";".
 #
@@ -174,7 +174,7 @@ _Translator.update({
     ord('\\'): '\\\\',
 })
 
-_is_legal_key = re.compile('[%s]+' % _LegalChars).fullmatch
+_is_legal_key = re.compile('[%s]+' % re.escape(_LegalChars)).fullmatch
 
 def _quote(str):
     r"""Quote a string for use in a cookie header.
index e1b71ab..00620d1 100644 (file)
@@ -337,6 +337,13 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
                 HTTPStatus.BAD_REQUEST,
                 "Line too long")
             return False
+        except http.client.HTTPException as err:
+            self.send_error(
+                HTTPStatus.REQUEST_HEADER_FIELDS_TOO_LARGE,
+                "Too many headers",
+                str(err)
+            )
+            return False
 
         conntype = self.headers.get('Connection', "")
         if conntype.lower() == 'close':
@@ -443,20 +450,30 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
         if explain is None:
             explain = longmsg
         self.log_error("code %d, message %s", code, message)
-        # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
-        content = (self.error_message_format %
-                   {'code': code, 'message': _quote_html(message), 'explain': _quote_html(explain)})
-        body = content.encode('UTF-8', 'replace')
         self.send_response(code, message)
-        self.send_header("Content-Type", self.error_content_type)
         self.send_header('Connection', 'close')
-        self.send_header('Content-Length', int(len(body)))
+
+        # Message body is omitted for cases described in:
+        #  - RFC7230: 3.3. 1xx, 204(No Content), 304(Not Modified)
+        #  - RFC7231: 6.3.6. 205(Reset Content)
+        body = None
+        if (code >= 200 and
+            code not in (HTTPStatus.NO_CONTENT,
+                         HTTPStatus.RESET_CONTENT,
+                         HTTPStatus.NOT_MODIFIED)):
+            # HTML encode to prevent Cross Site Scripting attacks
+            # (see bug #1100201)
+            content = (self.error_message_format % {
+                'code': code,
+                'message': _quote_html(message),
+                'explain': _quote_html(explain)
+            })
+            body = content.encode('UTF-8', 'replace')
+            self.send_header("Content-Type", self.error_content_type)
+            self.send_header('Content-Length', int(len(body)))
         self.end_headers()
 
-        if (self.command != 'HEAD' and
-                code >= 200 and
-                code not in (
-                    HTTPStatus.NO_CONTENT, HTTPStatus.NOT_MODIFIED)):
+        if self.command != 'HEAD' and body:
             self.wfile.write(body)
 
     def send_response(self, code, message=None):
@@ -767,9 +784,9 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
         words = filter(None, words)
         path = os.getcwd()
         for word in words:
-            drive, word = os.path.splitdrive(word)
-            head, word = os.path.split(word)
-            if word in (os.curdir, os.pardir): continue
+            if os.path.dirname(word) or word in (os.curdir, os.pardir):
+                # Ignore components that are not a simple file/directory name
+                continue
             path = os.path.join(path, word)
         if trailing_slash:
             path += '/'
index b20512d..ff085d5 100644 (file)
@@ -1,6 +1,6 @@
 """AutoComplete.py - An IDLE extension for automatically completing names.
 
-This extension can complete either attribute names of file names. It can pop
+This extension can complete either attribute names or file names. It can pop
 a window with all available names, for the user to select from.
 """
 import os
@@ -64,7 +64,7 @@ class AutoComplete:
 
     def try_open_completions_event(self, event):
         """Happens when it would be nice to open a completion list, but not
-        really necessary, for example after an dot, so function
+        really necessary, for example after a dot, so function
         calls won't be made.
         """
         lastchar = self.text.get("insert-1c")
index 5ff599d..3a50eb8 100644 (file)
@@ -24,7 +24,7 @@ Noam Raphael (Code Context, Call Tips, many other patches), and Chui Tey (RPC
 integration, debugger integration and persistent breakpoints).
 
 Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou,
-Jim Jewett, Martin v. Löwis, Jason Orendorff, Guilherme Polo, Josh Robb,
+Jim Jewett, Martin v. Löwis, Jason Orendorff, Guilherme Polo, Josh Robb,
 Nigel Rowe, Bruce Sherwood, Jeff Shute, and Weeble have submitted useful
 patches.  Thanks, guys!
 
index 90e02f6..0c36664 100644 (file)
@@ -1574,7 +1574,7 @@ Mon Oct 12 23:59:27 1998  Guido van Rossum  <guido@cnri.reston.va.us>
        * Attic/PopupMenu.py: Pass a root to the help window.
 
        * SearchBinding.py:
-       Add parent argument to 'to to line number' dialog box.
+       Add parent argument to 'go to line number' dialog box.
 
 Sat Oct 10 19:15:32 1998  Guido van Rossum  <guido@cnri.reston.va.us>
 
index 9f31349..02eac47 100644 (file)
@@ -2,6 +2,7 @@ import time
 import re
 import keyword
 import builtins
+from tkinter import TkVersion
 from idlelib.Delegator import Delegator
 from idlelib.configHandler import idleConf
 
@@ -32,6 +33,28 @@ def make_pat():
 prog = re.compile(make_pat(), re.S)
 idprog = re.compile(r"\s+(\w+)", re.S)
 
+def color_config(text):  # Called from htest, Editor, and Turtle Demo.
+    '''Set color opitons of Text widget.
+
+    Should be called whenever ColorDelegator is called.
+    '''
+    # Not automatic because ColorDelegator does not know 'text'.
+    theme = idleConf.CurrentTheme()
+    normal_colors = idleConf.GetHighlight(theme, 'normal')
+    cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg')
+    select_colors = idleConf.GetHighlight(theme, 'hilite')
+    text.config(
+        foreground=normal_colors['foreground'],
+        background=normal_colors['background'],
+        insertbackground=cursor_color,
+        selectforeground=select_colors['foreground'],
+        selectbackground=select_colors['background'],
+        )
+    if TkVersion >= 8.5:
+        text.config(
+            inactiveselectbackground=select_colors['background'])
+
+
 class ColorDelegator(Delegator):
 
     def __init__(self):
@@ -233,6 +256,7 @@ class ColorDelegator(Delegator):
         for tag in self.tagdefs:
             self.tag_remove(tag, "1.0", "end")
 
+
 def _color_delegator(parent):  # htest #
     from tkinter import Toplevel, Text
     from idlelib.Percolator import Percolator
@@ -247,6 +271,7 @@ def _color_delegator(parent):  # htest #
     text.insert("insert", source)
     text.focus_set()
 
+    color_config(text)
     p = Percolator(text)
     d = ColorDelegator()
     p.insertfilter(d)
index 250422e..d5e217d 100644 (file)
@@ -372,7 +372,7 @@ class StackViewer(ScrolledList):
     def __init__(self, master, flist, gui):
         if macosxSupport.isAquaTk():
             # At least on with the stock AquaTk version on OSX 10.4 you'll
-            # get an shaking GUI that eventually kills IDLE if the width
+            # get a shaking GUI that eventually kills IDLE if the width
             # argument is specified.
             ScrolledList.__init__(self, master)
         else:
index c476516..dc2a1aa 100644 (file)
@@ -1,10 +1,10 @@
 class Delegator:
 
-    # The cache is only used to be able to change delegates!
-
     def __init__(self, delegate=None):
         self.delegate = delegate
         self.__cache = set()
+        # Cache is used to only remove added attributes
+        # when changing the delegate.
 
     def __getattr__(self, name):
         attr = getattr(self.delegate, name) # May raise AttributeError
@@ -13,6 +13,9 @@ class Delegator:
         return attr
 
     def resetcache(self):
+        "Removes added attributes while leaving original attributes."
+        # Function is really about resetting delagator dict
+        # to original state.  Cache is just a means
         for key in self.__cache:
             try:
                 delattr(self, key)
@@ -21,5 +24,10 @@ class Delegator:
         self.__cache.clear()
 
     def setdelegate(self, delegate):
+        "Reset attributes and change delegate."
         self.resetcache()
         self.delegate = delegate
+
+if __name__ == '__main__':
+    from unittest import main
+    main('idlelib.idle_test.test_delegator', verbosity=2)
index b5868be..9944da3 100644 (file)
@@ -90,7 +90,7 @@ helpDialog = HelpDialog()  # singleton instance, no longer used
 
 class EditorWindow(object):
     from idlelib.Percolator import Percolator
-    from idlelib.ColorDelegator import ColorDelegator
+    from idlelib.ColorDelegator import ColorDelegator, color_config
     from idlelib.UndoDelegator import UndoDelegator
     from idlelib.IOBinding import IOBinding, filesystemencoding, encoding
     from idlelib import Bindings
@@ -742,20 +742,7 @@ class EditorWindow(object):
         # Called from self.filename_change_hook and from configDialog.py
         self._rmcolorizer()
         self._addcolorizer()
-        theme = idleConf.CurrentTheme()
-        normal_colors = idleConf.GetHighlight(theme, 'normal')
-        cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg')
-        select_colors = idleConf.GetHighlight(theme, 'hilite')
-        self.text.config(
-            foreground=normal_colors['foreground'],
-            background=normal_colors['background'],
-            insertbackground=cursor_color,
-            selectforeground=select_colors['foreground'],
-            selectbackground=select_colors['background'],
-            )
-        if TkVersion >= 8.5:
-            self.text.config(
-                inactiveselectbackground=select_colors['background'])
+        EditorWindow.color_config(self.text)
 
     IDENTCHARS = string.ascii_letters + string.digits + "_"
 
index 5ec9d54..84f39a2 100644 (file)
@@ -10,6 +10,7 @@ import tkinter.filedialog as tkFileDialog
 import tkinter.messagebox as tkMessageBox
 from tkinter.simpledialog import askstring
 
+from idlelib.configHandler import idleConf
 
 
 # Try setting the locale, so that we can find out
@@ -61,7 +62,7 @@ locale_encoding = locale_encoding.lower()
 encoding = locale_encoding  ### KBK 07Sep07  This is used all over IDLE, check!
                             ### 'encoding' is used below in encode(), check!
 
-coding_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII)
+coding_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII)
 blank_re = re.compile(r'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII)
 
 def coding_spec(data):
@@ -525,7 +526,6 @@ class IOBinding:
 
 def _io_binding(parent):  # htest #
     from tkinter import Toplevel, Text
-    from idlelib.configHandler import idleConf
 
     root = Toplevel(parent)
     root.title("Test IOBinding")
@@ -536,14 +536,23 @@ def _io_binding(parent):  # htest #
             self.text = text
             self.flist = None
             self.text.bind("<Control-o>", self.open)
+            self.text.bind('<Control-p>', self.print)
             self.text.bind("<Control-s>", self.save)
+            self.text.bind("<Alt-s>", self.saveas)
+            self.text.bind('<Control-c>', self.savecopy)
         def get_saved(self): return 0
         def set_saved(self, flag): pass
         def reset_undo(self): pass
         def open(self, event):
             self.text.event_generate("<<open-window-from-file>>")
+        def print(self, event):
+            self.text.event_generate("<<print-window>>")
         def save(self, event):
             self.text.event_generate("<<save-window>>")
+        def saveas(self, event):
+            self.text.event_generate("<<save-window-as-file>>")
+        def savecopy(self, event):
+            self.text.event_generate("<<save-copy-of-window-as-file>>")
 
     text = Text(root)
     text.pack()
index 251a84d..8462854 100644 (file)
@@ -111,7 +111,7 @@ class _SimpleBinder:
                     raise
 
 # An int in range(1 << len(_modifiers)) represents a combination of modifiers
-# (if the least significent bit is on, _modifiers[0] is on, and so on).
+# (if the least significant bit is on, _modifiers[0] is on, and so on).
 # _state_subsets gives for each combination of modifiers, or *state*,
 # a list of the states which are a subset of it. This list is ordered by the
 # number of modifiers is the state - the most specific state comes first.
index 0eb939b..00d5005 100644 (file)
@@ -1,3 +1,58 @@
+What's New in IDLE 3.5.2?
+=========================
+*Release date: 2016-06-30?*
+
+- Issue #5124: Paste with text selected now replaces the selection on X11.
+  This matches how paste works on Windows, Mac, most modern Linux apps,
+  and ttk widgets.  Original patch by Serhiy Storchaka.
+
+- Issue #24759: Make clear in idlelib.idle_test.__init__ that the directory
+  is a private implementation of test.test_idle and tool for maintainers.
+
+- Issue #27196: Stop 'ThemeChangef' warnings when running IDLE tests.
+  These persisted after other warnings were suppressed in #20567.
+  Apply Serhiy Storchaka's update_idletasks solution to four test files.
+  Record this additional advice in idle_test/README.txt
+
+- Issue #20567: Revise idle_test/README.txt with advice about avoiding
+  tk warning messages from tests.  Apply advice to several IDLE tests.
+
+- Issue #27117: Make colorizer htest and turtledemo work with dark themes.
+  Move code for configuring text widget colors to a new function.
+
+- Issue #26673: When tk reports font size as 0, change to size 10.
+  Such fonts on Linux prevented the configuration dialog from opening.
+
+- Issue #21939: Add test for IDLE's percolator.
+  Original patch by Saimadhav Heblikar.
+
+- Issue #21676: Add test for IDLE's replace dialog.
+  Original patch by Saimadhav Heblikar.
+
+- Issue #18410: Add test for IDLE's search dialog.
+  Original patch by Westley Martínez.
+
+- Issue #21703: Add test for undo delegator.
+  Original patch by Saimadhav Heblikar .
+
+- Issue #27044: Add ConfigDialog.remove_var_callbacks to stop memory leaks.
+
+- Issue #23977: Add more asserts to test_delegator.
+
+- Issue #20640: Add tests for idlelib.configHelpSourceEdit.
+  Patch by Saimadhav Heblikar.
+
+- In the 'IDLE-console differences' section of the IDLE doc, clarify
+  how running with IDLE affects sys.modules and the standard streams.
+
+- Issue #25507: fix incorrect change in IOBinding that prevented printing.
+  Augment IOBinding htest to include all major IOBinding functions.
+
+- Issue #25905: Revert unwanted conversion of ' to ’ RIGHT SINGLE QUOTATION
+  MARK in README.txt and open this and NEWS.txt with 'ascii'.
+  Re-encode CREDITS.txt to utf-8 and open it with 'utf-8'.
+
+
 What's New in IDLE 3.5.1?
 =========================
 *Release date: 2015-12-06*
@@ -149,7 +204,7 @@ What's New in IDLE 3.5.0?
   move version to end.
 
 - Issue #14105: Idle debugger breakpoints no longer disappear
-  when inseting or deleting lines.
+  when inserting or deleting lines.
 
 - Issue #17172: Turtledemo can now be run from Idle.
   Currently, the entry is on the Help menu, but it may move to Run.
index 9e93319..b8be2aa 100644 (file)
@@ -1,6 +1,7 @@
 from idlelib.WidgetRedirector import WidgetRedirector
 from idlelib.Delegator import Delegator
 
+
 class Percolator:
 
     def __init__(self, text):
@@ -16,8 +17,10 @@ class Percolator:
         while self.top is not self.bottom:
             self.removefilter(self.top)
         self.top = None
-        self.bottom.setdelegate(None); self.bottom = None
-        self.redir.close(); self.redir = None
+        self.bottom.setdelegate(None)
+        self.bottom = None
+        self.redir.close()
+        self.redir = None
         self.text = None
 
     def insert(self, index, chars, tags=None):
@@ -51,54 +54,52 @@ class Percolator:
             f.setdelegate(filter.delegate)
             filter.setdelegate(None)
 
-def _percolator(parent):
+
+def _percolator(parent):  # htest #
     import tkinter as tk
     import re
+
     class Tracer(Delegator):
         def __init__(self, name):
             self.name = name
             Delegator.__init__(self, None)
+
         def insert(self, *args):
             print(self.name, ": insert", args)
             self.delegate.insert(*args)
+
         def delete(self, *args):
             print(self.name, ": delete", args)
             self.delegate.delete(*args)
-    root = tk.Tk()
-    root.title("Test Percolator")
+
+    box = tk.Toplevel(parent)
+    box.title("Test Percolator")
     width, height, x, y = list(map(int, re.split('[x+]', parent.geometry())))
-    root.geometry("+%d+%d"%(x, y + 150))
-    text = tk.Text(root)
+    box.geometry("+%d+%d" % (x, y + 150))
+    text = tk.Text(box)
     p = Percolator(text)
+    pin = p.insertfilter
+    pout = p.removefilter
     t1 = Tracer("t1")
     t2 = Tracer("t2")
 
     def toggle1():
-        if var1.get() == 0:
-            var1.set(1)
-            p.insertfilter(t1)
-        elif var1.get() == 1:
-            var1.set(0)
-            p.removefilter(t1)
-
+        (pin if var1.get() else pout)(t1)
     def toggle2():
-        if var2.get() == 0:
-            var2.set(1)
-            p.insertfilter(t2)
-        elif var2.get() == 1:
-            var2.set(0)
-            p.removefilter(t2)
+        (pin if var2.get() else pout)(t2)
 
     text.pack()
     var1 = tk.IntVar()
-    cb1 = tk.Checkbutton(root, text="Tracer1", command=toggle1, variable=var1)
+    cb1 = tk.Checkbutton(box, text="Tracer1", command=toggle1, variable=var1)
     cb1.pack()
     var2 = tk.IntVar()
-    cb2 = tk.Checkbutton(root, text="Tracer2", command=toggle2, variable=var2)
+    cb2 = tk.Checkbutton(box, text="Tracer2", command=toggle2, variable=var2)
     cb2.pack()
 
-    root.mainloop()
-
 if __name__ == "__main__":
+    import unittest
+    unittest.main('idlelib.idle_test.test_percolator', verbosity=2,
+                  exit=False)
+
     from idlelib.idle_test.htest import run
     run(_percolator)
index 1bcc9b6..5dec68e 100755 (executable)
@@ -1396,6 +1396,17 @@ class PseudoInputFile(PseudoFile):
         self.shell.close()
 
 
+def fix_x11_paste(root):
+    "Make paste replace selection on x11.  See issue #5124."
+    if root._windowingsystem == 'x11':
+        for cls in 'Text', 'Entry', 'Spinbox':
+            root.bind_class(
+                cls,
+                '<<Paste>>',
+                'catch {%W delete sel.first sel.last}\n' +
+                        root.bind_class(cls, '<<Paste>>'))
+
+
 usage_msg = """\
 
 USAGE: idle  [-deins] [-t title] [file]*
@@ -1528,8 +1539,10 @@ def main():
                                     'editor-on-startup', type='bool')
     enable_edit = enable_edit or edit_start
     enable_shell = enable_shell or not enable_edit
+
     # start editor and/or shell windows:
     root = Tk(className="Idle")
+    root.withdraw()
 
     # set application icon
     icondir = os.path.join(os.path.dirname(__file__), 'Icons')
@@ -1544,7 +1557,7 @@ def main():
         root.wm_iconphoto(True, *icons)
 
     fixwordbreaks(root)
-    root.withdraw()
+    fix_x11_paste(root)
     flist = PyShellFileList(root)
     macosxSupport.setupApp(root, flist)
 
index b5663c2..7bf74c0 100644 (file)
@@ -1,6 +1,6 @@
 README.txt: an index to idlelib files and the IDLE menu.
 
-IDLE is Python\92s Integrated Development and Learning
+IDLE is Python's Integrated Development and Learning
 Environment.  The user documentation is part of the Library Reference and
 is available in IDLE by selecting Help => IDLE Help.  This README documents
 idlelib for IDLE developers and curious users.
index 2665a1c..f2ea22e 100644 (file)
@@ -1,3 +1,8 @@
+"""Replace dialog for IDLE. Inherits SearchDialogBase for GUI.
+Uses idlelib.SearchEngine for search capability.
+Defines various replace related functions like replace, replace all,
+replace+find.
+"""
 from tkinter import *
 
 from idlelib import SearchEngine
@@ -6,6 +11,8 @@ import re
 
 
 def replace(text):
+    """Returns a singleton ReplaceDialog instance.The single dialog
+     saves user entries and preferences across instances."""
     root = text._root()
     engine = SearchEngine.get(root)
     if not hasattr(engine, "_replacedialog"):
@@ -24,6 +31,7 @@ class ReplaceDialog(SearchDialogBase):
         self.replvar = StringVar(root)
 
     def open(self, text):
+        """Display the replace dialog"""
         SearchDialogBase.open(self, text)
         try:
             first = text.index("sel.first")
@@ -39,6 +47,7 @@ class ReplaceDialog(SearchDialogBase):
         self.ok = 1
 
     def create_entries(self):
+        """Create label and text entry widgets"""
         SearchDialogBase.create_entries(self)
         self.replent = self.make_entry("Replace with:", self.replvar)[0]
 
@@ -57,9 +66,10 @@ class ReplaceDialog(SearchDialogBase):
             self.do_replace()
 
     def default_command(self, event=None):
+        "Replace and find next."
         if self.do_find(self.ok):
-            if self.do_replace():   # Only find next match if replace succeeded.
-                                    # A bad re can cause it to fail.
+            if self.do_replace():  # Only find next match if replace succeeded.
+                                   # A bad re can cause it to fail.
                 self.do_find(0)
 
     def _replace_expand(self, m, repl):
@@ -77,6 +87,7 @@ class ReplaceDialog(SearchDialogBase):
         return new
 
     def replace_all(self, event=None):
+        """Replace all instances of patvar with replvar in text"""
         prog = self.engine.getprog()
         if not prog:
             return
@@ -173,6 +184,8 @@ class ReplaceDialog(SearchDialogBase):
         return True
 
     def show_hit(self, first, last):
+        """Highlight text from 'first' to 'last'.
+        'first', 'last' - Text indices"""
         text = self.text
         text.mark_set("insert", first)
         text.tag_remove("sel", "1.0", "end")
@@ -189,11 +202,13 @@ class ReplaceDialog(SearchDialogBase):
         SearchDialogBase.close(self, event)
         self.text.tag_remove("hit", "1.0", "end")
 
-def _replace_dialog(parent):
-    root = Tk()
-    root.title("Test ReplaceDialog")
+
+def _replace_dialog(parent):  # htest #
+    """htest wrapper function"""
+    box = Toplevel(parent)
+    box.title("Test ReplaceDialog")
     width, height, x, y = list(map(int, re.split('[x+]', parent.geometry())))
-    root.geometry("+%d+%d"%(x, y + 150))
+    box.geometry("+%d+%d"%(x, y + 150))
 
     # mock undo delegator methods
     def undo_block_start():
@@ -202,20 +217,25 @@ def _replace_dialog(parent):
     def undo_block_stop():
         pass
 
-    text = Text(root)
+    text = Text(box, inactiveselectbackground='gray')
     text.undo_block_start = undo_block_start
     text.undo_block_stop = undo_block_stop
     text.pack()
-    text.insert("insert","This is a sample string.\n"*10)
+    text.insert("insert","This is a sample sTring\nPlus MORE.")
+    text.focus_set()
 
     def show_replace():
         text.tag_add(SEL, "1.0", END)
         replace(text)
         text.tag_remove(SEL, "1.0", END)
 
-    button = Button(root, text="Replace", command=show_replace)
+    button = Button(box, text="Replace", command=show_replace)
     button.pack()
 
 if __name__ == '__main__':
+    import unittest
+    unittest.main('idlelib.idle_test.test_replacedialog',
+                verbosity=2, exit=False)
+
     from idlelib.idle_test.htest import run
     run(_replace_dialog)
index 77ef7b9..765d53f 100644 (file)
@@ -4,6 +4,7 @@ from idlelib import SearchEngine
 from idlelib.SearchDialogBase import SearchDialogBase
 
 def _setup(text):
+    "Create or find the singleton SearchDialog instance."
     root = text._root()
     engine = SearchEngine.get(root)
     if not hasattr(engine, "_searchdialog"):
@@ -11,13 +12,16 @@ def _setup(text):
     return engine._searchdialog
 
 def find(text):
+    "Handle the editor edit menu item and corresponding event."
     pat = text.get("sel.first", "sel.last")
-    return _setup(text).open(text,pat)
+    return _setup(text).open(text, pat)  # Open is inherited from SDBase.
 
 def find_again(text):
+    "Handle the editor edit menu item and corresponding event."
     return _setup(text).find_again(text)
 
 def find_selection(text):
+    "Handle the editor edit menu item and corresponding event."
     return _setup(text).find_selection(text)
 
 class SearchDialog(SearchDialogBase):
@@ -66,24 +70,28 @@ class SearchDialog(SearchDialogBase):
             self.engine.setcookedpat(pat)
         return self.find_again(text)
 
-def _search_dialog(parent):
-    root = Tk()
-    root.title("Test SearchDialog")
+
+def _search_dialog(parent):  # htest #
+    '''Display search test box.'''
+    box = Toplevel(parent)
+    box.title("Test SearchDialog")
     width, height, x, y = list(map(int, re.split('[x+]', parent.geometry())))
-    root.geometry("+%d+%d"%(x, y + 150))
-    text = Text(root)
+    box.geometry("+%d+%d"%(x, y + 150))
+    text = Text(box, inactiveselectbackground='gray')
     text.pack()
-    text.insert("insert","This is a sample string.\n"*10)
+    text.insert("insert","This is a sample string.\n"*5)
 
     def show_find():
         text.tag_add(SEL, "1.0", END)
-        s = _setup(text)
-        s.open(text)
+        _setup(text).open(text)
         text.tag_remove(SEL, "1.0", END)
 
-    button = Button(root, text="Search", command=show_find)
+    button = Button(box, text="Search (selection ignored)", command=show_find)
     button.pack()
 
 if __name__ == '__main__':
+    import unittest
+    unittest.main('idlelib.idle_test.test_searchdialog',
+                  verbosity=2, exit=False)
     from idlelib.idle_test.htest import run
     run(_search_dialog)
index 04c1cf5..1c2502d 100644 (file)
@@ -336,30 +336,33 @@ class CommandSequence(Command):
         self.depth = self.depth + incr
         return self.depth
 
-def _undo_delegator(parent):
+
+def _undo_delegator(parent):  # htest #
+    import re
+    import tkinter as tk
     from idlelib.Percolator import Percolator
-    root = Tk()
-    root.title("Test UndoDelegator")
+    undowin = tk.Toplevel()
+    undowin.title("Test UndoDelegator")
     width, height, x, y = list(map(int, re.split('[x+]', parent.geometry())))
-    root.geometry("+%d+%d"%(x, y + 150))
+    undowin.geometry("+%d+%d"%(x, y + 150))
 
-    text = Text(root)
-    text.config(height=10)
+    text = Text(undowin, height=10)
     text.pack()
     text.focus_set()
     p = Percolator(text)
     d = UndoDelegator()
     p.insertfilter(d)
 
-    undo = Button(root, text="Undo", command=lambda:d.undo_event(None))
+    undo = Button(undowin, text="Undo", command=lambda:d.undo_event(None))
     undo.pack(side='left')
-    redo = Button(root, text="Redo", command=lambda:d.redo_event(None))
+    redo = Button(undowin, text="Redo", command=lambda:d.redo_event(None))
     redo.pack(side='left')
-    dump = Button(root, text="Dump", command=lambda:d.dump_event(None))
+    dump = Button(undowin, text="Dump", command=lambda:d.dump_event(None))
     dump.pack(side='left')
 
-    root.mainloop()
-
 if __name__ == "__main__":
+    import unittest
+    unittest.main('idlelib.idle_test.test_undodelegator', verbosity=2,
+                  exit=False)
     from idlelib.idle_test.htest import run
     run(_undo_delegator)
index 67d7f61..b66be9e 100644 (file)
@@ -68,7 +68,7 @@ class WidgetRedirector:
         '''Return OriginalCommand(operation) after registering function.
 
         Registration adds an operation: function pair to ._operations.
-        It also adds an widget function attribute that masks the tkinter
+        It also adds a widget function attribute that masks the tkinter
         class instance method.  Method masking operates independently
         from command dispatch.
 
index d876a97..0457c43 100644 (file)
@@ -111,6 +111,7 @@ class AboutDialog(Toplevel):
                                 command=self.ShowIDLECredits)
         idle_credits_b.pack(side=LEFT, padx=10, pady=10)
 
+    # License, et all, are of type _sitebuiltins._Printer
     def ShowLicense(self):
         self.display_printer_text('About - License', license)
 
@@ -120,14 +121,16 @@ class AboutDialog(Toplevel):
     def ShowPythonCredits(self):
         self.display_printer_text('About - Python Credits', credits)
 
+    # Encode CREDITS.txt to utf-8 for proper version of Loewis.
+    # Specify others as ascii until need utf-8, so catch errors.
     def ShowIDLECredits(self):
-        self.display_file_text('About - Credits', 'CREDITS.txt', 'iso-8859-1')
+        self.display_file_text('About - Credits', 'CREDITS.txt', 'utf-8')
 
     def ShowIDLEAbout(self):
-        self.display_file_text('About - Readme', 'README.txt')
+        self.display_file_text('About - Readme', 'README.txt', 'ascii')
 
     def ShowIDLENEWS(self):
-        self.display_file_text('About - NEWS', 'NEWS.txt')
+        self.display_file_text('About - NEWS', 'NEWS.txt', 'utf-8')
 
     def display_printer_text(self, title, printer):
         printer._Printer__setup()
index 9b16459..b702253 100644 (file)
@@ -483,6 +483,17 @@ class ConfigDialog(Toplevel):
         self.autoSave.trace_variable('w', self.VarChanged_autoSave)
         self.encoding.trace_variable('w', self.VarChanged_encoding)
 
+    def remove_var_callbacks(self):
+        "Remove callbacks to prevent memory leaks."
+        for var in (
+                self.fontSize, self.fontName, self.fontBold,
+                self.spaceNum, self.colour, self.builtinTheme,
+                self.customTheme, self.themeIsBuiltin, self.highlightTarget,
+                self.keyBinding, self.builtinKeys, self.customKeys,
+                self.keysAreBuiltin, self.winWidth, self.winHeight,
+                self.startupEdit, self.autoSave, self.encoding,):
+            var.trace_vdelete('w', var.trace_vinfo()[0][1])
+
     def VarChanged_font(self, *params):
         '''When one font attribute changes, save them all, as they are
         not independent from each other. In particular, when we are
@@ -1196,7 +1207,7 @@ class ConfigDialog(Toplevel):
 
         All values are treated as text, and it is up to the user to supply
         reasonable values. The only exception to this are the 'enable*' options,
-        which are boolean, and can be toggled with an True/False button.
+        which are boolean, and can be toggled with a True/False button.
         """
         parent = self.parent
         frame = self.tabPages.pages['Extensions'].frame
index 531efb4..8ac1f60 100644 (file)
@@ -720,7 +720,7 @@ class IdleConf:
                 actualFont = Font.actual(f)
                 family = actualFont['family']
                 size = actualFont['size']
-                if size < 0:
+                if size <= 0:
                     size = 10  # if font in pixels, ignore actual size
                 bold = actualFont['weight']=='bold'
         return (family, size, 'bold' if bold else 'normal')
index 242b08d..cde8118 100644 (file)
@@ -23,10 +23,10 @@ class GetHelpSourceDialog(Toplevel):
         self.title(title)
         self.transient(parent)
         self.grab_set()
-        self.protocol("WM_DELETE_WINDOW", self.Cancel)
+        self.protocol("WM_DELETE_WINDOW", self.cancel)
         self.parent = parent
         self.result = None
-        self.CreateWidgets()
+        self.create_widgets()
         self.menu.set(menuItem)
         self.path.set(filePath)
         self.withdraw() #hide while setting geometry
@@ -41,10 +41,10 @@ class GetHelpSourceDialog(Toplevel):
                     ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                     if not _htest else 150)))
         self.deiconify() #geometry set, unhide
-        self.bind('<Return>', self.Ok)
+        self.bind('<Return>', self.ok)
         self.wait_window()
 
-    def CreateWidgets(self):
+    def create_widgets(self):
         self.menu = StringVar(self)
         self.path = StringVar(self)
         self.fontSize = StringVar(self)
@@ -65,18 +65,18 @@ class GetHelpSourceDialog(Toplevel):
         labelPath.pack(anchor=W, padx=5, pady=3)
         self.entryPath.pack(anchor=W, padx=5, pady=3)
         browseButton = Button(self.frameMain, text='Browse', width=8,
-                              command=self.browseFile)
+                              command=self.browse_file)
         browseButton.pack(pady=3)
         frameButtons = Frame(self)
         frameButtons.pack(side=BOTTOM, fill=X)
         self.buttonOk = Button(frameButtons, text='OK',
-                               width=8, default=ACTIVE,  command=self.Ok)
+                               width=8, default=ACTIVE,  command=self.ok)
         self.buttonOk.grid(row=0, column=0, padx=5,pady=5)
         self.buttonCancel = Button(frameButtons, text='Cancel',
-                                   width=8, command=self.Cancel)
+                                   width=8, command=self.cancel)
         self.buttonCancel.grid(row=0, column=1, padx=5, pady=5)
 
-    def browseFile(self):
+    def browse_file(self):
         filetypes = [
             ("HTML Files", "*.htm *.html", "TEXT"),
             ("PDF Files", "*.pdf", "TEXT"),
@@ -99,9 +99,9 @@ class GetHelpSourceDialog(Toplevel):
         if file:
             self.path.set(file)
 
-    def MenuOk(self):
+    def menu_ok(self):
         "Simple validity check for a sensible menu item name"
-        menuOk = True
+        menu_ok = True
         menu = self.menu.get()
         menu.strip()
         if not menu:
@@ -109,19 +109,19 @@ class GetHelpSourceDialog(Toplevel):
                                    message='No menu item specified',
                                    parent=self)
             self.entryMenu.focus_set()
-            menuOk = False
+            menu_ok = False
         elif len(menu) > 30:
             tkMessageBox.showerror(title='Menu Item Error',
                                    message='Menu item too long:'
                                            '\nLimit 30 characters.',
                                    parent=self)
             self.entryMenu.focus_set()
-            menuOk = False
-        return menuOk
+            menu_ok = False
+        return menu_ok
 
-    def PathOk(self):
+    def path_ok(self):
         "Simple validity check for menu file path"
-        pathOk = True
+        path_ok = True
         path = self.path.get()
         path.strip()
         if not path: #no path specified
@@ -129,7 +129,7 @@ class GetHelpSourceDialog(Toplevel):
                                    message='No help file path specified.',
                                    parent=self)
             self.entryPath.focus_set()
-            pathOk = False
+            path_ok = False
         elif path.startswith(('www.', 'http')):
             pass
         else:
@@ -140,16 +140,16 @@ class GetHelpSourceDialog(Toplevel):
                                        message='Help file path does not exist.',
                                        parent=self)
                 self.entryPath.focus_set()
-                pathOk = False
-        return pathOk
+                path_ok = False
+        return path_ok
 
-    def Ok(self, event=None):
-        if self.MenuOk() and self.PathOk():
+    def ok(self, event=None):
+        if self.menu_ok() and self.path_ok():
             self.result = (self.menu.get().strip(),
                            self.path.get().strip())
             if sys.platform == 'darwin':
                 path = self.result[1]
-                if path.startswith(('www', 'file:', 'http:')):
+                if path.startswith(('www', 'file:', 'http:', 'https:')):
                     pass
                 else:
                     # Mac Safari insists on using the URI form for local files
@@ -157,10 +157,14 @@ class GetHelpSourceDialog(Toplevel):
                     self.result[1] = "file://" + path
             self.destroy()
 
-    def Cancel(self, event=None):
+    def cancel(self, event=None):
         self.result = None
         self.destroy()
 
 if __name__ == '__main__':
+    import unittest
+    unittest.main('idlelib.idle_test.test_config_help',
+                   verbosity=2, exit=False)
+
     from idlelib.idle_test.htest import run
     run(GetHelpSourceDialog)
index 2189fd4..6f739c4 100644 (file)
@@ -6,7 +6,7 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
-    <title>25.5. IDLE &mdash; Python 3.4.3 documentation</title>
+    <title>25.5. IDLE &mdash; Python 3.5.1 documentation</title>
 
     <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
     <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@@ -14,7 +14,7 @@
     <script type="text/javascript">
       var DOCUMENTATION_OPTIONS = {
         URL_ROOT:    '../',
-        VERSION:     '3.4.3',
+        VERSION:     '3.5.1',
         COLLAPSE_INDEX: false,
         FILE_SUFFIX: '.html',
         HAS_SOURCE:  true
     <script type="text/javascript" src="../_static/doctools.js"></script>
     <script type="text/javascript" src="../_static/sidebar.js"></script>
     <link rel="search" type="application/opensearchdescription+xml"
-          title="Search within Python 3.4.3 documentation"
+          title="Search within Python 3.5.1 documentation"
           href="../_static/opensearch.xml"/>
     <link rel="author" title="About these documents" href="../about.html" />
     <link rel="copyright" title="Copyright" href="../copyright.html" />
-    <link rel="top" title="Python 3.4.3 documentation" href="../index.html" />
+    <link rel="top" title="Python 3.5.1 documentation" href="../contents.html" />
     <link rel="up" title="25. Graphical User Interfaces with Tk" href="tk.html" />
     <link rel="next" title="25.6. Other Graphical User Interface Packages" href="othergui.html" />
     <link rel="prev" title="25.4. tkinter.scrolledtext — Scrolled Text Widget" href="tkinter.scrolledtext.html" />
@@ -40,8 +40,8 @@
 
 
   </head>
-  <body>
-    <div class="related">
+  <body role="document">
+    <div class="related" role="navigation" aria-label="related navigation">
       <h3>Navigation</h3>
       <ul>
         <li class="right" style="margin-right: 10px">
                  style="vertical-align: middle; margin-top: -1px"/></li>
         <li><a href="https://www.python.org/">Python</a> &raquo;</li>
         <li>
-          <a href="../index.html">3.4.3 Documentation</a> &raquo;
+          <a href="../index.html">3.5.1 Documentation</a> &raquo;
         </li>
 
-          <li><a href="index.html" >The Python Standard Library</a> &raquo;</li>
-          <li><a href="tk.html" accesskey="U">25. Graphical User Interfaces with Tk</a> &raquo;</li>
+          <li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> &raquo;</li>
+          <li class="nav-item nav-item-2"><a href="tk.html" accesskey="U">25. Graphical User Interfaces with Tk</a> &raquo;</li>
       </ul>
     </div>
 
     <div class="document">
       <div class="documentwrapper">
         <div class="bodywrapper">
-          <div class="body">
+          <div class="body" role="main">
 
   <div class="section" id="idle">
 <span id="id1"></span><h1>25.5. IDLE<a class="headerlink" href="#idle" title="Permalink to this headline">¶</a></h1>
-<p id="index-0">IDLE is Python&#8217;s Integrated Development and Learning Environment.</p>
+<p><strong>Source code:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/idlelib/">Lib/idlelib/</a></p>
+<hr class="docutils" id="index-0" />
+<p>IDLE is Python&#8217;s Integrated Development and Learning Environment.</p>
 <p>IDLE has the following features:</p>
 <ul class="simple">
-<li>coded in 100% pure Python, using the <a class="reference internal" href="tkinter.html#module-tkinter" title="tkinter: Interface to Tcl/Tk for graphical user interfaces"><tt class="xref py py-mod docutils literal"><span class="pre">tkinter</span></tt></a> GUI toolkit</li>
+<li>coded in 100% pure Python, using the <a class="reference internal" href="tkinter.html#module-tkinter" title="tkinter: Interface to Tcl/Tk for graphical user interfaces"><code class="xref py py-mod docutils literal"><span class="pre">tkinter</span></code></a> GUI toolkit</li>
 <li>cross-platform: works mostly the same on Windows, Unix, and Mac OS X</li>
 <li>Python shell window (interactive interpreter) with colorizing
 of code input, output, and error messages</li>
@@ -163,7 +165,7 @@ be undone.</dd>
 <dt>Find Selection</dt>
 <dd>Search for the currently selected string, if there is one.</dd>
 <dt>Find in Files...</dt>
-<dd>Open a file search dialog.  Put results in an new output window.</dd>
+<dd>Open a file search dialog.  Put results in a new output window.</dd>
 <dt>Replace...</dt>
 <dd>Open a search-and-replace dialog.</dd>
 <dt>Go to Line</dt>
@@ -224,10 +226,10 @@ Editor window.</dd>
 <dt>Run Module</dt>
 <dd>Do Check Module (above).  If no error, restart the shell to clean the
 environment, then execute the module.  Output is displayed in the Shell
-window.  Note that output requires use of <tt class="docutils literal"><span class="pre">print</span></tt> or <tt class="docutils literal"><span class="pre">write</span></tt>.
+window.  Note that output requires use of <code class="docutils literal"><span class="pre">print</span></code> or <code class="docutils literal"><span class="pre">write</span></code>.
 When execution is complete, the Shell retains focus and displays a prompt.
 At this point, one may interactively explore the result of execution.
-This is similar to executing a file with <tt class="docutils literal"><span class="pre">python</span> <span class="pre">-i</span> <span class="pre">file</span></tt> at a command
+This is similar to executing a file with <code class="docutils literal"><span class="pre">python</span> <span class="pre">-i</span> <span class="pre">file</span></code> at a command
 line.</dd>
 </dl>
 </div>
@@ -339,47 +341,47 @@ debugger.  Breakpoints for a file are saved in the user&#8217;s .idlerc director
 </div>
 <div class="section" id="editing-and-navigation">
 <h2>25.5.2. Editing and navigation<a class="headerlink" href="#editing-and-navigation" title="Permalink to this headline">¶</a></h2>
-<p>In this section, &#8216;C&#8217; refers to the <tt class="kbd docutils literal"><span class="pre">Control</span></tt> key on Windows and Unix and
-the <tt class="kbd docutils literal"><span class="pre">Command</span></tt> key on Mac OSX.</p>
+<p>In this section, &#8216;C&#8217; refers to the <code class="kbd docutils literal"><span class="pre">Control</span></code> key on Windows and Unix and
+the <code class="kbd docutils literal"><span class="pre">Command</span></code> key on Mac OSX.</p>
 <ul>
-<li><p class="first"><tt class="kbd docutils literal"><span class="pre">Backspace</span></tt> deletes to the left; <tt class="kbd docutils literal"><span class="pre">Del</span></tt> deletes to the right</p>
+<li><p class="first"><code class="kbd docutils literal"><span class="pre">Backspace</span></code> deletes to the left; <code class="kbd docutils literal"><span class="pre">Del</span></code> deletes to the right</p>
 </li>
-<li><p class="first"><tt class="kbd docutils literal"><span class="pre">C-Backspace</span></tt> delete word left; <tt class="kbd docutils literal"><span class="pre">C-Del</span></tt> delete word to the right</p>
+<li><p class="first"><code class="kbd docutils literal"><span class="pre">C-Backspace</span></code> delete word left; <code class="kbd docutils literal"><span class="pre">C-Del</span></code> delete word to the right</p>
 </li>
-<li><p class="first">Arrow keys and <tt class="kbd docutils literal"><span class="pre">Page</span> <span class="pre">Up</span></tt>/<tt class="kbd docutils literal"><span class="pre">Page</span> <span class="pre">Down</span></tt> to move around</p>
+<li><p class="first">Arrow keys and <code class="kbd docutils literal"><span class="pre">Page</span> <span class="pre">Up</span></code>/<code class="kbd docutils literal"><span class="pre">Page</span> <span class="pre">Down</span></code> to move around</p>
 </li>
-<li><p class="first"><tt class="kbd docutils literal"><span class="pre">C-LeftArrow</span></tt> and <tt class="kbd docutils literal"><span class="pre">C-RightArrow</span></tt> moves by words</p>
+<li><p class="first"><code class="kbd docutils literal"><span class="pre">C-LeftArrow</span></code> and <code class="kbd docutils literal"><span class="pre">C-RightArrow</span></code> moves by words</p>
 </li>
-<li><p class="first"><tt class="kbd docutils literal"><span class="pre">Home</span></tt>/<tt class="kbd docutils literal"><span class="pre">End</span></tt> go to begin/end of line</p>
+<li><p class="first"><code class="kbd docutils literal"><span class="pre">Home</span></code>/<code class="kbd docutils literal"><span class="pre">End</span></code> go to begin/end of line</p>
 </li>
-<li><p class="first"><tt class="kbd docutils literal"><span class="pre">C-Home</span></tt>/<tt class="kbd docutils literal"><span class="pre">C-End</span></tt> go to begin/end of file</p>
+<li><p class="first"><code class="kbd docutils literal"><span class="pre">C-Home</span></code>/<code class="kbd docutils literal"><span class="pre">C-End</span></code> go to begin/end of file</p>
 </li>
 <li><p class="first">Some useful Emacs bindings are inherited from Tcl/Tk:</p>
 <blockquote>
 <div><ul class="simple">
-<li><tt class="kbd docutils literal"><span class="pre">C-a</span></tt> beginning of line</li>
-<li><tt class="kbd docutils literal"><span class="pre">C-e</span></tt> end of line</li>
-<li><tt class="kbd docutils literal"><span class="pre">C-k</span></tt> kill line (but doesn&#8217;t put it in clipboard)</li>
-<li><tt class="kbd docutils literal"><span class="pre">C-l</span></tt> center window around the insertion point</li>
-<li><tt class="kbd docutils literal"><span class="pre">C-b</span></tt> go backwards one character without deleting (usually you can
+<li><code class="kbd docutils literal"><span class="pre">C-a</span></code> beginning of line</li>
+<li><code class="kbd docutils literal"><span class="pre">C-e</span></code> end of line</li>
+<li><code class="kbd docutils literal"><span class="pre">C-k</span></code> kill line (but doesn&#8217;t put it in clipboard)</li>
+<li><code class="kbd docutils literal"><span class="pre">C-l</span></code> center window around the insertion point</li>
+<li><code class="kbd docutils literal"><span class="pre">C-b</span></code> go backwards one character without deleting (usually you can
 also use the cursor key for this)</li>
-<li><tt class="kbd docutils literal"><span class="pre">C-f</span></tt> go forward one character without deleting (usually you can
+<li><code class="kbd docutils literal"><span class="pre">C-f</span></code> go forward one character without deleting (usually you can
 also use the cursor key for this)</li>
-<li><tt class="kbd docutils literal"><span class="pre">C-p</span></tt> go up one line (usually you can also use the cursor key for
+<li><code class="kbd docutils literal"><span class="pre">C-p</span></code> go up one line (usually you can also use the cursor key for
 this)</li>
-<li><tt class="kbd docutils literal"><span class="pre">C-d</span></tt> delete next character</li>
+<li><code class="kbd docutils literal"><span class="pre">C-d</span></code> delete next character</li>
 </ul>
 </div></blockquote>
 </li>
 </ul>
-<p>Standard keybindings (like <tt class="kbd docutils literal"><span class="pre">C-c</span></tt> to copy and <tt class="kbd docutils literal"><span class="pre">C-v</span></tt> to paste)
+<p>Standard keybindings (like <code class="kbd docutils literal"><span class="pre">C-c</span></code> to copy and <code class="kbd docutils literal"><span class="pre">C-v</span></code> to paste)
 may work.  Keybindings are selected in the Configure IDLE dialog.</p>
 <div class="section" id="automatic-indentation">
 <h3>25.5.2.1. Automatic indentation<a class="headerlink" href="#automatic-indentation" title="Permalink to this headline">¶</a></h3>
 <p>After a block-opening statement, the next line is indented by 4 spaces (in the
 Python Shell window by one tab).  After certain keywords (break, return etc.)
-the next line is dedented.  In leading indentation, <tt class="kbd docutils literal"><span class="pre">Backspace</span></tt> deletes up
-to 4 spaces if they are there. <tt class="kbd docutils literal"><span class="pre">Tab</span></tt> inserts spaces (in the Python
+the next line is dedented.  In leading indentation, <code class="kbd docutils literal"><span class="pre">Backspace</span></code> deletes up
+to 4 spaces if they are there. <code class="kbd docutils literal"><span class="pre">Tab</span></code> inserts spaces (in the Python
 Shell window one tab), number depends on Indent width. Currently tabs
 are restricted to four spaces due to Tcl/Tk limitations.</p>
 <p>See also the indent/dedent region commands in the edit menu.</p>
@@ -394,25 +396,25 @@ two seconds) after a &#8216;.&#8217; or (in a string) an os.sep is typed. If aft
 of those characters (plus zero or more other characters) a tab is typed
 the ACW will open immediately if a possible continuation is found.</p>
 <p>If there is only one possible completion for the characters entered, a
-<tt class="kbd docutils literal"><span class="pre">Tab</span></tt> will supply that completion without opening the ACW.</p>
+<code class="kbd docutils literal"><span class="pre">Tab</span></code> will supply that completion without opening the ACW.</p>
 <p>&#8216;Show Completions&#8217; will force open a completions window, by default the
-<tt class="kbd docutils literal"><span class="pre">C-space</span></tt> will open a completions window. In an empty
+<code class="kbd docutils literal"><span class="pre">C-space</span></code> will open a completions window. In an empty
 string, this will contain the files in the current directory. On a
 blank line, it will contain the built-in and user-defined functions and
 classes in the current name spaces, plus any modules imported. If some
 characters have been entered, the ACW will attempt to be more specific.</p>
 <p>If a string of characters is typed, the ACW selection will jump to the
-entry most closely matching those characters.  Entering a <tt class="kbd docutils literal"><span class="pre">tab</span></tt> will
+entry most closely matching those characters.  Entering a <code class="kbd docutils literal"><span class="pre">tab</span></code> will
 cause the longest non-ambiguous match to be entered in the Editor window or
-Shell.  Two <tt class="kbd docutils literal"><span class="pre">tab</span></tt> in a row will supply the current ACW selection, as
+Shell.  Two <code class="kbd docutils literal"><span class="pre">tab</span></code> in a row will supply the current ACW selection, as
 will return or a double click.  Cursor keys, Page Up/Down, mouse selection,
 and the scroll wheel all operate on the ACW.</p>
 <p>&#8220;Hidden&#8221; attributes can be accessed by typing the beginning of hidden
 name after a &#8216;.&#8217;, e.g. &#8216;_&#8217;. This allows access to modules with
-<tt class="docutils literal"><span class="pre">__all__</span></tt> set, or to class-private attributes.</p>
+<code class="docutils literal"><span class="pre">__all__</span></code> set, or to class-private attributes.</p>
 <p>Completions and the &#8216;Expand Word&#8217; facility can save a lot of typing!</p>
 <p>Completions are currently limited to those in the namespaces. Names in
-an Editor window which are not via <tt class="docutils literal"><span class="pre">__main__</span></tt> and <a class="reference internal" href="sys.html#sys.modules" title="sys.modules"><tt class="xref py py-data docutils literal"><span class="pre">sys.modules</span></tt></a> will
+an Editor window which are not via <code class="docutils literal"><span class="pre">__main__</span></code> and <a class="reference internal" href="sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal"><span class="pre">sys.modules</span></code></a> will
 not be found.  Run the module once with your imports to correct this situation.
 Note that IDLE itself places quite a few modules in sys.modules, so
 much can be found by default, e.g. the re module.</p>
@@ -421,10 +423,10 @@ longer or disable the extension.</p>
 </div>
 <div class="section" id="calltips">
 <h3>25.5.2.3. Calltips<a class="headerlink" href="#calltips" title="Permalink to this headline">¶</a></h3>
-<p>A calltip is shown when one types <tt class="kbd docutils literal"><span class="pre">(</span></tt> after the name of an <em>acccessible</em>
+<p>A calltip is shown when one types <code class="kbd docutils literal"><span class="pre">(</span></code> after the name of an <em>acccessible</em>
 function.  A name expression may include dots and subscripts.  A calltip
 remains until it is clicked, the cursor is moved out of the argument area,
-or <tt class="kbd docutils literal"><span class="pre">)</span></tt> is typed.  When the cursor is in the argument part of a definition,
+or <code class="kbd docutils literal"><span class="pre">)</span></code> is typed.  When the cursor is in the argument part of a definition,
 the menu or shortcut display a calltip.</p>
 <p>A calltip consists of the function signature and the first line of the
 docstring.  For builtins without an accessible signature, the calltip
@@ -433,11 +435,11 @@ details may change.</p>
 <p>The set of <em>accessible</em> functions depends on what modules have been imported
 into the user process, including those imported by Idle itself,
 and what definitions have been run, all since the last restart.</p>
-<p>For example, restart the Shell and enter <tt class="docutils literal"><span class="pre">itertools.count(</span></tt>.  A calltip
+<p>For example, restart the Shell and enter <code class="docutils literal"><span class="pre">itertools.count(</span></code>.  A calltip
 appears because Idle imports itertools into the user process for its own use.
-(This could change.)  Enter <tt class="docutils literal"><span class="pre">turtle.write(</span></tt> and nothing appears.  Idle does
+(This could change.)  Enter <code class="docutils literal"><span class="pre">turtle.write(</span></code> and nothing appears.  Idle does
 not import turtle.  The menu or shortcut do nothing either.  Enter
-<tt class="docutils literal"><span class="pre">import</span> <span class="pre">turtle</span></tt> and then <tt class="docutils literal"><span class="pre">turtle.write(</span></tt> will work.</p>
+<code class="docutils literal"><span class="pre">import</span> <span class="pre">turtle</span></code> and then <code class="docutils literal"><span class="pre">turtle.write(</span></code> will work.</p>
 <p>In an editor, import statements have no effect until one runs the file.  One
 might want to run a file after writing the import statements at the top,
 or immediately run an existing file before editing.</p>
@@ -445,17 +447,17 @@ or immediately run an existing file before editing.</p>
 <div class="section" id="python-shell-window">
 <h3>25.5.2.4. Python Shell window<a class="headerlink" href="#python-shell-window" title="Permalink to this headline">¶</a></h3>
 <ul>
-<li><p class="first"><tt class="kbd docutils literal"><span class="pre">C-c</span></tt> interrupts executing command</p>
+<li><p class="first"><code class="kbd docutils literal"><span class="pre">C-c</span></code> interrupts executing command</p>
 </li>
-<li><p class="first"><tt class="kbd docutils literal"><span class="pre">C-d</span></tt> sends end-of-file; closes window if typed at a <tt class="docutils literal"><span class="pre">&gt;&gt;&gt;</span></tt> prompt</p>
+<li><p class="first"><code class="kbd docutils literal"><span class="pre">C-d</span></code> sends end-of-file; closes window if typed at a <code class="docutils literal"><span class="pre">&gt;&gt;&gt;</span></code> prompt</p>
 </li>
-<li><p class="first"><tt class="kbd docutils literal"><span class="pre">Alt-/</span></tt> (Expand word) is also useful to reduce typing</p>
+<li><p class="first"><code class="kbd docutils literal"><span class="pre">Alt-/</span></code> (Expand word) is also useful to reduce typing</p>
 <p>Command history</p>
 <ul class="simple">
-<li><tt class="kbd docutils literal"><span class="pre">Alt-p</span></tt> retrieves previous command matching what you have typed. On
-OS X use <tt class="kbd docutils literal"><span class="pre">C-p</span></tt>.</li>
-<li><tt class="kbd docutils literal"><span class="pre">Alt-n</span></tt> retrieves next. On OS X use <tt class="kbd docutils literal"><span class="pre">C-n</span></tt>.</li>
-<li><tt class="kbd docutils literal"><span class="pre">Return</span></tt> while on any previous command retrieves that command</li>
+<li><code class="kbd docutils literal"><span class="pre">Alt-p</span></code> retrieves previous command matching what you have typed. On
+OS X use <code class="kbd docutils literal"><span class="pre">C-p</span></code>.</li>
+<li><code class="kbd docutils literal"><span class="pre">Alt-n</span></code> retrieves next. On OS X use <code class="kbd docutils literal"><span class="pre">C-n</span></code>.</li>
+<li><code class="kbd docutils literal"><span class="pre">Return</span></code> while on any previous command retrieves that command</li>
 </ul>
 </li>
 </ul>
@@ -465,8 +467,8 @@ OS X use <tt class="kbd docutils literal"><span class="pre">C-p</span></tt>.</li
 <p>Idle defaults to black on white text, but colors text with special meanings.
 For the shell, these are shell output, shell error, user output, and
 user error.  For Python code, at the shell prompt or in an editor, these are
-keywords, builtin class and function names, names following <tt class="docutils literal"><span class="pre">class</span></tt> and
-<tt class="docutils literal"><span class="pre">def</span></tt>, strings, and comments. For any text window, these are the cursor (when
+keywords, builtin class and function names, names following <code class="docutils literal"><span class="pre">class</span></code> and
+<code class="docutils literal"><span class="pre">def</span></code>, strings, and comments. For any text window, these are the cursor (when
 present), found text (when possible), and selected text.</p>
 <p>Text coloring is done in the background, so uncolorized text is occasionally
 visible.  To change the color scheme, use the Configure IDLE dialog
@@ -476,15 +478,15 @@ text in popups and dialogs is not user-configurable.</p>
 </div>
 <div class="section" id="startup-and-code-execution">
 <h2>25.5.3. Startup and code execution<a class="headerlink" href="#startup-and-code-execution" title="Permalink to this headline">¶</a></h2>
-<p>Upon startup with the <tt class="docutils literal"><span class="pre">-s</span></tt> option, IDLE will execute the file referenced by
-the environment variables <span class="target" id="index-5"></span><tt class="xref std std-envvar docutils literal"><span class="pre">IDLESTARTUP</span></tt> or <span class="target" id="index-6"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONSTARTUP"><tt class="xref std std-envvar docutils literal"><span class="pre">PYTHONSTARTUP</span></tt></a>.
-IDLE first checks for <tt class="docutils literal"><span class="pre">IDLESTARTUP</span></tt>; if <tt class="docutils literal"><span class="pre">IDLESTARTUP</span></tt> is present the file
-referenced is run.  If <tt class="docutils literal"><span class="pre">IDLESTARTUP</span></tt> is not present, IDLE checks for
-<tt class="docutils literal"><span class="pre">PYTHONSTARTUP</span></tt>.  Files referenced by these environment variables are
+<p>Upon startup with the <code class="docutils literal"><span class="pre">-s</span></code> option, IDLE will execute the file referenced by
+the environment variables <span class="target" id="index-5"></span><code class="xref std std-envvar docutils literal"><span class="pre">IDLESTARTUP</span></code> or <span class="target" id="index-6"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONSTARTUP"><code class="xref std std-envvar docutils literal"><span class="pre">PYTHONSTARTUP</span></code></a>.
+IDLE first checks for <code class="docutils literal"><span class="pre">IDLESTARTUP</span></code>; if <code class="docutils literal"><span class="pre">IDLESTARTUP</span></code> is present the file
+referenced is run.  If <code class="docutils literal"><span class="pre">IDLESTARTUP</span></code> is not present, IDLE checks for
+<code class="docutils literal"><span class="pre">PYTHONSTARTUP</span></code>.  Files referenced by these environment variables are
 convenient places to store functions that are used frequently from the IDLE
 shell, or for executing import statements to import common modules.</p>
-<p>In addition, <tt class="docutils literal"><span class="pre">Tk</span></tt> also loads a startup file if it is present.  Note that the
-Tk file is loaded unconditionally.  This additional file is <tt class="docutils literal"><span class="pre">.Idle.py</span></tt> and is
+<p>In addition, <code class="docutils literal"><span class="pre">Tk</span></code> also loads a startup file if it is present.  Note that the
+Tk file is loaded unconditionally.  This additional file is <code class="docutils literal"><span class="pre">.Idle.py</span></code> and is
 looked for in the user&#8217;s home directory.  Statements in this file will be
 executed in the Tk namespace, so this file is not useful for importing
 functions to be used from IDLE&#8217;s Python shell.</p>
@@ -505,25 +507,27 @@ functions to be used from IDLE&#8217;s Python shell.</p>
 </div>
 <p>If there are arguments:</p>
 <ul class="simple">
-<li>If <tt class="docutils literal"><span class="pre">-</span></tt>, <tt class="docutils literal"><span class="pre">-c</span></tt>, or <tt class="docutils literal"><span class="pre">r</span></tt> is used, all arguments are placed in
-<tt class="docutils literal"><span class="pre">sys.argv[1:...]</span></tt> and <tt class="docutils literal"><span class="pre">sys.argv[0]</span></tt> is set to <tt class="docutils literal"><span class="pre">''</span></tt>, <tt class="docutils literal"><span class="pre">'-c'</span></tt>,
-or <tt class="docutils literal"><span class="pre">'-r'</span></tt>.  No editor window is opened, even if that is the default
+<li>If <code class="docutils literal"><span class="pre">-</span></code>, <code class="docutils literal"><span class="pre">-c</span></code>, or <code class="docutils literal"><span class="pre">r</span></code> is used, all arguments are placed in
+<code class="docutils literal"><span class="pre">sys.argv[1:...]</span></code> and <code class="docutils literal"><span class="pre">sys.argv[0]</span></code> is set to <code class="docutils literal"><span class="pre">''</span></code>, <code class="docutils literal"><span class="pre">'-c'</span></code>,
+or <code class="docutils literal"><span class="pre">'-r'</span></code>.  No editor window is opened, even if that is the default
 set in the Options dialog.</li>
 <li>Otherwise, arguments are files opened for editing and
-<tt class="docutils literal"><span class="pre">sys.argv</span></tt> reflects the arguments passed to IDLE itself.</li>
+<code class="docutils literal"><span class="pre">sys.argv</span></code> reflects the arguments passed to IDLE itself.</li>
 </ul>
 </div>
 <div class="section" id="idle-console-differences">
 <h3>25.5.3.2. IDLE-console differences<a class="headerlink" href="#idle-console-differences" title="Permalink to this headline">¶</a></h3>
 <p>As much as possible, the result of executing Python code with IDLE is the
 same as executing the same code in a console window.  However, the different
-interface and operation occasionally affects results.</p>
-<p>For instance, IDLE normally executes user code in a separate process from
-the IDLE GUI itself.  The IDLE versions of sys.stdin, .stdout, and .stderr in the
-execution process get input from and send output to the GUI process,
-which keeps control of the keyboard and screen.  This is normally transparent,
-but code that access these object will see different attribute values.
-Also, functions that directly access the keyboard and screen will not work.</p>
+interface and operation occasionally affects visible results.  For instance,
+<code class="docutils literal"><span class="pre">sys.modules</span></code> starts with more entries.</p>
+<p>IDLE also replaces <code class="docutils literal"><span class="pre">sys.stdin</span></code>, <code class="docutils literal"><span class="pre">sys.stdout</span></code>, and <code class="docutils literal"><span class="pre">sys.stderr</span></code> with
+objects that get input from and send output to the Shell window.
+When this window has the focus, it controls the keyboard and screen.
+This is normally transparent, but functions that directly access the keyboard
+and screen will not work.  If <code class="docutils literal"><span class="pre">sys</span></code> is reset with <code class="docutils literal"><span class="pre">importlib.reload(sys)</span></code>,
+IDLE&#8217;s changes are lost and things li ke <code class="docutils literal"><span class="pre">input</span></code>, <code class="docutils literal"><span class="pre">raw_input</span></code>, and
+<code class="docutils literal"><span class="pre">print</span></code> will not work correctly.</p>
 <p>With IDLE&#8217;s Shell, one enters, edits, and recalls complete statements.
 Some consoles only work with a single physical line at a time.</p>
 </div>
@@ -595,7 +599,7 @@ are currently:</p>
           </div>
         </div>
       </div>
-      <div class="sphinxsidebar">
+      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
         <div class="sphinxsidebarwrapper">
   <h3><a href="../contents.html">Table Of Contents</a></h3>
   <ul>
@@ -639,7 +643,7 @@ are currently:</p>
 
   <h4>Previous topic</h4>
   <p class="topless"><a href="tkinter.scrolledtext.html"
-                        title="previous chapter">25.4. <tt class="docutils literal"><span class="pre">tkinter.scrolledtext</span></tt> &#8212; Scrolled Text Widget</a></p>
+                        title="previous chapter">25.4. <code class="docutils literal"><span class="pre">tkinter.scrolledtext</span></code> &#8212; Scrolled Text Widget</a></p>
   <h4>Next topic</h4>
   <p class="topless"><a href="othergui.html"
                         title="next chapter">25.6. Other Graphical User Interface Packages</a></p>
@@ -650,7 +654,7 @@ are currently:</p>
          rel="nofollow">Show Source</a></li>
 </ul>
 
-<div id="searchbox" style="display: none">
+<div id="searchbox" style="display: none" role="search">
   <h3>Quick search</h3>
     <form class="search" action="../search.html" method="get">
       <input type="text" name="q" />
@@ -667,7 +671,7 @@ are currently:</p>
       </div>
       <div class="clearer"></div>
     </div>
-    <div class="related">
+    <div class="related" role="navigation" aria-label="related navigation">
       <h3>Navigation</h3>
       <ul>
         <li class="right" style="margin-right: 10px">
@@ -686,23 +690,23 @@ are currently:</p>
                  style="vertical-align: middle; margin-top: -1px"/></li>
         <li><a href="https://www.python.org/">Python</a> &raquo;</li>
         <li>
-          <a href="../index.html">3.4.3 Documentation</a> &raquo;
+          <a href="../index.html">3.5.1 Documentation</a> &raquo;
         </li>
 
-          <li><a href="index.html" >The Python Standard Library</a> &raquo;</li>
-          <li><a href="tk.html" >25. Graphical User Interfaces with Tk</a> &raquo;</li>
+          <li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> &raquo;</li>
+          <li class="nav-item nav-item-2"><a href="tk.html" >25. Graphical User Interfaces with Tk</a> &raquo;</li>
       </ul>
     </div>
     <div class="footer">
-    &copy; <a href="../copyright.html">Copyright</a> 1990-2015, Python Software Foundation.
+    &copy; <a href="../copyright.html">Copyright</a> 2001-2016, Python Software Foundation.
     <br />
     The Python Software Foundation is a non-profit corporation.
     <a href="https://www.python.org/psf/donations/">Please donate.</a>
     <br />
-    Last updated on Oct 13, 2015.
+    Last updated on Jun 11, 2016.
     <a href="../bugs.html">Found a bug</a>?
     <br />
-    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.2.3.
+    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.3.3.
     </div>
 
   </body>
index b31596c..d0c59c5 100644 (file)
@@ -11,7 +11,7 @@ Help => IDLE Help: Display help.html with proper formatting.
 Doc/library/idle.rst (Sphinx)=> Doc/build/html/library/idle.html
 (help.copy_strip)=> Lib/idlelib/help.html
 
-HelpParser - Parse help.html and and render to tk Text.
+HelpParser - Parse help.html and render to tk Text.
 
 HelpText - Display formatted help.html.
 
@@ -45,6 +45,8 @@ class HelpParser(HTMLParser):
     The overridden handle_xyz methods handle a subset of html tags.
     The supplied text should have the needed tag configurations.
     The behavior for unsupported tags, such as table, is undefined.
+    If the tags generated by Sphinx change, this class, especially
+    the handle_starttag and handle_endtags methods, might have to also.
     """
     def __init__(self, text):
         HTMLParser.__init__(self, convert_charrefs=True)
@@ -226,7 +228,28 @@ class HelpWindow(Toplevel):
 
 
 def copy_strip():
-    "Copy idle.html to idlelib/help.html, stripping trailing whitespace."
+    """Copy idle.html to idlelib/help.html, stripping trailing whitespace.
+
+    Files with trailing whitespace cannot be pushed to the hg cpython
+    repository.  For 3.x (on Windows), help.html is generated, after
+    editing idle.rst in the earliest maintenance version, with
+      sphinx-build -bhtml . build/html
+      python_d.exe -c "from idlelib.help import copy_strip; copy_strip()"
+    After refreshing TortoiseHG workshop to generate a diff,
+    check  both the diff and displayed text.  Push the diff along with
+    the idle.rst change and merge both into default (or an intermediate
+    maintenance version).
+
+    When the 'earlist' version gets its final maintenance release,
+    do an update as described above, without editing idle.rst, to
+    rebase help.html on the next version of idle.rst.  Do not worry
+    about version changes as version is not displayed.  Examine other
+    changes and the result of Help -> IDLE Help.
+
+    If maintenance and default versions of idle.rst diverge, and
+    merging does not go smoothly, then consider generating
+    separate help.html files from separate idle.htmls.
+    """
     src = join(abspath(dirname(dirname(dirname(__file__)))),
                'Doc', 'build', 'html', 'library', 'idle.html')
     dst = join(abspath(dirname(__file__)), 'help.html')
index 2339926..dc7a286 100644 (file)
@@ -2,12 +2,12 @@ README FOR IDLE TESTS IN IDLELIB.IDLE_TEST
 
 0. Quick Start
 
-Automated unit tests were added in 2.7 for Python 2.x and 3.3 for Python 3.x.
+Automated unit tests were added in 3.3 for Python 3.x.
 To run the tests from a command line:
 
 python -m test.test_idle
 
-Human-mediated tests were added later in 2.7 and in 3.4.
+Human-mediated tests were added later in 3.4.
 
 python -m idlelib.idle_test.htest
 
@@ -15,9 +15,9 @@ python -m idlelib.idle_test.htest
 1. Test Files
 
 The idle directory, idlelib, has over 60 xyz.py files. The idle_test
-subdirectory should contain a test_xyz.py for each, where 'xyz' is lowercased
-even if xyz.py is not. Here is a possible template, with the blanks after after
-'.' and 'as', and before and after '_' to be filled in.
+subdirectory should contain a test_xyz.py for each, where 'xyz' is
+lowercased even if xyz.py is not. Here is a possible template, with the
+blanks after '.' and 'as', and before and after '_' to be filled in.
 
 import unittest
 from test.support import requires
@@ -30,9 +30,9 @@ class _Test(unittest.TestCase):
 if __name__ == '__main__':
     unittest.main(verbosity=2)
 
-Add the following at the end of xyy.py, with the appropriate name added after
-'test_'. Some files already have something like this for htest.  If so, insert
-the import and unittest.main lines before the htest lines.
+Add the following at the end of xyy.py, with the appropriate name added
+after 'test_'. Some files already have something like this for htest.
+If so, insert the import and unittest.main lines before the htest lines.
 
 if __name__ == "__main__":
     import unittest
@@ -42,64 +42,82 @@ if __name__ == "__main__":
 
 2. GUI Tests
 
-When run as part of the Python test suite, Idle gui tests need to run
-test.support.requires('gui') (test.test_support in 2.7).  A test is a gui test
-if it creates a Tk root or master object either directly or indirectly by
-instantiating a tkinter or idle class.  For the benefit of test processes that
-either have no graphical environment available or are not allowed to use it, gui
-tests must be 'guarded' by "requires('gui')" in a setUp function or method.
-This will typically be setUpClass.
+When run as part of the Python test suite, Idle GUI tests need to run
+test.support.requires('gui').  A test is a GUI test if it creates a
+tkinter.Tk root or master object either directly or indirectly by
+instantiating a tkinter or idle class.  GUI tests cannot run in test
+processes that either have no graphical environment available or are not
+allowed to use it.
 
-To avoid interfering with other gui tests, all gui objects must be destroyed and
-deleted by the end of the test.  Widgets, such as a Tk root, created in a setUpX
-function, should be destroyed in the corresponding tearDownX.  Module and class
-widget attributes should also be deleted..
+To guard a module consisting entirely of GUI tests, start with
+
+from test.support import requires
+requires('gui')
+
+To guard a test class, put "requires('gui')" in its setUpClass function.
+
+To avoid interfering with other GUI tests, all GUI objects must be destroyed and
+deleted by the end of the test.  The Tk root created in a setUpX function should
+be destroyed in the corresponding tearDownX and the module or class attribute
+deleted.  Others widgets should descend from the single root and the attributes
+deleted BEFORE root is destroyed.  See https://bugs.python.org/issue20567.
 
     @classmethod
     def setUpClass(cls):
         requires('gui')
         cls.root = tk.Tk()
+        cls.text = tk.Text(root)
 
     @classmethod
     def tearDownClass(cls):
+        del cls.text
+        cls.root.update_idletasks()
         cls.root.destroy()
         del cls.root
 
+The update_idletasks call is sometimes needed to prevent the following warning
+either when running a test alone or as part of the test suite (#27196).
+  can't invoke "event" command: application has been destroyed
+  ...
+  "ttk::ThemeChanged"
 
 Requires('gui') causes the test(s) it guards to be skipped if any of
-a few conditions are met:
-    
- - The tests are being run by regrtest.py, and it was started without enabling
-   the "gui" resource with the "-u" command line option.
-   
- - The tests are being run on Windows by a service that is not allowed to
-   interact with the graphical environment.
-   
- - The tests are being run on Mac OSX in a process that cannot make a window
-   manager connection.
-   
+these conditions are met:
+
+ - The tests are being run by regrtest.py, and it was started without
+   enabling the "gui" resource with the "-u" command line option.
+
+ - The tests are being run on Windows by a service that is not allowed
+   to interact with the graphical environment.
+
+ - The tests are being run on Linux and X Windows is not available.
+
+ - The tests are being run on Mac OSX in a process that cannot make a
+   window manager connection.
+
  - tkinter.Tk cannot be successfully instantiated for some reason.
+
  - test.support.use_resources has been set by something other than
    regrtest.py and does not contain "gui".
-   
-Tests of non-gui operations should avoid creating tk widgets. Incidental uses of
-tk variables and messageboxes can be replaced by the mock classes in
-idle_test/mock_tk.py. The mock text handles some uses of the tk Text widget.
+
+Tests of non-GUI operations should avoid creating tk widgets. Incidental
+uses of tk variables and messageboxes can be replaced by the mock
+classes in idle_test/mock_tk.py. The mock text handles some uses of the
+tk Text widget.
 
 
 3. Running Unit Tests
 
 Assume that xyz.py and test_xyz.py both end with a unittest.main() call.
-Running either from an Idle editor runs all tests in the test_xyz file with the
-version of Python running Idle.  Test output appears in the Shell window.  The
-'verbosity=2' option lists all test methods in the file, which is appropriate
-when developing tests. The 'exit=False' option is needed in xyx.py files when an
-htest follows.
+Running either from an Idle editor runs all tests in the test_xyz file
+with the version of Python running Idle.  Test output appears in the
+Shell window.  The 'verbosity=2' option lists all test methods in the
+file, which is appropriate when developing tests. The 'exit=False'
+option is needed in xyx.py files when an htest follows.
 
 The following command lines also run all test methods, including
-gui tests, in test_xyz.py. (Both '-m idlelib' and '-m idlelib.idle' start
-Idle and so cannot run tests.)
+GUI tests, in test_xyz.py. (Both '-m idlelib' and '-m idlelib.idle'
+start Idle and so cannot run tests.)
 
 python -m idlelib.xyz
 python -m idlelib.idle_test.test_xyz
@@ -109,35 +127,35 @@ The following runs all idle_test/test_*.py tests interactively.
 >>> import unittest
 >>> unittest.main('idlelib.idle_test', verbosity=2)
 
-The following run all Idle tests at a command line.  Option '-v' is the same as
-'verbosity=2'.  (For 2.7, replace 'test' in the second line with
-'test.regrtest'.)
+The following run all Idle tests at a command line.  Option '-v' is the
+same as 'verbosity=2'.
 
 python -m unittest -v idlelib.idle_test
 python -m test -v -ugui test_idle
 python -m test.test_idle
 
-The idle tests are 'discovered' by idlelib.idle_test.__init__.load_tests,
-which is also imported into test.test_idle. Normally, neither file should be
-changed when working on individual test modules. The third command runs
-unittest indirectly through regrtest. The same happens when the entire test
-suite is run with 'python -m test'. So that command must work for buildbots
-to stay green. Idle tests must not disturb the environment in a way that
-makes other tests fail (issue 18081).
+The idle tests are 'discovered' by
+idlelib.idle_test.__init__.load_tests, which is also imported into
+test.test_idle. Normally, neither file should be changed when working on
+individual test modules. The third command runs unittest indirectly
+through regrtest. The same happens when the entire test suite is run
+with 'python -m test'. So that command must work for buildbots to stay
+green. Idle tests must not disturb the environment in a way that makes
+other tests fail (issue 18081).
 
-To run an individual Testcase or test method, extend the dotted name given to
-unittest on the command line.
+To run an individual Testcase or test method, extend the dotted name
+given to unittest on the command line.
 
 python -m unittest -v idlelib.idle_test.test_xyz.Test_case.test_meth
 
 
 4. Human-mediated Tests
 
-Human-mediated tests are widget tests that cannot be automated but need human
-verification. They are contained in idlelib/idle_test/htest.py, which has
-instructions.  (Some modules need an auxiliary function, identified with # htest
-# on the header line.)  The set is about complete, though some tests need
-improvement. To run all htests, run the htest file from an editor or from the
-command line with:
+Human-mediated tests are widget tests that cannot be automated but need
+human verification. They are contained in idlelib/idle_test/htest.py,
+which has instructions.  (Some modules need an auxiliary function,
+identified with "# htest # on the header line.)  The set is about
+complete, though some tests need improvement. To run all htests, run the
+htest file from an editor or from the command line with:
 
 python -m idlelib.idle_test.htest
index 1bc9536..845c92d 100644 (file)
@@ -1,3 +1,9 @@
+'''idlelib.idle_test is a private implementation of test.test_idle,
+which tests the IDLE application as part of the stdlib test suite.
+Run IDLE tests alone with "python -m test.test_idle".
+This package and its contained modules are subject to change and
+any direct use is at your own risk.
+'''
 from os.path import dirname
 
 def load_tests(loader, standard_tests, pattern):
index 3e24518..58e62cb 100644 (file)
@@ -192,7 +192,10 @@ _io_binding_spec = {
     'msg': "Test the following bindings.\n"
            "<Control-o> to open file from dialog.\n"
            "Edit the file.\n"
+           "<Control-p> to print the file.\n"
            "<Control-s> to save the file.\n"
+           "<Alt-s> to save-as another file.\n"
+           "<Control-c> to save-copy-as another file.\n"
            "Check that changes were saved by opening the file elsewhere."
     }
 
index 86fe848..6e35129 100644 (file)
@@ -296,3 +296,8 @@ class Text:
     def bind(sequence=None, func=None, add=None):
         "Bind to this widget at event sequence a call to function func."
         pass
+
+class Entry:
+    "Mock for tkinter.Entry."
+    def focus_set(self):
+        pass
index 3a2192e..e4493d1 100644 (file)
@@ -33,9 +33,8 @@ class AutoCompleteTest(unittest.TestCase):
 
     @classmethod
     def tearDownClass(cls):
+        del cls.editor, cls.text
         cls.root.destroy()
-        del cls.text
-        del cls.editor
         del cls.root
 
     def setUp(self):
index 7ca941e..d2a3156 100644 (file)
@@ -25,10 +25,10 @@ class AutoExpandTest(unittest.TestCase):
 
     @classmethod
     def tearDownClass(cls):
+        del cls.text, cls.auto_expand
         if hasattr(cls, 'tk'):
             cls.tk.destroy()
             del cls.tk
-        del cls.text, cls.auto_expand
 
     def tearDown(self):
         self.text.delete('1.0', 'end')
diff --git a/Lib/idlelib/idle_test/test_config_help.py b/Lib/idlelib/idle_test/test_config_help.py
new file mode 100644 (file)
index 0000000..664f8ed
--- /dev/null
@@ -0,0 +1,106 @@
+"""Unittests for idlelib.configHelpSourceEdit"""
+import unittest
+from idlelib.idle_test.mock_tk import Var, Mbox, Entry
+from idlelib import configHelpSourceEdit as help_dialog_module
+
+help_dialog = help_dialog_module.GetHelpSourceDialog
+
+
+class Dummy_help_dialog:
+    # Mock for testing the following methods of help_dialog
+    menu_ok = help_dialog.menu_ok
+    path_ok = help_dialog.path_ok
+    ok = help_dialog.ok
+    cancel = help_dialog.cancel
+    # Attributes, constant or variable, needed for tests
+    menu = Var()
+    entryMenu = Entry()
+    path = Var()
+    entryPath = Entry()
+    result = None
+    destroyed = False
+
+    def destroy(self):
+        self.destroyed = True
+
+
+# menu_ok and path_ok call Mbox.showerror if menu and path are not ok.
+orig_mbox = help_dialog_module.tkMessageBox
+showerror = Mbox.showerror
+
+
+class ConfigHelpTest(unittest.TestCase):
+    dialog = Dummy_help_dialog()
+
+    @classmethod
+    def setUpClass(cls):
+        help_dialog_module.tkMessageBox = Mbox
+
+    @classmethod
+    def tearDownClass(cls):
+        help_dialog_module.tkMessageBox = orig_mbox
+
+    def test_blank_menu(self):
+        self.dialog.menu.set('')
+        self.assertFalse(self.dialog.menu_ok())
+        self.assertEqual(showerror.title, 'Menu Item Error')
+        self.assertIn('No', showerror.message)
+
+    def test_long_menu(self):
+        self.dialog.menu.set('hello' * 10)
+        self.assertFalse(self.dialog.menu_ok())
+        self.assertEqual(showerror.title, 'Menu Item Error')
+        self.assertIn('long', showerror.message)
+
+    def test_good_menu(self):
+        self.dialog.menu.set('help')
+        showerror.title = 'No Error'  # should not be called
+        self.assertTrue(self.dialog.menu_ok())
+        self.assertEqual(showerror.title, 'No Error')
+
+    def test_blank_path(self):
+        self.dialog.path.set('')
+        self.assertFalse(self.dialog.path_ok())
+        self.assertEqual(showerror.title, 'File Path Error')
+        self.assertIn('No', showerror.message)
+
+    def test_invalid_file_path(self):
+        self.dialog.path.set('foobar' * 100)
+        self.assertFalse(self.dialog.path_ok())
+        self.assertEqual(showerror.title, 'File Path Error')
+        self.assertIn('not exist', showerror.message)
+
+    def test_invalid_url_path(self):
+        self.dialog.path.set('ww.foobar.com')
+        self.assertFalse(self.dialog.path_ok())
+        self.assertEqual(showerror.title, 'File Path Error')
+        self.assertIn('not exist', showerror.message)
+
+        self.dialog.path.set('htt.foobar.com')
+        self.assertFalse(self.dialog.path_ok())
+        self.assertEqual(showerror.title, 'File Path Error')
+        self.assertIn('not exist', showerror.message)
+
+    def test_good_path(self):
+        self.dialog.path.set('https://docs.python.org')
+        showerror.title = 'No Error'  # should not be called
+        self.assertTrue(self.dialog.path_ok())
+        self.assertEqual(showerror.title, 'No Error')
+
+    def test_ok(self):
+        self.dialog.destroyed = False
+        self.dialog.menu.set('help')
+        self.dialog.path.set('https://docs.python.org')
+        self.dialog.ok()
+        self.assertEqual(self.dialog.result, ('help',
+                                              'https://docs.python.org'))
+        self.assertTrue(self.dialog.destroyed)
+
+    def test_cancel(self):
+        self.dialog.destroyed = False
+        self.dialog.cancel()
+        self.assertEqual(self.dialog.result, None)
+        self.assertTrue(self.dialog.destroyed)
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2, exit=False)
index 6883123..b063601 100644 (file)
@@ -1,31 +1,31 @@
-'''Unittests for idlelib/configHandler.py
-
-Coverage: 46% just by creating dialog. The other half is change code.
+'''Test idlelib.configDialog.
 
+Coverage: 46% just by creating dialog.
+The other half is code for working with user customizations.
 '''
-import unittest
+from idlelib.configDialog import ConfigDialog  # always test import
 from test.support import requires
+requires('gui')
 from tkinter import Tk
-from idlelib.configDialog import ConfigDialog
-from idlelib.macosxSupport import _initializeTkVariantTests
-
+import unittest
+from idlelib import macosxSupport as macosx
 
 class ConfigDialogTest(unittest.TestCase):
 
     @classmethod
     def setUpClass(cls):
-        requires('gui')
         cls.root = Tk()
-        _initializeTkVariantTests(cls.root)
+        macosx._initializeTkVariantTests(cls.root)
 
     @classmethod
     def tearDownClass(cls):
+        cls.root.update_idletasks()
         cls.root.destroy()
         del cls.root
 
     def test_dialog(self):
-        d=ConfigDialog(self.root, 'Test', _utest=True)
-        d.destroy()
+        d = ConfigDialog(self.root, 'Test', _utest=True)
+        d.remove_var_callbacks()
 
 
 if __name__ == '__main__':
index b8ae5ee..1f0baa9 100644 (file)
@@ -4,34 +4,37 @@ from idlelib.Delegator import Delegator
 class DelegatorTest(unittest.TestCase):
 
     def test_mydel(self):
-        # test a simple use scenario
+        # Test a simple use scenario.
 
-        # initialize
+        # Initialize an int delegator.
         mydel = Delegator(int)
         self.assertIs(mydel.delegate, int)
         self.assertEqual(mydel._Delegator__cache, set())
-
-        # add an attribute:
+        # Trying to access a non-attribute of int fails.
         self.assertRaises(AttributeError, mydel.__getattr__, 'xyz')
+
+        # Add real int attribute 'bit_length' by accessing it.
         bl = mydel.bit_length
         self.assertIs(bl, int.bit_length)
         self.assertIs(mydel.__dict__['bit_length'], int.bit_length)
         self.assertEqual(mydel._Delegator__cache, {'bit_length'})
 
-        # add a second attribute
+        # Add attribute 'numerator'.
         mydel.numerator
         self.assertEqual(mydel._Delegator__cache, {'bit_length', 'numerator'})
 
-        # delete the second (which, however, leaves it in the name cache)
+        # Delete 'numerator'.
         del mydel.numerator
         self.assertNotIn('numerator', mydel.__dict__)
-        self.assertIn('numerator', mydel._Delegator__cache)
+        # The current implementation leaves  it in the name cache.
+        # self.assertIn('numerator', mydel._Delegator__cache)
+        # However, this is not required and not part of the specification
 
-        # reset by calling .setdelegate, which calls .resetcache
-        mydel.setdelegate(float)
-        self.assertIs(mydel.delegate, float)
+        # Change delegate to float, first resetting the attributes.
+        mydel.setdelegate(float)  # calls resetcache
         self.assertNotIn('bit_length', mydel.__dict__)
         self.assertEqual(mydel._Delegator__cache, set())
+        self.assertIs(mydel.delegate, float)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2, exit=2)
diff --git a/Lib/idlelib/idle_test/test_editmenu.py b/Lib/idlelib/idle_test/test_editmenu.py
new file mode 100644 (file)
index 0000000..50317a9
--- /dev/null
@@ -0,0 +1,71 @@
+'''Test (selected) IDLE Edit menu items.
+
+Edit modules have their own test files files
+'''
+from test.support import requires
+requires('gui')
+import tkinter as tk
+import unittest
+from idlelib import PyShell
+
+class PasteTest(unittest.TestCase):
+    '''Test pasting into widgets that allow pasting.
+
+    On X11, replacing selections requires tk fix.
+    '''
+    @classmethod
+    def setUpClass(cls):
+        cls.root = root = tk.Tk()
+        PyShell.fix_x11_paste(root)
+        cls.text = tk.Text(root)
+        cls.entry = tk.Entry(root)
+        cls.spin = tk.Spinbox(root)
+        root.clipboard_clear()
+        root.clipboard_append('two')
+
+    @classmethod
+    def tearDownClass(cls):
+        del cls.text, cls.entry, cls.spin
+        cls.root.clipboard_clear()
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root
+
+    def test_paste_text(self):
+        "Test pasting into text with and without a selection."
+        text = self.text
+        for tag, ans in ('', 'onetwo\n'), ('sel', 'two\n'):
+            with self.subTest(tag=tag, ans=ans):
+                text.delete('1.0', 'end')
+                text.insert('1.0', 'one', tag)
+                text.event_generate('<<Paste>>')
+                self.assertEqual(text.get('1.0', 'end'), ans)
+
+    def test_paste_entry(self):
+        "Test pasting into an entry with and without a selection."
+        # On 3.6, generated <<Paste>> fails without empty select range
+        # for 'no selection'.  Live widget works fine.
+        entry = self.entry
+        for end, ans in (0, 'onetwo'), ('end', 'two'):
+            with self.subTest(entry=entry, end=end, ans=ans):
+                entry.delete(0, 'end')
+                entry.insert(0, 'one')
+                entry.select_range(0, end)  # see note
+                entry.event_generate('<<Paste>>')
+                self.assertEqual(entry.get(), ans)
+
+    def test_paste_spin(self):
+        "Test pasting into a spinbox with and without a selection."
+        # See note above for entry.
+        spin = self.spin
+        for end, ans in (0, 'onetwo'), ('end', 'two'):
+            with self.subTest(end=end, ans=ans):
+                spin.delete(0, 'end')
+                spin.insert(0, 'one')
+                spin.selection('range', 0, end)  # see note
+                spin.event_generate('<<Paste>>')
+                self.assertEqual(spin.get(), ans)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
index f6039e6..e5561d8 100644 (file)
@@ -276,10 +276,9 @@ class FormatEventTest(unittest.TestCase):
 
     @classmethod
     def tearDownClass(cls):
+        del cls.text, cls.formatter
         cls.root.destroy()
         del cls.root
-        del cls.text
-        del cls.formatter
 
     def test_short_line(self):
         self.text.insert('1.0', "Short line\n")
index 9aba4be..95cc22c 100644 (file)
@@ -1,10 +1,13 @@
-"""Test idlelib.ParenMatch."""
-# This must currently be a gui test because ParenMatch methods use
-# several text methods not defined on idlelib.idle_test.mock_tk.Text.
+'''Test idlelib.ParenMatch.
+
+This must currently be a gui test because ParenMatch methods use
+several text methods not defined on idlelib.idle_test.mock_tk.Text.
+'''
+from test.support import requires
+requires('gui')
 
 import unittest
 from unittest.mock import Mock
-from test.support import requires
 from tkinter import Tk, Text
 from idlelib.ParenMatch import ParenMatch
 
@@ -20,7 +23,6 @@ class ParenMatchTest(unittest.TestCase):
 
     @classmethod
     def setUpClass(cls):
-        requires('gui')
         cls.root = Tk()
         cls.text = Text(cls.root)
         cls.editwin = DummyEditwin(cls.text)
@@ -29,6 +31,7 @@ class ParenMatchTest(unittest.TestCase):
     @classmethod
     def tearDownClass(cls):
         del cls.text, cls.editwin
+        cls.root.update_idletasks()
         cls.root.destroy()
         del cls.root
 
diff --git a/Lib/idlelib/idle_test/test_percolator.py b/Lib/idlelib/idle_test/test_percolator.py
new file mode 100644 (file)
index 0000000..4c0a7ad
--- /dev/null
@@ -0,0 +1,118 @@
+'''Test Percolator'''
+from test.support import requires
+requires('gui')
+
+import unittest
+from tkinter import Text, Tk, END
+from idlelib.Percolator import Percolator, Delegator
+
+
+class MyFilter(Delegator):
+    def __init__(self):
+        Delegator.__init__(self, None)
+
+    def insert(self, *args):
+        self.insert_called_with = args
+        self.delegate.insert(*args)
+
+    def delete(self, *args):
+        self.delete_called_with = args
+        self.delegate.delete(*args)
+
+    def uppercase_insert(self, index, chars, tags=None):
+        chars = chars.upper()
+        self.delegate.insert(index, chars)
+
+    def lowercase_insert(self, index, chars, tags=None):
+        chars = chars.lower()
+        self.delegate.insert(index, chars)
+
+    def dont_insert(self, index, chars, tags=None):
+        pass
+
+
+class PercolatorTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = Tk()
+        cls.text = Text(cls.root)
+
+    @classmethod
+    def tearDownClass(cls):
+        del cls.text
+        cls.root.destroy()
+        del cls.root
+
+    def setUp(self):
+        self.percolator = Percolator(self.text)
+        self.filter_one = MyFilter()
+        self.filter_two = MyFilter()
+        self.percolator.insertfilter(self.filter_one)
+        self.percolator.insertfilter(self.filter_two)
+
+    def tearDown(self):
+        self.percolator.close()
+        self.text.delete('1.0', END)
+
+    def test_insertfilter(self):
+        self.assertIsNotNone(self.filter_one.delegate)
+        self.assertEqual(self.percolator.top, self.filter_two)
+        self.assertEqual(self.filter_two.delegate, self.filter_one)
+        self.assertEqual(self.filter_one.delegate, self.percolator.bottom)
+
+    def test_removefilter(self):
+        filter_three = MyFilter()
+        self.percolator.removefilter(self.filter_two)
+        self.assertEqual(self.percolator.top, self.filter_one)
+        self.assertIsNone(self.filter_two.delegate)
+
+        filter_three = MyFilter()
+        self.percolator.insertfilter(self.filter_two)
+        self.percolator.insertfilter(filter_three)
+        self.percolator.removefilter(self.filter_one)
+        self.assertEqual(self.percolator.top, filter_three)
+        self.assertEqual(filter_three.delegate, self.filter_two)
+        self.assertEqual(self.filter_two.delegate, self.percolator.bottom)
+        self.assertIsNone(self.filter_one.delegate)
+
+    def test_insert(self):
+        self.text.insert('insert', 'foo')
+        self.assertEqual(self.text.get('1.0', END), 'foo\n')
+        self.assertTupleEqual(self.filter_one.insert_called_with,
+                              ('insert', 'foo', None))
+
+    def test_modify_insert(self):
+        self.filter_one.insert = self.filter_one.uppercase_insert
+        self.text.insert('insert', 'bAr')
+        self.assertEqual(self.text.get('1.0', END), 'BAR\n')
+
+    def test_modify_chain_insert(self):
+        filter_three = MyFilter()
+        self.percolator.insertfilter(filter_three)
+        self.filter_two.insert = self.filter_two.uppercase_insert
+        self.filter_one.insert = self.filter_one.lowercase_insert
+        self.text.insert('insert', 'BaR')
+        self.assertEqual(self.text.get('1.0', END), 'bar\n')
+
+    def test_dont_insert(self):
+        self.filter_one.insert = self.filter_one.dont_insert
+        self.text.insert('insert', 'foo bar')
+        self.assertEqual(self.text.get('1.0', END), '\n')
+        self.filter_one.insert = self.filter_one.dont_insert
+        self.text.insert('insert', 'foo bar')
+        self.assertEqual(self.text.get('1.0', END), '\n')
+
+    def test_without_filter(self):
+        self.text.insert('insert', 'hello')
+        self.assertEqual(self.text.get('1.0', 'end'), 'hello\n')
+
+    def test_delete(self):
+        self.text.insert('insert', 'foo')
+        self.text.delete('1.0', '1.2')
+        self.assertEqual(self.text.get('1.0', END), 'o\n')
+        self.assertTupleEqual(self.filter_one.delete_called_with,
+                              ('1.0', '1.2'))
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_replacedialog.py b/Lib/idlelib/idle_test/test_replacedialog.py
new file mode 100644 (file)
index 0000000..ff44820
--- /dev/null
@@ -0,0 +1,293 @@
+"""Unittest for idlelib.ReplaceDialog"""
+from test.support import requires
+requires('gui')
+
+import unittest
+from unittest.mock import Mock
+from tkinter import Tk, Text
+from idlelib.idle_test.mock_tk import Mbox
+import idlelib.SearchEngine as se
+import idlelib.ReplaceDialog as rd
+
+orig_mbox = se.tkMessageBox
+showerror = Mbox.showerror
+
+
+class ReplaceDialogTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = Tk()
+        cls.root.withdraw()
+        se.tkMessageBox = Mbox
+        cls.engine = se.SearchEngine(cls.root)
+        cls.dialog = rd.ReplaceDialog(cls.root, cls.engine)
+        cls.dialog.ok = Mock()
+        cls.text = Text(cls.root)
+        cls.text.undo_block_start = Mock()
+        cls.text.undo_block_stop = Mock()
+        cls.dialog.text = cls.text
+
+    @classmethod
+    def tearDownClass(cls):
+        se.tkMessageBox = orig_mbox
+        del cls.text, cls.dialog, cls.engine
+        cls.root.destroy()
+        del cls.root
+
+    def setUp(self):
+        self.text.insert('insert', 'This is a sample sTring')
+
+    def tearDown(self):
+        self.engine.patvar.set('')
+        self.dialog.replvar.set('')
+        self.engine.wordvar.set(False)
+        self.engine.casevar.set(False)
+        self.engine.revar.set(False)
+        self.engine.wrapvar.set(True)
+        self.engine.backvar.set(False)
+        showerror.title = ''
+        showerror.message = ''
+        self.text.delete('1.0', 'end')
+
+    def test_replace_simple(self):
+        # Test replace function with all options at default setting.
+        # Wrap around - True
+        # Regular Expression - False
+        # Match case - False
+        # Match word - False
+        # Direction - Forwards
+        text = self.text
+        equal = self.assertEqual
+        pv = self.engine.patvar
+        rv = self.dialog.replvar
+        replace = self.dialog.replace_it
+
+        # test accessor method
+        self.engine.setpat('asdf')
+        equal(self.engine.getpat(), pv.get())
+
+        # text found and replaced
+        pv.set('a')
+        rv.set('asdf')
+        self.dialog.open(self.text)
+        replace()
+        equal(text.get('1.8', '1.12'), 'asdf')
+
+        # dont "match word" case
+        text.mark_set('insert', '1.0')
+        pv.set('is')
+        rv.set('hello')
+        replace()
+        equal(text.get('1.2', '1.7'), 'hello')
+
+        # dont "match case" case
+        pv.set('string')
+        rv.set('world')
+        replace()
+        equal(text.get('1.23', '1.28'), 'world')
+
+        # without "regular expression" case
+        text.mark_set('insert', 'end')
+        text.insert('insert', '\nline42:')
+        before_text = text.get('1.0', 'end')
+        pv.set('[a-z][\d]+')
+        replace()
+        after_text = text.get('1.0', 'end')
+        equal(before_text, after_text)
+
+        # test with wrap around selected and complete a cycle
+        text.mark_set('insert', '1.9')
+        pv.set('i')
+        rv.set('j')
+        replace()
+        equal(text.get('1.8'), 'i')
+        equal(text.get('2.1'), 'j')
+        replace()
+        equal(text.get('2.1'), 'j')
+        equal(text.get('1.8'), 'j')
+        before_text = text.get('1.0', 'end')
+        replace()
+        after_text = text.get('1.0', 'end')
+        equal(before_text, after_text)
+
+        # text not found
+        before_text = text.get('1.0', 'end')
+        pv.set('foobar')
+        replace()
+        after_text = text.get('1.0', 'end')
+        equal(before_text, after_text)
+
+        # test access method
+        self.dialog.find_it(0)
+
+    def test_replace_wrap_around(self):
+        text = self.text
+        equal = self.assertEqual
+        pv = self.engine.patvar
+        rv = self.dialog.replvar
+        replace = self.dialog.replace_it
+        self.engine.wrapvar.set(False)
+
+        # replace candidate found both after and before 'insert'
+        text.mark_set('insert', '1.4')
+        pv.set('i')
+        rv.set('j')
+        replace()
+        equal(text.get('1.2'), 'i')
+        equal(text.get('1.5'), 'j')
+        replace()
+        equal(text.get('1.2'), 'i')
+        equal(text.get('1.20'), 'j')
+        replace()
+        equal(text.get('1.2'), 'i')
+
+        # replace candidate found only before 'insert'
+        text.mark_set('insert', '1.8')
+        pv.set('is')
+        before_text = text.get('1.0', 'end')
+        replace()
+        after_text = text.get('1.0', 'end')
+        equal(before_text, after_text)
+
+    def test_replace_whole_word(self):
+        text = self.text
+        equal = self.assertEqual
+        pv = self.engine.patvar
+        rv = self.dialog.replvar
+        replace = self.dialog.replace_it
+        self.engine.wordvar.set(True)
+
+        pv.set('is')
+        rv.set('hello')
+        replace()
+        equal(text.get('1.0', '1.4'), 'This')
+        equal(text.get('1.5', '1.10'), 'hello')
+
+    def test_replace_match_case(self):
+        equal = self.assertEqual
+        text = self.text
+        pv = self.engine.patvar
+        rv = self.dialog.replvar
+        replace = self.dialog.replace_it
+        self.engine.casevar.set(True)
+
+        before_text = self.text.get('1.0', 'end')
+        pv.set('this')
+        rv.set('that')
+        replace()
+        after_text = self.text.get('1.0', 'end')
+        equal(before_text, after_text)
+
+        pv.set('This')
+        replace()
+        equal(text.get('1.0', '1.4'), 'that')
+
+    def test_replace_regex(self):
+        equal = self.assertEqual
+        text = self.text
+        pv = self.engine.patvar
+        rv = self.dialog.replvar
+        replace = self.dialog.replace_it
+        self.engine.revar.set(True)
+
+        before_text = text.get('1.0', 'end')
+        pv.set('[a-z][\d]+')
+        rv.set('hello')
+        replace()
+        after_text = text.get('1.0', 'end')
+        equal(before_text, after_text)
+
+        text.insert('insert', '\nline42')
+        replace()
+        equal(text.get('2.0', '2.8'), 'linhello')
+
+        pv.set('')
+        replace()
+        self.assertIn('error', showerror.title)
+        self.assertIn('Empty', showerror.message)
+
+        pv.set('[\d')
+        replace()
+        self.assertIn('error', showerror.title)
+        self.assertIn('Pattern', showerror.message)
+
+        showerror.title = ''
+        showerror.message = ''
+        pv.set('[a]')
+        rv.set('test\\')
+        replace()
+        self.assertIn('error', showerror.title)
+        self.assertIn('Invalid Replace Expression', showerror.message)
+
+        # test access method
+        self.engine.setcookedpat("\'")
+        equal(pv.get(), "\\'")
+
+    def test_replace_backwards(self):
+        equal = self.assertEqual
+        text = self.text
+        pv = self.engine.patvar
+        rv = self.dialog.replvar
+        replace = self.dialog.replace_it
+        self.engine.backvar.set(True)
+
+        text.insert('insert', '\nis as ')
+
+        pv.set('is')
+        rv.set('was')
+        replace()
+        equal(text.get('1.2', '1.4'), 'is')
+        equal(text.get('2.0', '2.3'), 'was')
+        replace()
+        equal(text.get('1.5', '1.8'), 'was')
+        replace()
+        equal(text.get('1.2', '1.5'), 'was')
+
+    def test_replace_all(self):
+        text = self.text
+        pv = self.engine.patvar
+        rv = self.dialog.replvar
+        replace_all = self.dialog.replace_all
+
+        text.insert('insert', '\n')
+        text.insert('insert', text.get('1.0', 'end')*100)
+        pv.set('is')
+        rv.set('was')
+        replace_all()
+        self.assertNotIn('is', text.get('1.0', 'end'))
+
+        self.engine.revar.set(True)
+        pv.set('')
+        replace_all()
+        self.assertIn('error', showerror.title)
+        self.assertIn('Empty', showerror.message)
+
+        pv.set('[s][T]')
+        rv.set('\\')
+        replace_all()
+
+        self.engine.revar.set(False)
+        pv.set('text which is not present')
+        rv.set('foobar')
+        replace_all()
+
+    def test_default_command(self):
+        text = self.text
+        pv = self.engine.patvar
+        rv = self.dialog.replvar
+        replace_find = self.dialog.default_command
+        equal = self.assertEqual
+
+        pv.set('This')
+        rv.set('was')
+        replace_find()
+        equal(text.get('sel.first', 'sel.last'), 'was')
+
+        self.engine.revar.set(True)
+        pv.set('')
+        replace_find()
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_searchdialog.py b/Lib/idlelib/idle_test/test_searchdialog.py
new file mode 100644 (file)
index 0000000..190c866
--- /dev/null
@@ -0,0 +1,80 @@
+"""Test SearchDialog class in SearchDialogue.py"""
+
+# Does not currently test the event handler wrappers.
+# A usage test should simulate clicks and check hilighting.
+# Tests need to be coordinated with SearchDialogBase tests
+# to avoid duplication.
+
+from test.support import requires
+requires('gui')
+
+import unittest
+import tkinter as tk
+from tkinter import BooleanVar
+import idlelib.SearchEngine as se
+import idlelib.SearchDialog as sd
+
+
+class SearchDialogTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = tk.Tk()
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.root.destroy()
+        del cls.root
+
+    def setUp(self):
+        self.engine = se.SearchEngine(self.root)
+        self.dialog = sd.SearchDialog(self.root, self.engine)
+        self.text = tk.Text(self.root)
+        self.text.insert('1.0', 'Hello World!')
+
+    def test_find_again(self):
+        # Search for various expressions
+        text = self.text
+
+        self.engine.setpat('')
+        self.assertFalse(self.dialog.find_again(text))
+
+        self.engine.setpat('Hello')
+        self.assertTrue(self.dialog.find_again(text))
+
+        self.engine.setpat('Goodbye')
+        self.assertFalse(self.dialog.find_again(text))
+
+        self.engine.setpat('World!')
+        self.assertTrue(self.dialog.find_again(text))
+
+        self.engine.setpat('Hello World!')
+        self.assertTrue(self.dialog.find_again(text))
+
+        # Regular expression
+        self.engine.revar = BooleanVar(self.root, True)
+        self.engine.setpat('W[aeiouy]r')
+        self.assertTrue(self.dialog.find_again(text))
+
+    def test_find_selection(self):
+        # Select some text and make sure it's found
+        text = self.text
+        # Add additional line to find
+        self.text.insert('2.0', 'Hello World!')
+
+        text.tag_add('sel', '1.0', '1.4')       # Select 'Hello'
+        self.assertTrue(self.dialog.find_selection(text))
+
+        text.tag_remove('sel', '1.0', 'end')
+        text.tag_add('sel', '1.6', '1.11')      # Select 'World!'
+        self.assertTrue(self.dialog.find_selection(text))
+
+        text.tag_remove('sel', '1.0', 'end')
+        text.tag_add('sel', '1.0', '1.11')      # Select 'Hello World!'
+        self.assertTrue(self.dialog.find_selection(text))
+
+        # Remove additional line
+        text.delete('2.0', 'end')
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2, exit=2)
index 68e5b82..02d1472 100644 (file)
@@ -1,4 +1,4 @@
-'''Test the functions and main class method of textView.py.
+'''Test idlelib.textView.
 
 Since all methods and functions create (or destroy) a TextViewer, which
 is a widget containing multiple widgets, all tests must be gui tests.
@@ -22,7 +22,9 @@ def setUpModule():
     root = Tk()
 
 def tearDownModule():
-    global root
+    global root, TV
+    del TV
+    root.update_idletasks()
     root.destroy()  # pyflakes falsely sees root as undefined
     del root
 
diff --git a/Lib/idlelib/idle_test/test_undodelegator.py b/Lib/idlelib/idle_test/test_undodelegator.py
new file mode 100644 (file)
index 0000000..2b83c99
--- /dev/null
@@ -0,0 +1,135 @@
+"""Unittest for UndoDelegator in idlelib.UndoDelegator.
+
+Coverage about 80% (retest).
+"""
+from test.support import requires
+requires('gui')
+
+import unittest
+from unittest.mock import Mock
+from tkinter import Text, Tk
+from idlelib.UndoDelegator import UndoDelegator
+from idlelib.Percolator import Percolator
+
+
+class UndoDelegatorTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = Tk()
+        cls.text = Text(cls.root)
+        cls.percolator = Percolator(cls.text)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.percolator.redir.close()
+        del cls.percolator, cls.text
+        cls.root.destroy()
+        del cls.root
+
+    def setUp(self):
+        self.delegator = UndoDelegator()
+        self.percolator.insertfilter(self.delegator)
+        self.delegator.bell = Mock(wraps=self.delegator.bell)
+
+    def tearDown(self):
+        self.percolator.removefilter(self.delegator)
+        self.text.delete('1.0', 'end')
+        self.delegator.resetcache()
+
+    def test_undo_event(self):
+        text = self.text
+
+        text.insert('insert', 'foobar')
+        text.insert('insert', 'h')
+        text.event_generate('<<undo>>')
+        self.assertEqual(text.get('1.0', 'end'), '\n')
+
+        text.insert('insert', 'foo')
+        text.insert('insert', 'bar')
+        text.delete('1.2', '1.4')
+        text.insert('insert', 'hello')
+        text.event_generate('<<undo>>')
+        self.assertEqual(text.get('1.0', '1.4'), 'foar')
+        text.event_generate('<<undo>>')
+        self.assertEqual(text.get('1.0', '1.6'), 'foobar')
+        text.event_generate('<<undo>>')
+        self.assertEqual(text.get('1.0', '1.3'), 'foo')
+        text.event_generate('<<undo>>')
+        self.delegator.undo_event('event')
+        self.assertTrue(self.delegator.bell.called)
+
+    def test_redo_event(self):
+        text = self.text
+
+        text.insert('insert', 'foo')
+        text.insert('insert', 'bar')
+        text.delete('1.0', '1.3')
+        text.event_generate('<<undo>>')
+        text.event_generate('<<redo>>')
+        self.assertEqual(text.get('1.0', '1.3'), 'bar')
+        text.event_generate('<<redo>>')
+        self.assertTrue(self.delegator.bell.called)
+
+    def test_dump_event(self):
+        """
+        Dump_event cannot be tested directly without changing
+        environment variables. So, test statements in dump_event
+        indirectly
+        """
+        text = self.text
+        d = self.delegator
+
+        text.insert('insert', 'foo')
+        text.insert('insert', 'bar')
+        text.delete('1.2', '1.4')
+        self.assertTupleEqual((d.pointer, d.can_merge), (3, True))
+        text.event_generate('<<undo>>')
+        self.assertTupleEqual((d.pointer, d.can_merge), (2, False))
+
+    def test_get_set_saved(self):
+        # test the getter method get_saved
+        # test the setter method set_saved
+        # indirectly test check_saved
+        d = self.delegator
+
+        self.assertTrue(d.get_saved())
+        self.text.insert('insert', 'a')
+        self.assertFalse(d.get_saved())
+        d.saved_change_hook = Mock()
+
+        d.set_saved(True)
+        self.assertEqual(d.pointer, d.saved)
+        self.assertTrue(d.saved_change_hook.called)
+
+        d.set_saved(False)
+        self.assertEqual(d.saved, -1)
+        self.assertTrue(d.saved_change_hook.called)
+
+    def test_undo_start_stop(self):
+        # test the undo_block_start and undo_block_stop methods
+        text = self.text
+
+        text.insert('insert', 'foo')
+        self.delegator.undo_block_start()
+        text.insert('insert', 'bar')
+        text.insert('insert', 'bar')
+        self.delegator.undo_block_stop()
+        self.assertEqual(text.get('1.0', '1.3'), 'foo')
+
+        # test another code path
+        self.delegator.undo_block_start()
+        text.insert('insert', 'bar')
+        self.delegator.undo_block_stop()
+        self.assertEqual(text.get('1.0', '1.3'), 'foo')
+
+    def test_addcmd(self):
+        text = self.text
+        # when number of undo operations exceeds max_undo
+        self.delegator.max_undo = max_undo = 10
+        for i in range(max_undo + 10):
+            text.insert('insert', 'foo')
+            self.assertLessEqual(len(self.delegator.undolist), max_undo)
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2, exit=False)
index 54ac993..18627dd 100644 (file)
@@ -68,15 +68,6 @@ class ShellWarnTest(unittest.TestCase):
                     'Test', UserWarning, 'test_warning.py', 99, f, 'Line of code')
             self.assertEqual(shellmsg.splitlines(), f.getvalue().splitlines())
 
-class ImportWarnTest(unittest.TestCase):
-    def test_idlever(self):
-        with warnings.catch_warnings(record=True) as w:
-            warnings.simplefilter("always")
-            import idlelib.idlever
-            self.assertEqual(len(w), 1)
-            self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
-            self.assertIn("version", str(w[-1].message))
-
 
 if __name__ == '__main__':
     unittest.main(verbosity=2, exit=False)
index 6440561..c68dfcc 100644 (file)
@@ -1,7 +1,7 @@
-"""Unittest for idlelib.WidgetRedirector
+'''Test idlelib.WidgetRedirector.
 
 100% coverage
-"""
+'''
 from test.support import requires
 import unittest
 from idlelib.idle_test.mock_idle import Func
@@ -14,14 +14,14 @@ class InitCloseTest(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         requires('gui')
-        cls.tk = Tk()
-        cls.text = Text(cls.tk)
+        cls.root = Tk()
+        cls.text = Text(cls.root)
 
     @classmethod
     def tearDownClass(cls):
-        cls.text.destroy()
-        cls.tk.destroy()
-        del cls.text, cls.tk
+        del cls.text
+        cls.root.destroy()
+        del cls.root
 
     def test_init(self):
         redir = WidgetRedirector(self.text)
@@ -43,14 +43,15 @@ class WidgetRedirectorTest(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         requires('gui')
-        cls.tk = Tk()
-        cls.text = Text(cls.tk)
+        cls.root = Tk()
+        cls.text = Text(cls.root)
 
     @classmethod
     def tearDownClass(cls):
-        cls.text.destroy()
-        cls.tk.destroy()
-        del cls.text, cls.tk
+        del cls.text
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root
 
     def setUp(self):
         self.redir = WidgetRedirector(self.text)
@@ -108,13 +109,13 @@ class WidgetRedirectorTest(unittest.TestCase):
     def test_command_dispatch(self):
         # Test that .__init__ causes redirection of tk calls
         # through redir.dispatch
-        self.tk.call(self.text._w, 'insert', 'hello')
+        self.root.call(self.text._w, 'insert', 'hello')
         self.assertEqual(self.func.args, ('hello',))
         self.assertEqual(self.text.get('1.0', 'end'), '\n')
         # Ensure that called through redir .dispatch and not through
         # self.text.insert by having mock raise TclError.
         self.func.__init__(TclError())
-        self.assertEqual(self.tk.call(self.text._w, 'insert', 'boo'), '')
+        self.assertEqual(self.root.call(self.text._w, 'insert', 'boo'), '')
 
 
 
index aa33041..48105f2 100644 (file)
@@ -1,4 +1,4 @@
-"""RPC Implemention, originally written for the Python Idle IDE
+"""RPC Implementation, originally written for the Python Idle IDE
 
 For security reasons, GvR requested that Idle's Python execution server process
 connect to the Idle process, which listens for the connection.  Since Idle has
index 6f62bb3..9eecbfe 100644 (file)
@@ -922,7 +922,7 @@ def _sanity_check(name, package, level):
         raise TypeError('module name must be str, not {}'.format(type(name)))
     if level < 0:
         raise ValueError('level must be >= 0')
-    if package:
+    if level > 0:
         if not isinstance(package, str):
             raise TypeError('__package__ not set to a string')
         elif package not in sys.modules:
@@ -1043,7 +1043,7 @@ def _calc___package__(globals):
 def __import__(name, globals=None, locals=None, fromlist=(), level=0):
     """Import a module.
 
-    The 'globals' argument is used to infer where the import is occuring from
+    The 'globals' argument is used to infer where the import is occurring from
     to handle relative imports. The 'locals' argument is ignored. The
     'fromlist' argument specifies what should exist as attributes on the module
     being imported (e.g. ``from module import <fromlist>``).  The 'level'
index 616b17f..9788828 100644 (file)
@@ -227,6 +227,9 @@ _code_type = type(_write_atomic.__code__)
 # MAGIC must change whenever the bytecode emitted by the compiler may no
 # longer be understood by older implementations of the eval loop (usually
 # due to the addition of new opcodes).
+#
+# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
+# in PC/launcher.c must also be updated.
 
 MAGIC_NUMBER = (3350).to_bytes(2, 'little') + b'\r\n'
 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c
@@ -1210,8 +1213,8 @@ class FileFinder:
                                        submodule_search_locations=smsl)
 
     def find_spec(self, fullname, target=None):
-        """Try to find a loader for the specified module, or the namespace
-        package portions. Returns (loader, list-of-portions)."""
+        """Try to find a spec for the specified module.  Returns the
+        matching spec, or None if not found."""
         is_namespace = False
         tail_module = fullname.rpartition('.')[2]
         try:
index 11af22d..daff681 100644 (file)
@@ -4,7 +4,6 @@ from . import _bootstrap_external
 from . import machinery
 try:
     import _frozen_importlib
-#    import _frozen_importlib_external
 except ImportError as exc:
     if exc.name != '_frozen_importlib':
         raise
index 1dbff26..4525b3f 100644 (file)
@@ -263,11 +263,6 @@ class LazyLoader(abc.Loader):
     def __check_eager_loader(loader):
         if not hasattr(loader, 'exec_module'):
             raise TypeError('loader must define exec_module()')
-        elif hasattr(loader.__class__, 'create_module'):
-            if abc.Loader.create_module != loader.__class__.create_module:
-                # Only care if create_module() is overridden in a subclass of
-                # importlib.abc.Loader.
-                raise TypeError('loader cannot define create_module()')
 
     @classmethod
     def factory(cls, loader):
index b65bec7..e830eb6 100644 (file)
@@ -2591,8 +2591,6 @@ class BoundArguments:
         empty dict.
         """
         arguments = self.arguments
-        if not arguments:
-            return
         new_arguments = []
         for name, param in self._signature.parameters.items():
             try:
index 7469a9d..1f90058 100644 (file)
@@ -740,21 +740,21 @@ class _BaseNetwork(_IPAddressBase):
 
             addr1 = ip_network('192.0.2.0/28')
             addr2 = ip_network('192.0.2.1/32')
-            addr1.address_exclude(addr2) =
+            list(addr1.address_exclude(addr2)) =
                 [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'),
-                IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')]
+                 IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')]
 
         or IPv6:
 
             addr1 = ip_network('2001:db8::1/32')
             addr2 = ip_network('2001:db8::1/128')
-            addr1.address_exclude(addr2) =
+            list(addr1.address_exclude(addr2)) =
                 [ip_network('2001:db8::1/128'),
-                ip_network('2001:db8::2/127'),
-                ip_network('2001:db8::4/126'),
-                ip_network('2001:db8::8/125'),
-                ...
-                ip_network('2001:db8:8000::/33')]
+                 ip_network('2001:db8::2/127'),
+                 ip_network('2001:db8::4/126'),
+                 ip_network('2001:db8::8/125'),
+                 ...
+                 ip_network('2001:db8:8000::/33')]
 
         Args:
             other: An IPv4Network or IPv6Network object of the same type.
@@ -916,7 +916,7 @@ class _BaseNetwork(_IPAddressBase):
                     new_prefixlen, self))
 
         start = int(self.network_address)
-        end = int(self.broadcast_address)
+        end = int(self.broadcast_address) + 1
         step = (int(self.hostmask) + 1) >> prefixlen_diff
         for new_addr in range(start, end, step):
             current = self.__class__((new_addr, new_prefixlen))
@@ -1312,6 +1312,11 @@ class IPv4Address(_BaseV4, _BaseAddress):
         return any(self in net for net in self._constants._private_networks)
 
     @property
+    @functools.lru_cache()
+    def is_global(self):
+        return self not in self._constants._public_network and not self.is_private
+
+    @property
     def is_multicast(self):
         """Test if the address is reserved for multicast use.
 
@@ -1557,6 +1562,8 @@ class _IPv4Constants:
 
     _multicast_network = IPv4Network('224.0.0.0/4')
 
+    _public_network = IPv4Network('100.64.0.0/10')
+
     _private_networks = [
         IPv4Network('0.0.0.0/8'),
         IPv4Network('10.0.0.0/8'),
index 26e9eb2..d596489 100644 (file)
@@ -32,7 +32,6 @@ for i in range(0x20):
     #ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
 
 INFINITY = float('inf')
-FLOAT_REPR = repr
 
 def py_encode_basestring(s):
     """Return a JSON representation of a Python string
@@ -221,7 +220,7 @@ class JSONEncoder(object):
             _encoder = encode_basestring
 
         def floatstr(o, allow_nan=self.allow_nan,
-                _repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY):
+                _repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY):
             # Check for specials.  Note that this type of test is processor
             # and/or platform-specific, so do tests which don't depend on the
             # internals.
@@ -268,6 +267,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
         list=list,
         str=str,
         tuple=tuple,
+        _intstr=int.__str__,
     ):
 
     if _indent is not None and not isinstance(_indent, str):
@@ -309,10 +309,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
                 # Subclasses of int/float may override __str__, but we still
                 # want to encode them as integers/floats in JSON. One example
                 # within the standard library is IntEnum.
-                yield buf + str(int(value))
+                yield buf + _intstr(value)
             elif isinstance(value, float):
                 # see comment above for int
-                yield buf + _floatstr(float(value))
+                yield buf + _floatstr(value)
             else:
                 yield buf
                 if isinstance(value, (list, tuple)):
@@ -359,7 +359,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
             # also allow them.  Many encoders seem to do something like this.
             elif isinstance(key, float):
                 # see comment for int/float in _make_iterencode
-                key = _floatstr(float(key))
+                key = _floatstr(key)
             elif key is True:
                 key = 'true'
             elif key is False:
@@ -368,7 +368,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
                 key = 'null'
             elif isinstance(key, int):
                 # see comment for int/float in _make_iterencode
-                key = str(int(key))
+                key = _intstr(key)
             elif _skipkeys:
                 continue
             else:
@@ -389,10 +389,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
                 yield 'false'
             elif isinstance(value, int):
                 # see comment for int/float in _make_iterencode
-                yield str(int(value))
+                yield _intstr(value)
             elif isinstance(value, float):
                 # see comment for int/float in _make_iterencode
-                yield _floatstr(float(value))
+                yield _floatstr(value)
             else:
                 if isinstance(value, (list, tuple)):
                     chunks = _iterencode_list(value, _current_indent_level)
@@ -419,10 +419,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
             yield 'false'
         elif isinstance(o, int):
             # see comment for int/float in _make_iterencode
-            yield str(int(o))
+            yield _intstr(o)
         elif isinstance(o, float):
             # see comment for int/float in _make_iterencode
-            yield _floatstr(float(o))
+            yield _floatstr(o)
         elif isinstance(o, (list, tuple)):
             yield from _iterencode_list(o, _current_indent_level)
         elif isinstance(o, dict):
index 339750e..ff76ba3 100644 (file)
@@ -215,7 +215,7 @@ def reduce_tree(node, parent=None):
                 #reduce to None
                 new_node = None
             elif repeater_node.children[0].value == '+':
-                #reduce to a single occurence i.e. do nothing
+                #reduce to a single occurrence i.e. do nothing
                 pass
             else:
                 #TODO: handle {min, max} repeaters
index b176056..1ce62fe 100644 (file)
@@ -49,7 +49,7 @@ class BaseFix(object):
         """Initializer.  Subclass may override.
 
         Args:
-            options: an dict containing the options passed to RefactoringTool
+            options: a dict containing the options passed to RefactoringTool
             that could be used to customize the fixer through the command line.
             log: a list to append warnings and other messages to.
         """
index f3f8708..46c7aaf 100644 (file)
@@ -25,7 +25,7 @@ from ..fixer_util import Name, syms, Node, Leaf
 
 def has_metaclass(parent):
     """ we have to check the cls_node without changing it.
-        There are two possiblities:
+        There are two possibilities:
           1)  clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta')
           2)  clsdef => simple_stmt => expr_stmt => Leaf('__meta')
     """
index 2012ec4..06a4b9d 100644 (file)
@@ -3,7 +3,7 @@
 
 """Pattern compiler.
 
-The grammer is taken from PatternGrammar.txt.
+The grammar is taken from PatternGrammar.txt.
 
 The compiler compiles a pattern to a pytree.*Pattern instance.
 """
index 1ff1c61..d14db60 100644 (file)
@@ -236,7 +236,7 @@ class Untokenizer:
                 startline = False
             toks_append(tokval)
 
-cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII)
+cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII)
 blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII)
 
 def _get_normal_name(orig_enc):
index adf9996..0728083 100644 (file)
@@ -184,7 +184,7 @@ class RefactoringTool(object):
 
         Args:
             fixer_names: a list of fixers to import
-            options: an dict with configuration.
+            options: a dict with configuration.
             explicit: a list of fixers to run even if they are explicit.
         """
         self.fixers = fixer_names
index c6359bf..2e7e978 100755 (executable)
@@ -18,8 +18,8 @@ import logging
 
 # Local imports
 from .. import pytree
-import pgen2
-from pgen2 import driver
+from .. import pgen2
+from ..pgen2 import driver
 
 logging.basicConfig()
 
index ceaa6d8..6d59cd8 100644 (file)
@@ -1,13 +1,12 @@
-""" Locale support.
+"""Locale support module.
 
-    The module provides low-level access to the C lib's locale APIs
-    and adds high level number formatting APIs as well as a locale
-    aliasing engine to complement these.
+The module provides low-level access to the C lib's locale APIs and adds high
+level number formatting APIs as well as a locale aliasing engine to complement
+these.
 
-    The aliasing engine includes support for many commonly used locale
-    names and maps them to values suitable for passing to the C lib's
-    setlocale() function. It also includes default encodings for all
-    supported locale names.
+The aliasing engine includes support for many commonly used locale names and
+maps them to values suitable for passing to the C lib's setlocale() function. It
+also includes default encodings for all supported locale names.
 
 """
 
@@ -298,7 +297,7 @@ def currency(val, symbol=True, grouping=False, international=False):
     return s.replace('<', '').replace('>', '')
 
 def str(val):
-    """Convert float to integer, taking the locale into account."""
+    """Convert float to string, taking the locale into account."""
     return format("%.12g", val)
 
 def delocalize(string):
@@ -1452,7 +1451,7 @@ windows_locale = {
     0x1809: "en_IE", # English - Ireland
     0x1c09: "en_ZA", # English - South Africa
     0x2009: "en_JA", # English - Jamaica
-    0x2409: "en_CB", # English - Carribbean
+    0x2409: "en_CB", # English - Caribbean
     0x2809: "en_BZ", # English - Belize
     0x2c09: "en_TT", # English - Trinidad
     0x3009: "en_ZW", # English - Zimbabwe
index 104b0be..a7bd890 100644 (file)
@@ -471,7 +471,7 @@ class Formatter(object):
         use one of %-formatting, :meth:`str.format` (``{}``) formatting or
         :class:`string.Template` formatting in your format string.
 
-        .. versionchanged: 3.2
+        .. versionchanged:: 3.2
            Added the ``style`` parameter.
         """
         if style not in _STYLES:
@@ -700,7 +700,7 @@ class Filterer(object):
         this and the record is then dropped. Returns a zero value if a record
         is to be dropped, else non-zero.
 
-        .. versionchanged: 3.2
+        .. versionchanged:: 3.2
 
            Allow filters to be just callables.
         """
index b810fa9..c9f8217 100644 (file)
@@ -588,6 +588,8 @@ class SocketHandler(logging.Handler):
         d['msg'] = record.getMessage()
         d['args'] = None
         d['exc_info'] = None
+        # Issue #25685: delete 'message' if present: redundant with 'msg'
+        d.pop('message', None)
         s = pickle.dumps(d, 1)
         slen = struct.pack(">L", len(s))
         return slen + s
@@ -1154,8 +1156,8 @@ class HTTPHandler(logging.Handler):
                 h.putheader("Content-length", str(len(data)))
             if self.credentials:
                 import base64
-                s = ('u%s:%s' % self.credentials).encode('utf-8')
-                s = 'Basic ' + base64.b64encode(s).strip()
+                s = ('%s:%s' % self.credentials).encode('utf-8')
+                s = 'Basic ' + base64.b64encode(s).strip().decode('ascii')
                 h.putheader('Authorization', s)
             h.endheaders()
             if self.method == "POST":
index 89528b6..7dff1c3 100644 (file)
@@ -279,7 +279,7 @@ def open(filename, mode="rb", *,
     constructor: LZMAFile(filename, mode, ...). In this case, the
     encoding, errors and newline arguments must not be provided.
 
-    For text mode, a LZMAFile object is created, and wrapped in an
+    For text mode, an LZMAFile object is created, and wrapped in an
     io.TextIOWrapper instance with the specified encoding, error
     handling behavior, and line ending(s).
 
index 24d4aec..0270e25 100644 (file)
@@ -1821,7 +1821,7 @@ class BabylMessage(Message):
     _type_specific_attributes = ['_labels', '_visible']
 
     def __init__(self, message=None):
-        """Initialize an BabylMessage instance."""
+        """Initialize a BabylMessage instance."""
         self._labels = []
         self._visible = Message()
         Message.__init__(self, message)
index d64726b..0be76ad 100644 (file)
@@ -416,6 +416,7 @@ def _default_mime_types():
         '.cpio'   : 'application/x-cpio',
         '.csh'    : 'application/x-csh',
         '.css'    : 'text/css',
+        '.csv'    : 'text/csv',
         '.dll'    : 'application/octet-stream',
         '.doc'    : 'application/msword',
         '.dot'    : 'application/msword',
@@ -513,6 +514,7 @@ def _default_mime_types():
         '.ustar'  : 'application/x-ustar',
         '.vcf'    : 'text/x-vcard',
         '.wav'    : 'audio/x-wav',
+        '.webm'   : 'video/webm',
         '.wiz'    : 'application/msword',
         '.wsdl'   : 'application/xml',
         '.xbm'    : 'image/x-xbitmap',
index 50f2462..8103502 100644 (file)
@@ -13,13 +13,12 @@ with warnings.catch_warnings():
     warnings.simplefilter('ignore', PendingDeprecationWarning)
     import imp
 
-# XXX Clean up once str8's cstor matches bytes.
-LOAD_CONST = bytes([dis.opname.index('LOAD_CONST')])
-IMPORT_NAME = bytes([dis.opname.index('IMPORT_NAME')])
-STORE_NAME = bytes([dis.opname.index('STORE_NAME')])
-STORE_GLOBAL = bytes([dis.opname.index('STORE_GLOBAL')])
-STORE_OPS = [STORE_NAME, STORE_GLOBAL]
-HAVE_ARGUMENT = bytes([dis.HAVE_ARGUMENT])
+LOAD_CONST = dis.opmap['LOAD_CONST']
+IMPORT_NAME = dis.opmap['IMPORT_NAME']
+STORE_NAME = dis.opmap['STORE_NAME']
+STORE_GLOBAL = dis.opmap['STORE_GLOBAL']
+STORE_OPS = STORE_NAME, STORE_GLOBAL
+EXTENDED_ARG = dis.EXTENDED_ARG
 
 # Modulefinder does a good job at simulating Python's, but it can not
 # handle __path__ modifications packages make at runtime.  Therefore there
@@ -340,31 +339,24 @@ class ModuleFinder:
     def scan_opcodes_25(self, co,
                      unpack = struct.unpack):
         # Scan the code, and yield 'interesting' opcode combinations
-        # Python 2.5 version (has absolute and relative imports)
         code = co.co_code
         names = co.co_names
         consts = co.co_consts
-        LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME
-        while code:
-            c = bytes([code[0]])
-            if c in STORE_OPS:
-                oparg, = unpack('<H', code[1:3])
+        opargs = [(op, arg) for _, op, arg in dis._unpack_opargs(code)
+                  if op != EXTENDED_ARG]
+        for i, (op, oparg) in enumerate(opargs):
+            if op in STORE_OPS:
                 yield "store", (names[oparg],)
-                code = code[3:]
                 continue
-            if code[:9:3] == LOAD_LOAD_AND_IMPORT:
-                oparg_1, oparg_2, oparg_3 = unpack('<xHxHxH', code[:9])
-                level = consts[oparg_1]
+            if (op == IMPORT_NAME and i >= 2
+                    and opargs[i-1][0] == opargs[i-2][0] == LOAD_CONST):
+                level = consts[opargs[i-2][1]]
+                fromlist = consts[opargs[i-1][1]]
                 if level == 0: # absolute import
-                    yield "absolute_import", (consts[oparg_2], names[oparg_3])
+                    yield "absolute_import", (fromlist, names[oparg])
                 else: # relative import
-                    yield "relative_import", (level, consts[oparg_2], names[oparg_3])
-                code = code[9:]
+                    yield "relative_import", (level, fromlist, names[oparg])
                 continue
-            if c >= HAVE_ARGUMENT:
-                code = code[3:]
-            else:
-                code = code[1:]
 
     def scan_code(self, co, m):
         code = co.co_code
index 873560d..6d0a28f 100644 (file)
@@ -1,7 +1,11 @@
 # Copyright (C) 2005 Martin v. Löwis
 # Licensed to PSF under a Contributor Agreement.
 from _msi import *
-import os, string, re, sys
+import glob
+import os
+import re
+import string
+import sys
 
 AMD64 = "AMD64" in sys.version
 Itanium = "Itanium" in sys.version
index 70fe138..eeb3ecd 100644 (file)
@@ -731,7 +731,7 @@ _Validation_records = [
 ('CustomAction','Type','N',1,16383,None, None, None, None, 'The numeric custom action type, consisting of source location, code type, entry, option flags.',),
 ('CustomAction','Action','N',None, None, None, None, 'Identifier',None, 'Primary key, name of action, normally appears in sequence table unless private use.',),
 ('CustomAction','Source','Y',None, None, None, None, 'CustomSource',None, 'The table reference of the source of the code.',),
-('CustomAction','Target','Y',None, None, None, None, 'Formatted',None, 'Excecution parameter, depends on the type of custom action',),
+('CustomAction','Target','Y',None, None, None, None, 'Formatted',None, 'Execution parameter, depends on the type of custom action',),
 ('DrLocator','Signature_','N',None, None, None, None, 'Identifier',None, 'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',),
 ('DrLocator','Path','Y',None, None, None, None, 'AnyPath',None, 'The path on the user system. This is either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',),
 ('DrLocator','Depth','Y',0,32767,None, None, None, None, 'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.',),
index 4c32237..d0a1b86 100644 (file)
@@ -397,7 +397,7 @@ class Connection(_ConnectionBase):
             self._send(header)
             self._send(buf)
         else:
-            # Issue #20540: concatenate before sending, to avoid delays due
+            # Issue #20540: concatenate before sending, to avoid delays due
             # to Nagle's algorithm on a TCP socket.
             # Also note we want to avoid sending a 0-length buffer separately,
             # to avoid "broken pipe" errors if the other end closed the pipe.
index b27cba5..ad01ede 100644 (file)
@@ -147,13 +147,7 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None):
             except ImportError:
                 pass
 
-    # close sys.stdin
-    if sys.stdin is not None:
-        try:
-            sys.stdin.close()
-            sys.stdin = open(os.devnull)
-        except (OSError, ValueError):
-            pass
+    util._close_stdin()
 
     # ignoring SIGCHLD means no need to reap zombie processes
     handler = signal.signal(signal.SIGCHLD, signal.SIG_IGN)
index 776656e..c559b55 100644 (file)
@@ -842,7 +842,7 @@ def RebuildProxy(func, token, serializer, kwds):
 
 def MakeProxyType(name, exposed, _cache={}):
     '''
-    Return an proxy type whose methods are given by `exposed`
+    Return a proxy type whose methods are given by `exposed`
     '''
     exposed = tuple(exposed)
     try:
index 68959bf..bca8b7a 100644 (file)
@@ -234,12 +234,7 @@ class BaseProcess(object):
                 context._force_start_method(self._start_method)
             _process_counter = itertools.count(1)
             _children = set()
-            if sys.stdin is not None:
-                try:
-                    sys.stdin.close()
-                    sys.stdin = open(os.devnull)
-                except (OSError, ValueError):
-                    pass
+            util._close_stdin()
             old_process = _current_process
             _current_process = self
             try:
index 336e479..4d76951 100644 (file)
@@ -91,7 +91,7 @@ def get_command_line(**kwds):
 
 def spawn_main(pipe_handle, parent_pid=None, tracker_fd=None):
     '''
-    Run code specifed by data received over pipe
+    Run code specified by data received over pipe
     '''
     assert is_forking(sys.argv)
     if sys.platform == 'win32':
index ea5443d..1a2c0db 100644 (file)
@@ -9,6 +9,7 @@
 
 import os
 import itertools
+import sys
 import weakref
 import atexit
 import threading        # we want threading to install it's
@@ -356,6 +357,28 @@ def close_all_fds_except(fds):
     assert fds[-1] == MAXFD, 'fd too large'
     for i in range(len(fds) - 1):
         os.closerange(fds[i]+1, fds[i+1])
+#
+# Close sys.stdin and replace stdin with os.devnull
+#
+
+def _close_stdin():
+    if sys.stdin is None:
+        return
+
+    try:
+        sys.stdin.close()
+    except (OSError, ValueError):
+        pass
+
+    try:
+        fd = os.open(os.devnull, os.O_RDONLY)
+        try:
+            sys.stdin = open(fd, closefd=False)
+        except:
+            os.close(fd)
+            raise
+    except (OSError, ValueError):
+        pass
 
 #
 # Start a program with only specified fds kept open
index a75faad..28cd099 100644 (file)
@@ -165,7 +165,7 @@ ArticleInfo = collections.namedtuple('ArticleInfo',
 
 # Helper function(s)
 def decode_header(header_str):
-    """Takes an unicode string representing a munged header value
+    """Takes a unicode string representing a munged header value
     and decodes it as a (possibly non-ASCII) readable value."""
     parts = []
     for v, enc in _email_decode_header(header_str):
@@ -420,7 +420,7 @@ class _NNTPBase:
 
     def _putcmd(self, line):
         """Internal: send one command to the server (through _putline()).
-        The `line` must be an unicode string."""
+        The `line` must be a unicode string."""
         if self.debugging: print('*cmd*', repr(line))
         line = line.encode(self.encoding, self.errors)
         self._putline(line)
@@ -445,7 +445,7 @@ class _NNTPBase:
     def _getresp(self):
         """Internal: get a response from the server.
         Raise various errors if the response indicates an error.
-        Returns an unicode string."""
+        Returns a unicode string."""
         resp = self._getline()
         if self.debugging: print('*resp*', repr(resp))
         resp = resp.decode(self.encoding, self.errors)
@@ -462,7 +462,7 @@ class _NNTPBase:
         """Internal: get a response plus following text from the server.
         Raise various errors if the response indicates an error.
 
-        Returns a (response, lines) tuple where `response` is an unicode
+        Returns a (response, lines) tuple where `response` is a unicode
         string and `lines` is a list of bytes objects.
         If `file` is a file-like object, it must be open in binary mode.
         """
index 9cc5ca7..af6a709 100644 (file)
@@ -177,7 +177,7 @@ def splitunc(p):
     Return a 2-tuple (unc, rest); either part may be empty.
     If unc is not empty, it has the form '//host/mount' (or similar
     using backslashes).  unc+rest is always the input path.
-    Paths containing drive letters never have an UNC part.
+    Paths containing drive letters never have a UNC part.
     """
     import warnings
     warnings.warn("ntpath.splitunc is deprecated, use ntpath.splitdrive instead",
index 432a2eb..74b3b36 100644 (file)
@@ -900,7 +900,7 @@ class OptionContainer:
       _short_opt : { string : Option }
         dictionary mapping short option strings, eg. "-f" or "-X",
         to the Option instances that implement them.  If an Option
-        has multiple short option strings, it will appears in this
+        has multiple short option strings, it will appear in this
         dictionary multiple times. [1]
       _long_opt : { string : Option }
         dictionary mapping long option strings, eg. "--file" or
@@ -1361,7 +1361,7 @@ class OptionParser (OptionContainer):
         sys.argv[1:]).  Any errors result in a call to 'error()', which
         by default prints the usage message to stderr and calls
         sys.exit() with an error message.  On success returns a pair
-        (values, args) where 'values' is an Values instance (with all
+        (values, args) where 'values' is a Values instance (with all
         your option values) and 'args' is the list of arguments left
         over after parsing options.
         """
index 2b89b93..b4c651d 100644 (file)
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -363,25 +363,19 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
     # minor reason when (say) a thousand readable directories are still
     # left to visit.  That logic is copied here.
     try:
-        # Note that scandir is global in this module due
-        # to earlier import-*.
-        scandir_it = scandir(top)
+        if name == 'nt' and isinstance(top, bytes):
+            scandir_it = _dummy_scandir(top)
+        else:
+            # Note that scandir is global in this module due
+            # to earlier import-*.
+            scandir_it = scandir(top)
+        entries = list(scandir_it)
     except OSError as error:
         if onerror is not None:
             onerror(error)
         return
 
-    while True:
-        try:
-            try:
-                entry = next(scandir_it)
-            except StopIteration:
-                break
-        except OSError as error:
-            if onerror is not None:
-                onerror(error)
-            return
-
+    for entry in entries:
         try:
             is_dir = entry.is_dir()
         except OSError:
@@ -418,8 +412,8 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
 
         # Recurse into sub-directories
         islink, join = path.islink, path.join
-        for name in dirs:
-            new_path = join(top, name)
+        for dirname in dirs:
+            new_path = join(top, dirname)
             # Issue #23605: os.path.islink() is used instead of caching
             # entry.is_symlink() result during the loop on os.scandir() because
             # the caller can replace the directory entry during the "yield"
@@ -430,6 +424,54 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
         # Yield after recursion if going bottom up
         yield top, dirs, nondirs
 
+class _DummyDirEntry:
+    """Dummy implementation of DirEntry
+
+    Only used internally by os.walk(bytes). Since os.walk() doesn't need the
+    follow_symlinks parameter: don't implement it, always follow symbolic
+    links.
+    """
+
+    def __init__(self, dir, name):
+        self.name = name
+        self.path = path.join(dir, name)
+        # Mimick FindFirstFile/FindNextFile: we should get file attributes
+        # while iterating on a directory
+        self._stat = None
+        self._lstat = None
+        try:
+            self.stat(follow_symlinks=False)
+        except OSError:
+            pass
+
+    def stat(self, *, follow_symlinks=True):
+        if follow_symlinks:
+            if self._stat is None:
+                self._stat = stat(self.path)
+            return self._stat
+        else:
+            if self._lstat is None:
+                self._lstat = stat(self.path, follow_symlinks=False)
+            return self._lstat
+
+    def is_dir(self):
+        if self._lstat is not None and not self.is_symlink():
+            # use the cache lstat
+            stat = self.stat(follow_symlinks=False)
+            return st.S_ISDIR(stat.st_mode)
+
+        stat = self.stat()
+        return st.S_ISDIR(stat.st_mode)
+
+    def is_symlink(self):
+        stat = self.stat(follow_symlinks=False)
+        return st.S_ISLNK(stat.st_mode)
+
+def _dummy_scandir(dir):
+    # listdir-based implementation for bytes patches on Windows
+    for name in listdir(dir):
+        yield _DummyDirEntry(dir, name)
+
 __all__.append("walk")
 
 if {open, stat} <= supports_dir_fd and {listdir, stat} <= supports_fd:
@@ -514,7 +556,7 @@ if {open, stat} <= supports_dir_fd and {listdir, stat} <= supports_fd:
             except OSError as err:
                 if onerror is not None:
                     onerror(err)
-                return
+                continue
             try:
                 if follow_symlinks or path.samestat(orig_st, stat(dirfd)):
                     dirpath = path.join(toppath, name)
index 1b5d2a9..1480e2f 100644 (file)
@@ -499,12 +499,15 @@ class _PreciseSelector(_Selector):
         _Selector.__init__(self, child_parts)
 
     def _select_from(self, parent_path, is_dir, exists, listdir):
-        if not is_dir(parent_path):
+        try:
+            if not is_dir(parent_path):
+                return
+            path = parent_path._make_child_relpath(self.name)
+            if exists(path):
+                for p in self.successor._select_from(path, is_dir, exists, listdir):
+                    yield p
+        except PermissionError:
             return
-        path = parent_path._make_child_relpath(self.name)
-        if exists(path):
-            for p in self.successor._select_from(path, is_dir, exists, listdir):
-                yield p
 
 
 class _WildcardSelector(_Selector):
@@ -514,15 +517,19 @@ class _WildcardSelector(_Selector):
         _Selector.__init__(self, child_parts)
 
     def _select_from(self, parent_path, is_dir, exists, listdir):
-        if not is_dir(parent_path):
+        try:
+            if not is_dir(parent_path):
+                return
+            cf = parent_path._flavour.casefold
+            for name in listdir(parent_path):
+                casefolded = cf(name)
+                if self.pat.match(casefolded):
+                    path = parent_path._make_child_relpath(name)
+                    for p in self.successor._select_from(path, is_dir, exists, listdir):
+                        yield p
+        except PermissionError:
             return
-        cf = parent_path._flavour.casefold
-        for name in listdir(parent_path):
-            casefolded = cf(name)
-            if self.pat.match(casefolded):
-                path = parent_path._make_child_relpath(name)
-                for p in self.successor._select_from(path, is_dir, exists, listdir):
-                    yield p
+
 
 
 class _RecursiveWildcardSelector(_Selector):
@@ -532,26 +539,32 @@ class _RecursiveWildcardSelector(_Selector):
 
     def _iterate_directories(self, parent_path, is_dir, listdir):
         yield parent_path
-        for name in listdir(parent_path):
-            path = parent_path._make_child_relpath(name)
-            if is_dir(path):
-                for p in self._iterate_directories(path, is_dir, listdir):
-                    yield p
+        try:
+            for name in listdir(parent_path):
+                path = parent_path._make_child_relpath(name)
+                if is_dir(path) and not path.is_symlink():
+                    for p in self._iterate_directories(path, is_dir, listdir):
+                        yield p
+        except PermissionError:
+            return
 
     def _select_from(self, parent_path, is_dir, exists, listdir):
-        if not is_dir(parent_path):
+        try:
+            if not is_dir(parent_path):
+                return
+            with _cached(listdir) as listdir:
+                yielded = set()
+                try:
+                    successor_select = self.successor._select_from
+                    for starting_point in self._iterate_directories(parent_path, is_dir, listdir):
+                        for p in successor_select(starting_point, is_dir, exists, listdir):
+                            if p not in yielded:
+                                yield p
+                                yielded.add(p)
+                finally:
+                    yielded.clear()
+        except PermissionError:
             return
-        with _cached(listdir) as listdir:
-            yielded = set()
-            try:
-                successor_select = self.successor._select_from
-                for starting_point in self._iterate_directories(parent_path, is_dir, listdir):
-                    for p in successor_select(starting_point, is_dir, exists, listdir):
-                        if p not in yielded:
-                            yield p
-                            yielded.add(p)
-            finally:
-                yielded.clear()
 
 
 #
@@ -661,7 +674,7 @@ class PurePath(object):
             return cls._flavour.join(parts)
 
     def _init(self):
-        # Overriden in concrete Path
+        # Overridden in concrete Path
         pass
 
     def _make_child(self, args):
@@ -1045,6 +1058,8 @@ class Path(PurePath):
         """Iterate over this subtree and yield all existing files (of any
         kind, including directories) matching the given pattern.
         """
+        if not pattern:
+            raise ValueError("Unacceptable pattern: {!r}".format(pattern))
         pattern = self._flavour.casefold(pattern)
         drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
         if drv or root:
@@ -1403,3 +1418,9 @@ class PosixPath(Path, PurePosixPath):
 
 class WindowsPath(Path, PureWindowsPath):
     __slots__ = ()
+
+    def owner(self):
+        raise NotImplementedError("Path.owner() is unsupported on this system")
+
+    def group(self):
+        raise NotImplementedError("Path.group() is unsupported on this system")
index 4cba8a0..b11ac0a 100755 (executable)
@@ -52,7 +52,7 @@ If a file ".pdbrc" exists in your home directory or in the current
 directory, it is read in and executed as if it had been typed at the
 debugger prompt.  This is particularly useful for aliases.  If both
 files exist, the one in the home directory is read first and aliases
-defined there can be overriden by the local file.
+defined there can be overridden by the local file.
 
 Aside from aliases, the debugger is not directly programmable; but it
 is implemented as a class from which you can derive your own debugger
@@ -300,7 +300,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
 
         # An 'Internal StopIteration' exception is an exception debug event
         # issued by the interpreter when handling a subgenerator run with
-        # 'yield from' or a generator controled by a for loop. No exception has
+        # 'yield from' or a generator controlled by a for loop. No exception has
         # actually occurred in this case. The debugger uses this debug event to
         # stop when the debuggee is returning from such generators.
         prefix = 'Internal ' if (not exc_traceback
index 45fd383..7760425 100644 (file)
@@ -995,7 +995,7 @@ class _Unpickler:
         meets this interface.
 
         Optional keyword arguments are *fix_imports*, *encoding* and
-        *errors*, which are used to control compatiblity support for
+        *errors*, which are used to control compatibility support for
         pickle stream generated by Python 2.  If *fix_imports* is True,
         pickle will try to map the old Python 2 names to the new names
         used in Python 3.  The *encoding* and *errors* tell pickle how
@@ -1391,13 +1391,7 @@ class _Unpickler:
         stack = self.stack
         args = stack.pop()
         func = stack[-1]
-        try:
-            value = func(*args)
-        except:
-            print(sys.exc_info())
-            print(func, args)
-            raise
-        stack[-1] = value
+        stack[-1] = func(*args)
     dispatch[REDUCE[0]] = load_reduce
 
     def load_pop(self):
index 155bd5b..16ae7d5 100644 (file)
@@ -590,7 +590,7 @@ bytes8 = ArgumentDescriptor(
               reader=read_bytes8,
               doc="""A counted bytes string.
 
-              The first argument is a 8-byte little-endian unsigned int giving
+              The first argument is an 8-byte little-endian unsigned int giving
               the number of bytes, and the second argument is that many bytes.
               """)
 
@@ -734,7 +734,7 @@ unicodestring8 = ArgumentDescriptor(
                     reader=read_unicodestring8,
                     doc="""A counted Unicode string.
 
-                    The first argument is a 8-byte little-endian signed int
+                    The first argument is an 8-byte little-endian signed int
                     giving the number of bytes in the string, and the second
                     argument-- the UTF-8 encoding of the Unicode string --
                     contains that many bytes.
@@ -1330,7 +1330,7 @@ opcodes = [
       proto=4,
       doc="""Push a Python bytes object.
 
-      There are two arguments:  the first is a 8-byte unsigned int giving
+      There are two arguments:  the first is an 8-byte unsigned int giving
       the number of bytes in the string, and the second is that many bytes,
       which are taken literally as the string content.
       """),
@@ -1417,7 +1417,7 @@ opcodes = [
       proto=4,
       doc="""Push a Python Unicode string object.
 
-      There are two arguments:  the first is a 8-byte little-endian signed int
+      There are two arguments:  the first is an 8-byte little-endian signed int
       giving the number of bytes in the string.  The second is that many
       bytes, and is the UTF-8 encoding of the Unicode string.
       """),
index fc4a074..97726a9 100644 (file)
@@ -375,7 +375,7 @@ try:
             if len(fn)==2 and fn[1].startswith('__init__.py'):
                 if fn[0] not in yielded:
                     yielded[fn[0]] = 1
-                    yield fn[0], True
+                    yield prefix + fn[0], True
 
             if len(fn)!=1:
                 continue
index f3d2c42..d58494c 100755 (executable)
@@ -303,8 +303,7 @@ def linux_distribution(distname='', version='', id='',
                        full_distribution_name=1):
     import warnings
     warnings.warn("dist() and linux_distribution() functions are deprecated "
-                  "in Python 3.5 and will be removed in Python 3.7",
-                  PendingDeprecationWarning, stacklevel=2)
+                  "in Python 3.5", PendingDeprecationWarning, stacklevel=2)
     return _linux_distribution(distname, version, id, supported_dists,
                                full_distribution_name)
 
@@ -378,8 +377,7 @@ def dist(distname='', version='', id='',
     """
     import warnings
     warnings.warn("dist() and linux_distribution() functions are deprecated "
-                  "in Python 3.5 and will be removed in Python 3.7",
-                  PendingDeprecationWarning, stacklevel=2)
+                  "in Python 3.5", PendingDeprecationWarning, stacklevel=2)
     return _linux_distribution(distname, version, id,
                                supported_dists=supported_dists,
                                full_distribution_name=0)
@@ -588,7 +586,7 @@ def win32_ver(release='', version='', csd='', ptype=''):
                 csd = 'SP' + csd[13:]
 
     # VER_NT_SERVER = 3
-    if getattr(winver, 'product_type', None) == 3:
+    if getattr(winver, 'product', None) == 3:
         release = (_WIN32_SERVER_RELEASES.get((maj, min)) or
                    _WIN32_SERVER_RELEASES.get((maj, None)) or
                    release)
@@ -1148,9 +1146,11 @@ def processor():
 ### Various APIs for extracting information from sys.version
 
 _sys_version_parser = re.compile(
-    r'([\w.+]+)\s*'
-    '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
-    '\[([^\]]+)\]?', re.ASCII)
+    r'([\w.+]+)\s*'  # "version<space>"
+    r'\(#?([^,]+)'  # "(#buildno"
+    r'(?:,\s*([\w ]*)'  # ", builddate"
+    r'(?:,\s*([\w :]*))?)?\)\s*'  # ", buildtime)<space>"
+    r'\[([^\]]+)\]?', re.ASCII)  # "[compiler]"
 
 _ironpython_sys_version_parser = re.compile(
     r'IronPython\s*'
@@ -1229,6 +1229,8 @@ def _sys_version(sys_version=None):
                 'failed to parse Jython sys.version: %s' %
                 repr(sys_version))
         version, buildno, builddate, buildtime, _ = match.groups()
+        if builddate is None:
+            builddate = ''
         compiler = sys.platform
 
     elif "PyPy" in sys_version:
@@ -1251,7 +1253,10 @@ def _sys_version(sys_version=None):
         version, buildno, builddate, buildtime, compiler = \
               match.groups()
         name = 'CPython'
-        builddate = builddate + ' ' + buildtime
+        if builddate is None:
+            builddate = ''
+        elif buildtime:
+            builddate = builddate + ' ' + buildtime
 
     if hasattr(sys, '_mercurial'):
         _, branch, revision = sys._mercurial
index b9946fd..b66639c 100644 (file)
@@ -225,10 +225,10 @@ class Data:
     def __eq__(self, other):
         if isinstance(other, self.__class__):
             return self.data == other.data
-        elif isinstance(other, str):
+        elif isinstance(other, bytes):
             return self.data == other
         else:
-            return id(self) == id(other)
+            return NotImplemented
 
     def __repr__(self):
         return "%s(%s)" % (self.__class__.__name__, repr(self.data))
@@ -685,7 +685,7 @@ class _BinaryPlistParser:
             f = struct.unpack('>d', self._fp.read(8))[0]
             # timestamp 0 of binary plists corresponds to 1/1/2001
             # (year of Mac OS X 10.0), instead of 1/1/1970.
-            return datetime.datetime.utcfromtimestamp(f + (31 * 365 + 8) * 86400)
+            return datetime.datetime(2001, 1, 1) + datetime.timedelta(seconds=f)
 
         elif tokenH == 0x40:  # data
             s = self._get_size(tokenL)
index 09b8897..7bb4d59 100644 (file)
@@ -372,7 +372,7 @@ symbolic links encountered in the path."""
     path, ok = _joinrealpath(filename[:0], filename, {})
     return abspath(path)
 
-# Join two paths, normalizing ang eliminating any symbolic links
+# Join two paths, normalizing and eliminating any symbolic links
 # encountered in the second path.
 def _joinrealpath(path, rest, seen):
     if isinstance(path, bytes):
index 87649b4..bcf2eed 100644 (file)
@@ -72,7 +72,7 @@ def isrecursive(object):
 class _safe_key:
     """Helper function for key functions when sorting unorderable objects.
 
-    The wrapped-object will fallback to an Py2.x style comparison for
+    The wrapped-object will fallback to a Py2.x style comparison for
     unorderable types (sorting first comparing the type name and then by
     the obj ids).  Does not work recursively, so dict.items() must have
     _safe_key applied to both the key and the value.
index dd58ada..4d40b87 100644 (file)
@@ -142,10 +142,10 @@ def _readmodule(module, path, inpackage=None):
         search_path = path + sys.path
     # XXX This will change once issue19944 lands.
     spec = importlib.util._find_spec_from_path(fullmodule, search_path)
-    fname = spec.loader.get_filename(fullmodule)
     _modules[fullmodule] = dict
-    if spec.loader.is_package(fullmodule):
-        dict['__path__'] = [os.path.dirname(fname)]
+    # is module a package?
+    if spec.submodule_search_locations is not None:
+        dict['__path__'] = spec.submodule_search_locations
     try:
         source = spec.loader.get_source(fullmodule)
         if source is None:
@@ -154,6 +154,8 @@ def _readmodule(module, path, inpackage=None):
         # not Python source, can't do anything with this module
         return dict
 
+    fname = spec.loader.get_filename(fullmodule)
+
     f = io.StringIO(source)
 
     stack = [] # stack of (class, indent) pairs
index a9c04f0..3ca08c9 100755 (executable)
@@ -354,7 +354,7 @@ def safeimport(path, forceload=0, cache={}):
 class Doc:
 
     PYTHONDOCS = os.environ.get("PYTHONDOCS",
-                                "http://docs.python.org/%d.%d/library"
+                                "https://docs.python.org/%d.%d/library"
                                 % sys.version_info[:2])
 
     def document(self, object, name=None, *args):
@@ -383,7 +383,9 @@ class Doc:
 
     docmodule = docclass = docroutine = docother = docproperty = docdata = fail
 
-    def getdocloc(self, object):
+    def getdocloc(self, object,
+                  basedir=os.path.join(sys.base_exec_prefix, "lib",
+                                       "python%d.%d" %  sys.version_info[:2])):
         """Return the location of module docs or None"""
 
         try:
@@ -393,8 +395,6 @@ class Doc:
 
         docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)
 
-        basedir = os.path.join(sys.base_exec_prefix, "lib",
-                               "python%d.%d" %  sys.version_info[:2])
         if (isinstance(object, type(os)) and
             (object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
                                  'marshal', 'posix', 'signal', 'sys',
@@ -403,9 +403,9 @@ class Doc:
               not file.startswith(os.path.join(basedir, 'site-packages')))) and
             object.__name__ not in ('xml.etree', 'test.pydoc_mod')):
             if docloc.startswith("http://"):
-                docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__)
+                docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__.lower())
             else:
-                docloc = os.path.join(docloc, object.__name__ + ".html")
+                docloc = os.path.join(docloc, object.__name__.lower() + ".html")
         else:
             docloc = None
         return docloc
index 250bfd3..d6f1366 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Sat Dec  5 17:02:49 2015
-topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n   assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, "assert expression", is equivalent to\n\n   if __debug__:\n      if not expression: raise AssertionError\n\nThe extended form, "assert expression1, expression2", is equivalent to\n\n   if __debug__:\n      if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that "__debug__" and "AssertionError" refer\nto the built-in variables with those names.  In the current\nimplementation, the built-in variable "__debug__" is "True" under\nnormal circumstances, "False" when optimization is requested (command\nline option -O).  The current code generator emits no code for an\nassert statement when optimization is requested at compile time.  Note\nthat it is unnecessary to include the source code for the expression\nthat failed in the error message; it will be displayed as part of the\nstack trace.\n\nAssignments to "__debug__" are illegal.  The value for the built-in\nvariable is determined when the interpreter starts.\n',
- 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n   assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n   target_list     ::= target ("," target)* [","]\n   target          ::= identifier\n              | "(" target_list ")"\n              | "[" target_list "]"\n              | attributeref\n              | subscription\n              | slicing\n              | "*" target\n\n(See section *Primaries* for the syntax definitions for\n*attributeref*, *subscription*, and *slicing*.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable.  The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n  that target.\n\n* If the target list is a comma-separated list of targets: The\n  object must be an iterable with the same number of items as there\n  are targets in the target list, and the items are assigned, from\n  left to right, to the corresponding targets.\n\n  * If the target list contains one target prefixed with an\n    asterisk, called a "starred" target: The object must be a sequence\n    with at least as many items as there are targets in the target\n    list, minus one.  The first items of the sequence are assigned,\n    from left to right, to the targets before the starred target.  The\n    final items of the sequence are assigned to the targets after the\n    starred target.  A list of the remaining items in the sequence is\n    then assigned to the starred target (the list can be empty).\n\n  * Else: The object must be a sequence with the same number of\n    items as there are targets in the target list, and the items are\n    assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n  * If the name does not occur in a "global" or "nonlocal" statement\n    in the current code block: the name is bound to the object in the\n    current local namespace.\n\n  * Otherwise: the name is bound to the object in the global\n    namespace or the outer namespace determined by "nonlocal",\n    respectively.\n\n  The name is rebound if it was already bound.  This may cause the\n  reference count for the object previously bound to the name to reach\n  zero, causing the object to be deallocated and its destructor (if it\n  has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in\n  square brackets: The object must be an iterable with the same number\n  of items as there are targets in the target list, and its items are\n  assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n  the reference is evaluated.  It should yield an object with\n  assignable attributes; if this is not the case, "TypeError" is\n  raised.  That object is then asked to assign the assigned object to\n  the given attribute; if it cannot perform the assignment, it raises\n  an exception (usually but not necessarily "AttributeError").\n\n  Note: If the object is a class instance and the attribute reference\n  occurs on both sides of the assignment operator, the RHS expression,\n  "a.x" can access either an instance attribute or (if no instance\n  attribute exists) a class attribute.  The LHS target "a.x" is always\n  set as an instance attribute, creating it if necessary.  Thus, the\n  two occurrences of "a.x" do not necessarily refer to the same\n  attribute: if the RHS expression refers to a class attribute, the\n  LHS creates a new instance attribute as the target of the\n  assignment:\n\n     class Cls:\n         x = 3             # class variable\n     inst = Cls()\n     inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3\n\n  This description does not necessarily apply to descriptor\n  attributes, such as properties created with "property()".\n\n* If the target is a subscription: The primary expression in the\n  reference is evaluated.  It should yield either a mutable sequence\n  object (such as a list) or a mapping object (such as a dictionary).\n  Next, the subscript expression is evaluated.\n\n  If the primary is a mutable sequence object (such as a list), the\n  subscript must yield an integer.  If it is negative, the sequence\'s\n  length is added to it.  The resulting value must be a nonnegative\n  integer less than the sequence\'s length, and the sequence is asked\n  to assign the assigned object to its item with that index.  If the\n  index is out of range, "IndexError" is raised (assignment to a\n  subscripted sequence cannot add new items to a list).\n\n  If the primary is a mapping object (such as a dictionary), the\n  subscript must have a type compatible with the mapping\'s key type,\n  and the mapping is then asked to create a key/datum pair which maps\n  the subscript to the assigned object.  This can either replace an\n  existing key/value pair with the same key value, or insert a new\n  key/value pair (if no key with the same value existed).\n\n  For user-defined objects, the "__setitem__()" method is called with\n  appropriate arguments.\n\n* If the target is a slicing: The primary expression in the\n  reference is evaluated.  It should yield a mutable sequence object\n  (such as a list).  The assigned object should be a sequence object\n  of the same type.  Next, the lower and upper bound expressions are\n  evaluated, insofar they are present; defaults are zero and the\n  sequence\'s length.  The bounds should evaluate to integers. If\n  either bound is negative, the sequence\'s length is added to it.  The\n  resulting bounds are clipped to lie between zero and the sequence\'s\n  length, inclusive.  Finally, the sequence object is asked to replace\n  the slice with the items of the assigned sequence.  The length of\n  the slice may be different from the length of the assigned sequence,\n  thus changing the length of the target sequence, if the target\n  sequence allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nAlthough the definition of assignment implies that overlaps between\nthe left-hand side and the right-hand side are \'simultanenous\' (for\nexample "a, b = b, a" swaps two variables), overlaps *within* the\ncollection of assigned-to variables occur left-to-right, sometimes\nresulting in confusion.  For instance, the following program prints\n"[0, 2]":\n\n   x = [0, 1]\n   i = 0\n   i, x[i] = 1, 2         # i is updated, then x[i] is updated\n   print(x)\n\nSee also: **PEP 3132** - Extended Iterable Unpacking\n\n     The specification for the "*target" feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n   augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n   augtarget                 ::= identifier | attributeref | subscription | slicing\n   augop                     ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="\n             | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions of the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nUnlike normal assignments, augmented assignments evaluate the left-\nhand side *before* evaluating the right-hand side.  For example, "a[i]\n+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs\nthe addition, and lastly, it writes the result back to "a[i]".\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n',
+# Autogenerated by Sphinx on Sat Jun 25 14:08:44 2016
+topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n   assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, "assert expression", is equivalent to\n\n   if __debug__:\n       if not expression: raise AssertionError\n\nThe extended form, "assert expression1, expression2", is equivalent to\n\n   if __debug__:\n       if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that "__debug__" and "AssertionError" refer\nto the built-in variables with those names.  In the current\nimplementation, the built-in variable "__debug__" is "True" under\nnormal circumstances, "False" when optimization is requested (command\nline option -O).  The current code generator emits no code for an\nassert statement when optimization is requested at compile time.  Note\nthat it is unnecessary to include the source code for the expression\nthat failed in the error message; it will be displayed as part of the\nstack trace.\n\nAssignments to "__debug__" are illegal.  The value for the built-in\nvariable is determined when the interpreter starts.\n',
+ 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n   assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)\n   target_list     ::= target ("," target)* [","]\n   target          ::= identifier\n              | "(" target_list ")"\n              | "[" [target_list] "]"\n              | attributeref\n              | subscription\n              | slicing\n              | "*" target\n\n(See section *Primaries* for the syntax definitions for\n*attributeref*, *subscription*, and *slicing*.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable.  The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is empty: The object must also be an empty\n  iterable.\n\n* If the target list is a single target in parentheses: The object\n  is assigned to that target.\n\n* If the target list is a comma-separated list of targets, or a\n  single target in square brackets: The object must be an iterable\n  with the same number of items as there are targets in the target\n  list, and the items are assigned, from left to right, to the\n  corresponding targets.\n\n  * If the target list contains one target prefixed with an\n    asterisk, called a "starred" target: The object must be an\n    iterable with at least as many items as there are targets in the\n    target list, minus one.  The first items of the iterable are\n    assigned, from left to right, to the targets before the starred\n    target.  The final items of the iterable are assigned to the\n    targets after the starred target.  A list of the remaining items\n    in the iterable is then assigned to the starred target (the list\n    can be empty).\n\n  * Else: The object must be an iterable with the same number of\n    items as there are targets in the target list, and the items are\n    assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n  * If the name does not occur in a "global" or "nonlocal" statement\n    in the current code block: the name is bound to the object in the\n    current local namespace.\n\n  * Otherwise: the name is bound to the object in the global\n    namespace or the outer namespace determined by "nonlocal",\n    respectively.\n\n  The name is rebound if it was already bound.  This may cause the\n  reference count for the object previously bound to the name to reach\n  zero, causing the object to be deallocated and its destructor (if it\n  has one) to be called.\n\n* If the target is an attribute reference: The primary expression in\n  the reference is evaluated.  It should yield an object with\n  assignable attributes; if this is not the case, "TypeError" is\n  raised.  That object is then asked to assign the assigned object to\n  the given attribute; if it cannot perform the assignment, it raises\n  an exception (usually but not necessarily "AttributeError").\n\n  Note: If the object is a class instance and the attribute reference\n  occurs on both sides of the assignment operator, the RHS expression,\n  "a.x" can access either an instance attribute or (if no instance\n  attribute exists) a class attribute.  The LHS target "a.x" is always\n  set as an instance attribute, creating it if necessary.  Thus, the\n  two occurrences of "a.x" do not necessarily refer to the same\n  attribute: if the RHS expression refers to a class attribute, the\n  LHS creates a new instance attribute as the target of the\n  assignment:\n\n     class Cls:\n         x = 3             # class variable\n     inst = Cls()\n     inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3\n\n  This description does not necessarily apply to descriptor\n  attributes, such as properties created with "property()".\n\n* If the target is a subscription: The primary expression in the\n  reference is evaluated.  It should yield either a mutable sequence\n  object (such as a list) or a mapping object (such as a dictionary).\n  Next, the subscript expression is evaluated.\n\n  If the primary is a mutable sequence object (such as a list), the\n  subscript must yield an integer.  If it is negative, the sequence\'s\n  length is added to it.  The resulting value must be a nonnegative\n  integer less than the sequence\'s length, and the sequence is asked\n  to assign the assigned object to its item with that index.  If the\n  index is out of range, "IndexError" is raised (assignment to a\n  subscripted sequence cannot add new items to a list).\n\n  If the primary is a mapping object (such as a dictionary), the\n  subscript must have a type compatible with the mapping\'s key type,\n  and the mapping is then asked to create a key/datum pair which maps\n  the subscript to the assigned object.  This can either replace an\n  existing key/value pair with the same key value, or insert a new\n  key/value pair (if no key with the same value existed).\n\n  For user-defined objects, the "__setitem__()" method is called with\n  appropriate arguments.\n\n* If the target is a slicing: The primary expression in the\n  reference is evaluated.  It should yield a mutable sequence object\n  (such as a list).  The assigned object should be a sequence object\n  of the same type.  Next, the lower and upper bound expressions are\n  evaluated, insofar they are present; defaults are zero and the\n  sequence\'s length.  The bounds should evaluate to integers. If\n  either bound is negative, the sequence\'s length is added to it.  The\n  resulting bounds are clipped to lie between zero and the sequence\'s\n  length, inclusive.  Finally, the sequence object is asked to replace\n  the slice with the items of the assigned sequence.  The length of\n  the slice may be different from the length of the assigned sequence,\n  thus changing the length of the target sequence, if the target\n  sequence allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nAlthough the definition of assignment implies that overlaps between\nthe left-hand side and the right-hand side are \'simultaneous\' (for\nexample "a, b = b, a" swaps two variables), overlaps *within* the\ncollection of assigned-to variables occur left-to-right, sometimes\nresulting in confusion.  For instance, the following program prints\n"[0, 2]":\n\n   x = [0, 1]\n   i = 0\n   i, x[i] = 1, 2         # i is updated, then x[i] is updated\n   print(x)\n\nSee also: **PEP 3132** - Extended Iterable Unpacking\n\n     The specification for the "*target" feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n   augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n   augtarget                 ::= identifier | attributeref | subscription | slicing\n   augop                     ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="\n             | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions of the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nUnlike normal assignments, augmented assignments evaluate the left-\nhand side *before* evaluating the right-hand side.  For example, "a[i]\n+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs\nthe addition, and lastly, it writes the result back to "a[i]".\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n',
  'atom-identifiers': u'\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name.  See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a "NameError" exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them.  The transformation inserts the\nclass name, with leading underscores removed and a single underscore\ninserted, in front of the name.  For example, the identifier "__spam"\noccurring in a class named "Ham" will be transformed to "_Ham__spam".\nThis transformation is independent of the syntactical context in which\nthe identifier is used.  If the transformed name is extremely long\n(longer than 255 characters), implementation defined truncation may\nhappen. If the class name consists only of underscores, no\ntransformation is done.\n',
  'atom-literals': u"\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n   literal ::= stringliteral | bytesliteral\n               | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue.  The value may be approximated in the case of floating point\nand imaginary (complex) literals.  See section *Literals* for details.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value.  Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n",
  'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n   Called when an attribute lookup has not found the attribute in the\n   usual places (i.e. it is not an instance attribute nor is it found\n   in the class tree for "self").  "name" is the attribute name. This\n   method should return the (computed) attribute value or raise an\n   "AttributeError" exception.\n\n   Note that if the attribute is found through the normal mechanism,\n   "__getattr__()" is not called.  (This is an intentional asymmetry\n   between "__getattr__()" and "__setattr__()".) This is done both for\n   efficiency reasons and because otherwise "__getattr__()" would have\n   no way to access other attributes of the instance.  Note that at\n   least for instance variables, you can fake total control by not\n   inserting any values in the instance attribute dictionary (but\n   instead inserting them in another object).  See the\n   "__getattribute__()" method below for a way to actually get total\n   control over attribute access.\n\nobject.__getattribute__(self, name)\n\n   Called unconditionally to implement attribute accesses for\n   instances of the class. If the class also defines "__getattr__()",\n   the latter will not be called unless "__getattribute__()" either\n   calls it explicitly or raises an "AttributeError". This method\n   should return the (computed) attribute value or raise an\n   "AttributeError" exception. In order to avoid infinite recursion in\n   this method, its implementation should always call the base class\n   method with the same name to access any attributes it needs, for\n   example, "object.__getattribute__(self, name)".\n\n   Note: This method may still be bypassed when looking up special\n     methods as the result of implicit invocation via language syntax\n     or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n   Called when an attribute assignment is attempted.  This is called\n   instead of the normal mechanism (i.e. store the value in the\n   instance dictionary). *name* is the attribute name, *value* is the\n   value to be assigned to it.\n\n   If "__setattr__()" wants to assign to an instance attribute, it\n   should call the base class method with the same name, for example,\n   "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n   Like "__setattr__()" but for attribute deletion instead of\n   assignment.  This should only be implemented if "del obj.name" is\n   meaningful for the object.\n\nobject.__dir__(self)\n\n   Called when "dir()" is called on the object. A sequence must be\n   returned. "dir()" converts the returned sequence to a list and\n   sorts it.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents).  In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n   Called to get the attribute of the owner class (class attribute\n   access) or of an instance of that class (instance attribute\n   access). *owner* is always the owner class, while *instance* is the\n   instance that the attribute was accessed through, or "None" when\n   the attribute is accessed through the *owner*.  This method should\n   return the (computed) attribute value or raise an "AttributeError"\n   exception.\n\nobject.__set__(self, instance, value)\n\n   Called to set the attribute on an instance *instance* of the owner\n   class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n   Called to delete the attribute on an instance *instance* of the\n   owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol:  "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead.  Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n   The simplest and least common call is when user code directly\n   invokes a descriptor method:    "x.__get__(a)".\n\nInstance Binding\n   If binding to an object instance, "a.x" is transformed into the\n   call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n   If binding to a class, "A.x" is transformed into the call:\n   "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n   If "a" is an instance of "super", then the binding "super(B,\n   obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n   immediately preceding "B" and then invokes the descriptor with the\n   call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined.  A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()".  If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary.  If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor.  Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method.  Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary.  In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors.  Accordingly, instances can\nredefine and override methods.  This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of classes have a dictionary for attribute\nstorage.  This wastes space for objects having very few instance\nvariables.  The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable.  Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n   This class variable can be assigned a string, iterable, or sequence\n   of strings with variable names used by instances.  *__slots__*\n   reserves space for the declared variables and prevents the\n   automatic creation of *__dict__* and *__weakref__* for each\n   instance.\n\n\nNotes on using *__slots__*\n--------------------------\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n  attribute of that class will always be accessible, so a *__slots__*\n  definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n  variables not listed in the *__slots__* definition.  Attempts to\n  assign to an unlisted variable name raises "AttributeError". If\n  dynamic assignment of new variables is desired, then add\n  "\'__dict__\'" to the sequence of strings in the *__slots__*\n  declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n  defining *__slots__* do not support weak references to its\n  instances. If weak reference support is needed, then add\n  "\'__weakref__\'" to the sequence of strings in the *__slots__*\n  declaration.\n\n* *__slots__* are implemented at the class level by creating\n  descriptors (*Implementing Descriptors*) for each variable name.  As\n  a result, class attributes cannot be used to set default values for\n  instance variables defined by *__slots__*; otherwise, the class\n  attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n  where it is defined.  As a result, subclasses will have a *__dict__*\n  unless they also define *__slots__* (which must only contain names\n  of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n  instance variable defined by the base class slot is inaccessible\n  (except by retrieving its descriptor directly from the base class).\n  This renders the meaning of the program undefined.  In the future, a\n  check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n  "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n  may also be used; however, in the future, special meaning may be\n  assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n  *__slots__*.\n',
@@ -16,36 +16,36 @@ topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert
  'booleans': u'\nBoolean operations\n******************\n\n   or_test  ::= and_test | or_test "or" and_test\n   and_test ::= not_test | and_test "and" not_test\n   not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: "False", "None", numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets).  All other values are interpreted\nas true.  User-defined objects can customize their truth value by\nproviding a "__bool__()" method.\n\nThe operator "not" yields "True" if its argument is false, "False"\notherwise.\n\nThe expression "x and y" first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression "x or y" first evaluates *x*; if *x* is true, its value\nis returned; otherwise, *y* is evaluated and the resulting value is\nreturned.\n\n(Note that neither "and" nor "or" restrict the value and type they\nreturn to "False" and "True", but rather return the last evaluated\nargument.  This is sometimes useful, e.g., if "s" is a string that\nshould be replaced by a default value if it is empty, the expression\n"s or \'foo\'" yields the desired value.  Because "not" has to create a\nnew value, it returns a boolean value regardless of the type of its\nargument (for example, "not \'foo\'" produces "False" rather than "\'\'".)\n',
  'break': u'\nThe "break" statement\n*********************\n\n   break_stmt ::= "break"\n\n"break" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition within that\nloop.\n\nIt terminates the nearest enclosing loop, skipping the optional "else"\nclause if the loop has one.\n\nIf a "for" loop is terminated by "break", the loop control target\nkeeps its current value.\n\nWhen "break" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nloop.\n',
  'callable-types': u'\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n   Called when the instance is "called" as a function; if this method\n   is defined, "x(arg1, arg2, ...)" is a shorthand for\n   "x.__call__(arg1, arg2, ...)".\n',
- 'calls': u'\nCalls\n*****\n\nA call calls a callable object (e.g., a *function*) with a possibly\nempty series of *arguments*:\n\n   call                 ::= primary "(" [argument_list [","] | comprehension] ")"\n   argument_list        ::= positional_arguments ["," keyword_arguments]\n                       ["," "*" expression] ["," keyword_arguments]\n                       ["," "**" expression]\n                     | keyword_arguments ["," "*" expression]\n                       ["," keyword_arguments] ["," "**" expression]\n                     | "*" expression ["," keyword_arguments] ["," "**" expression]\n                     | "**" expression\n   positional_arguments ::= expression ("," expression)*\n   keyword_arguments    ::= keyword_item ("," keyword_item)*\n   keyword_item         ::= identifier "=" expression\n\nAn optional trailing comma may be present after the positional and\nkeyword arguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n"__call__()" method are callable).  All argument expressions are\nevaluated before the call is attempted.  Please refer to section\n*Function definitions* for the syntax of formal *parameter* lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows.  First, a list of unfilled slots is\ncreated for the formal parameters.  If there are N positional\narguments, they are placed in the first N slots.  Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on).  If the slot is\nalready filled, a "TypeError" exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is "None", it fills the slot).  When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition.  (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.)  If there are any\nunfilled slots for which no default value is specified, a "TypeError"\nexception is raised.  Otherwise, the list of filled slots is used as\nthe argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword.  In CPython, this is the case\nfor functions implemented in C that use "PyArg_ParseTuple()" to parse\ntheir arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "*identifier" is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "**identifier" is present; in this case, that formal\nparameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax "*expression" appears in the function call, "expression"\nmust evaluate to an iterable.  Elements from this iterable are treated\nas if they were additional positional arguments; if there are\npositional arguments *x1*, ..., *xN*, and "expression" evaluates to a\nsequence *y1*, ..., *yM*, this is equivalent to a call with M+N\npositional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the "*expression" syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the "**expression" argument, if any -- see\nbelow).  So:\n\n   >>> def f(a, b):\n   ...  print(a, b)\n   ...\n   >>> f(b=1, *(2,))\n   2 1\n   >>> f(a=1, *(2,))\n   Traceback (most recent call last):\n     File "<stdin>", line 1, in ?\n   TypeError: f() got multiple values for keyword argument \'a\'\n   >>> f(1, *(2,))\n   1 2\n\nIt is unusual for both keyword arguments and the "*expression" syntax\nto be used in the same call, so in practice this confusion does not\narise.\n\nIf the syntax "**expression" appears in the function call,\n"expression" must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments.  In the case of a keyword\nappearing in both "expression" and as an explicit keyword argument, a\n"TypeError" exception is raised.\n\nFormal parameters using the syntax "*identifier" or "**identifier"\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly "None", unless it raises an\nexception.  How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n   The code block for the function is executed, passing it the\n   argument list.  The first thing the code block will do is bind the\n   formal parameters to the arguments; this is described in section\n   *Function definitions*.  When the code block executes a "return"\n   statement, this specifies the return value of the function call.\n\na built-in function or method:\n   The result is up to the interpreter; see *Built-in Functions* for\n   the descriptions of built-in functions and methods.\n\na class object:\n   A new instance of that class is returned.\n\na class instance method:\n   The corresponding user-defined function is called, with an argument\n   list that is one longer than the argument list of the call: the\n   instance becomes the first argument.\n\na class instance:\n   The class must define a "__call__()" method; the effect is then the\n   same as if that method was called.\n',
- 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n   classdef    ::= [decorators] "class" classname [inheritance] ":" suite\n   inheritance ::= "(" [parameter_list] ")"\n   classname   ::= identifier\n\nA class definition is an executable statement.  The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.  Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n   class Foo:\n       pass\n\nis equivalent to\n\n   class Foo(object):\n       pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.)  When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n   @f1(arg)\n   @f2\n   class Foo: pass\n\nis equivalent to\n\n   class Foo: pass\n   Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators.  The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances.  Instance attributes\ncan be set in a method with "self.name = value".  Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way.  Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results.  *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n  Class Decorators\n',
+ 'calls': u'\nCalls\n*****\n\nA call calls a callable object (e.g., a *function*) with a possibly\nempty series of *arguments*:\n\n   call                 ::= primary "(" [argument_list [","] | comprehension] ")"\n   argument_list        ::= positional_arguments ["," starred_and_keywords]\n                       ["," keywords_arguments]\n                     | starred_and_keywords ["," keywords_arguments]\n                     | keywords_arguments\n   positional_arguments ::= ["*"] expression ("," ["*"] expression)*\n   starred_and_keywords ::= ("*" expression | keyword_item)\n                            ("," "*" expression | "," keyword_item)*\n   keywords_arguments   ::= (keyword_item | "**" expression)\n                          ("," keyword_item | "**" expression)*\n   keyword_item         ::= identifier "=" expression\n\nAn optional trailing comma may be present after the positional and\nkeyword arguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n"__call__()" method are callable).  All argument expressions are\nevaluated before the call is attempted.  Please refer to section\n*Function definitions* for the syntax of formal *parameter* lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows.  First, a list of unfilled slots is\ncreated for the formal parameters.  If there are N positional\narguments, they are placed in the first N slots.  Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on).  If the slot is\nalready filled, a "TypeError" exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is "None", it fills the slot).  When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition.  (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.)  If there are any\nunfilled slots for which no default value is specified, a "TypeError"\nexception is raised.  Otherwise, the list of filled slots is used as\nthe argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword.  In CPython, this is the case\nfor functions implemented in C that use "PyArg_ParseTuple()" to parse\ntheir arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "*identifier" is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "**identifier" is present; in this case, that formal\nparameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax "*expression" appears in the function call, "expression"\nmust evaluate to an *iterable*.  Elements from these iterables are\ntreated as if they were additional positional arguments.  For the call\n"f(x1, x2, *y, x3, x4)", if *y* evaluates to a sequence *y1*, ...,\n*yM*, this is equivalent to a call with M+4 positional arguments *x1*,\n*x2*, *y1*, ..., *yM*, *x3*, *x4*.\n\nA consequence of this is that although the "*expression" syntax may\nappear *after* explicit keyword arguments, it is processed *before*\nthe keyword arguments (and any "**expression" arguments -- see below).\nSo:\n\n   >>> def f(a, b):\n   ...     print(a, b)\n   ...\n   >>> f(b=1, *(2,))\n   2 1\n   >>> f(a=1, *(2,))\n   Traceback (most recent call last):\n     File "<stdin>", line 1, in ?\n   TypeError: f() got multiple values for keyword argument \'a\'\n   >>> f(1, *(2,))\n   1 2\n\nIt is unusual for both keyword arguments and the "*expression" syntax\nto be used in the same call, so in practice this confusion does not\narise.\n\nIf the syntax "**expression" appears in the function call,\n"expression" must evaluate to a *mapping*, the contents of which are\ntreated as additional keyword arguments.  If a keyword is already\npresent (as an explicit keyword argument, or from another unpacking),\na "TypeError" exception is raised.\n\nFormal parameters using the syntax "*identifier" or "**identifier"\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nChanged in version 3.5: Function calls accept any number of "*" and\n"**" unpackings, positional arguments may follow iterable unpackings\n("*"), and keyword arguments may follow dictionary unpackings ("**").\nOriginally proposed by **PEP 448**.\n\nA call always returns some value, possibly "None", unless it raises an\nexception.  How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n   The code block for the function is executed, passing it the\n   argument list.  The first thing the code block will do is bind the\n   formal parameters to the arguments; this is described in section\n   *Function definitions*.  When the code block executes a "return"\n   statement, this specifies the return value of the function call.\n\na built-in function or method:\n   The result is up to the interpreter; see *Built-in Functions* for\n   the descriptions of built-in functions and methods.\n\na class object:\n   A new instance of that class is returned.\n\na class instance method:\n   The corresponding user-defined function is called, with an argument\n   list that is one longer than the argument list of the call: the\n   instance becomes the first argument.\n\na class instance:\n   The class must define a "__call__()" method; the effect is then the\n   same as if that method was called.\n',
+ 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n   classdef    ::= [decorators] "class" classname [inheritance] ":" suite\n   inheritance ::= "(" [argument_list] ")"\n   classname   ::= identifier\n\nA class definition is an executable statement.  The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.  Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n   class Foo:\n       pass\n\nis equivalent to\n\n   class Foo(object):\n       pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.)  When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n   @f1(arg)\n   @f2\n   class Foo: pass\n\nis equivalent to\n\n   class Foo: pass\n   Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators.  The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances.  Instance attributes\ncan be set in a method with "self.name = value".  Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way.  Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results.  *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n  Class Decorators\n',
  'comparisons': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation.  Also unlike C, expressions like "a < b < c" have the\ninterpretation that is conventional in mathematics:\n\n   comparison    ::= or_expr ( comp_operator or_expr )*\n   comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n                     | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: "True" or "False".\n\nComparisons can be chained arbitrarily, e.g., "x < y <= z" is\nequivalent to "x < y and y <= z", except that "y" is evaluated only\nonce (but in both cases "z" is not evaluated at all when "x < y" is\nfound to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... y\nopN z" is equivalent to "a op1 b and b op2 c and ... y opN z", except\nthat each expression is evaluated at most once.\n\nNote that "a op1 b op2 c" doesn\'t imply any kind of comparison between\n*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\nperhaps not pretty).\n\n\nValue comparisons\n=================\n\nThe operators "<", ">", "==", ">=", "<=", and "!=" compare the values\nof two objects.  The objects do not need to have the same type.\n\nChapter *Objects, values and types* states that objects have a value\n(in addition to type and identity).  The value of an object is a\nrather abstract notion in Python: For example, there is no canonical\naccess method for an object\'s value.  Also, there is no requirement\nthat the value of an object should be constructed in a particular way,\ne.g. comprised of all its data attributes. Comparison operators\nimplement a particular notion of what the value of an object is.  One\ncan think of them as defining the value of an object indirectly, by\nmeans of their comparison implementation.\n\nBecause all types are (direct or indirect) subtypes of "object", they\ninherit the default comparison behavior from "object".  Types can\ncustomize their comparison behavior by implementing *rich comparison\nmethods* like "__lt__()", described in *Basic customization*.\n\nThe default behavior for equality comparison ("==" and "!=") is based\non the identity of the objects.  Hence, equality comparison of\ninstances with the same identity results in equality, and equality\ncomparison of instances with different identities results in\ninequality.  A motivation for this default behavior is the desire that\nall objects should be reflexive (i.e. "x is y" implies "x == y").\n\nA default order comparison ("<", ">", "<=", and ">=") is not provided;\nan attempt raises "TypeError".  A motivation for this default behavior\nis the lack of a similar invariant as for equality.\n\nThe behavior of the default equality comparison, that instances with\ndifferent identities are always unequal, may be in contrast to what\ntypes will need that have a sensible definition of object value and\nvalue-based equality.  Such types will need to customize their\ncomparison behavior, and in fact, a number of built-in types have done\nthat.\n\nThe following list describes the comparison behavior of the most\nimportant built-in types.\n\n* Numbers of built-in numeric types (*Numeric Types --- int, float,\n  complex*) and of the standard library types "fractions.Fraction" and\n  "decimal.Decimal" can be compared within and across their types,\n  with the restriction that complex numbers do not support order\n  comparison.  Within the limits of the types involved, they compare\n  mathematically (algorithmically) correct without loss of precision.\n\n  The not-a-number values "float(\'NaN\')" and "Decimal(\'NaN\')" are\n  special.  They are identical to themselves ("x is x" is true) but\n  are not equal to themselves ("x == x" is false).  Additionally,\n  comparing any number to a not-a-number value will return "False".\n  For example, both "3 < float(\'NaN\')" and "float(\'NaN\') < 3" will\n  return "False".\n\n* Binary sequences (instances of "bytes" or "bytearray") can be\n  compared within and across their types.  They compare\n  lexicographically using the numeric values of their elements.\n\n* Strings (instances of "str") compare lexicographically using the\n  numerical Unicode code points (the result of the built-in function\n  "ord()") of their characters. [3]\n\n  Strings and binary sequences cannot be directly compared.\n\n* Sequences (instances of "tuple", "list", or "range") can be\n  compared only within each of their types, with the restriction that\n  ranges do not support order comparison.  Equality comparison across\n  these types results in unequality, and ordering comparison across\n  these types raises "TypeError".\n\n  Sequences compare lexicographically using comparison of\n  corresponding elements, whereby reflexivity of the elements is\n  enforced.\n\n  In enforcing reflexivity of elements, the comparison of collections\n  assumes that for a collection element "x", "x == x" is always true.\n  Based on that assumption, element identity is compared first, and\n  element comparison is performed only for distinct elements.  This\n  approach yields the same result as a strict element comparison\n  would, if the compared elements are reflexive.  For non-reflexive\n  elements, the result is different than for strict element\n  comparison, and may be surprising:  The non-reflexive not-a-number\n  values for example result in the following comparison behavior when\n  used in a list:\n\n     >>> nan = float(\'NaN\')\n     >>> nan is nan\n     True\n     >>> nan == nan\n     False                 <-- the defined non-reflexive behavior of NaN\n     >>> [nan] == [nan]\n     True                  <-- list enforces reflexivity and tests identity first\n\n  Lexicographical comparison between built-in collections works as\n  follows:\n\n  * For two collections to compare equal, they must be of the same\n    type, have the same length, and each pair of corresponding\n    elements must compare equal (for example, "[1,2] == (1,2)" is\n    false because the type is not the same).\n\n  * Collections that support order comparison are ordered the same\n    as their first unequal elements (for example, "[1,2,x] <= [1,2,y]"\n    has the same value as "x <= y").  If a corresponding element does\n    not exist, the shorter collection is ordered first (for example,\n    "[1,2] < [1,2,3]" is true).\n\n* Mappings (instances of "dict") compare equal if and only if they\n  have equal *(key, value)* pairs. Equality comparison of the keys and\n  elements enforces reflexivity.\n\n  Order comparisons ("<", ">", "<=", and ">=") raise "TypeError".\n\n* Sets (instances of "set" or "frozenset") can be compared within\n  and across their types.\n\n  They define order comparison operators to mean subset and superset\n  tests.  Those relations do not define total orderings (for example,\n  the two sets "{1,2}" and "{2,3}" are not equal, nor subsets of one\n  another, nor supersets of one another).  Accordingly, sets are not\n  appropriate arguments for functions which depend on total ordering\n  (for example, "min()", "max()", and "sorted()" produce undefined\n  results given a list of sets as inputs).\n\n  Comparison of sets enforces reflexivity of its elements.\n\n* Most other built-in types have no comparison methods implemented,\n  so they inherit the default comparison behavior.\n\nUser-defined classes that customize their comparison behavior should\nfollow some consistency rules, if possible:\n\n* Equality comparison should be reflexive. In other words, identical\n  objects should compare equal:\n\n     "x is y" implies "x == y"\n\n* Comparison should be symmetric. In other words, the following\n  expressions should have the same result:\n\n     "x == y" and "y == x"\n\n     "x != y" and "y != x"\n\n     "x < y" and "y > x"\n\n     "x <= y" and "y >= x"\n\n* Comparison should be transitive. The following (non-exhaustive)\n  examples illustrate that:\n\n     "x > y and y > z" implies "x > z"\n\n     "x < y and y <= z" implies "x < z"\n\n* Inverse comparison should result in the boolean negation. In other\n  words, the following expressions should have the same result:\n\n     "x == y" and "not x != y"\n\n     "x < y" and "not x >= y" (for total ordering)\n\n     "x > y" and "not x <= y" (for total ordering)\n\n  The last two expressions apply to totally ordered collections (e.g.\n  to sequences, but not to sets or mappings). See also the\n  "total_ordering()" decorator.\n\nPython does not enforce these consistency rules. In fact, the\nnot-a-number values are an example for not following these rules.\n\n\nMembership test operations\n==========================\n\nThe operators "in" and "not in" test for membership.  "x in s"\nevaluates to true if *x* is a member of *s*, and false otherwise.  "x\nnot in s" returns the negation of "x in s".  All built-in sequences\nand set types support this as well as dictionary, for which "in" tests\nwhether the dictionary has a given key. For container types such as\nlist, tuple, set, frozenset, dict, or collections.deque, the\nexpression "x in y" is equivalent to "any(x is e or x == e for e in\ny)".\n\nFor the string and bytes types, "x in y" is true if and only if *x* is\na substring of *y*.  An equivalent test is "y.find(x) != -1".  Empty\nstrings are always considered to be a substring of any other string,\nso """ in "abc"" will return "True".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y".  If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception.  (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n\n\nIdentity comparisons\n====================\n\nThe operators "is" and "is not" test for object identity: "x is y" is\ntrue if and only if *x* and *y* are the same object.  "x is not y"\nyields the inverse truth value. [4]\n',
- 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way.  In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe "if", "while" and "for" statements implement traditional control\nflow constructs.  "try" specifies exception handlers and/or cleanup\ncode for a group of statements, while the "with" statement allows the\nexecution of initialization and finalization code around a block of\ncode.  Function and class definitions are also syntactically compound\nstatements.\n\nA compound statement consists of one or more \'clauses.\'  A clause\nconsists of a header and a \'suite.\'  The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon.  A suite is a group of statements controlled by a\nclause.  A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines.  Only the latter form of a suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which "if" clause a following "else" clause would belong:\n\n   if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n"print()" calls are executed:\n\n   if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n   compound_stmt ::= if_stmt\n                     | while_stmt\n                     | for_stmt\n                     | try_stmt\n                     | with_stmt\n                     | funcdef\n                     | classdef\n                     | async_with_stmt\n                     | async_for_stmt\n                     | async_funcdef\n   suite         ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n   statement     ::= stmt_list NEWLINE | compound_stmt\n   stmt_list     ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a "NEWLINE" possibly followed by a\n"DEDENT".  Also note that optional continuation clauses always begin\nwith a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling "else"\' problem is solved in Python by\nrequiring nested "if" statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe "if" statement\n==================\n\nThe "if" statement is used for conditional execution:\n\n   if_stmt ::= "if" expression ":" suite\n               ( "elif" expression ":" suite )*\n               ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n\n\nThe "while" statement\n=====================\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n   while_stmt ::= "while" expression ":" suite\n                  ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite.  A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n\n\nThe "for" statement\n===================\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n   for_stmt ::= "for" target_list "in" expression_list ":" suite\n                ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject.  An iterator is created for the result of the\n"expression_list".  The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator.  Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted.  When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite.  A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n   for i in range(10):\n       print(i)\n       i = 5             # this will not affect the for-loop\n                         # because i will be overwritten with the next\n                         # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop.  Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n  loop (this can only occur for mutable sequences, i.e. lists).  An\n  internal counter is used to keep track of which item is used next,\n  and this is incremented on each iteration.  When this counter has\n  reached the length of the sequence the loop terminates.  This means\n  that if the suite deletes the current (or a previous) item from the\n  sequence, the next item will be skipped (since it gets the index of\n  the current item which has already been treated).  Likewise, if the\n  suite inserts an item in the sequence before the current item, the\n  current item will be treated again the next time through the loop.\n  This can lead to nasty bugs that can be avoided by making a\n  temporary copy using a slice of the whole sequence, e.g.,\n\n     for x in a[:]:\n         if x < 0: a.remove(x)\n\n\nThe "try" statement\n===================\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n   try_stmt  ::= try1_stmt | try2_stmt\n   try1_stmt ::= "try" ":" suite\n                 ("except" [expression ["as" identifier]] ":" suite)+\n                 ["else" ":" suite]\n                 ["finally" ":" suite]\n   try2_stmt ::= "try" ":" suite\n                 "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started.  This search inspects the except clauses\nin turn until one is found that matches the exception.  An expression-\nless except clause, if present, must be last; it matches any\nexception.  For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception.  An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed.  All except\nclauses must have an executable block.  When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause.  This is as if\n\n   except E as N:\n       foo\n\nwas translated to\n\n   except E as N:\n       try:\n           foo\n       finally:\n           del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause.  Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred.  "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler.  The "try"\nclause is executed, including any "except" and "else" clauses.  If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed.  If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause.  If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n   >>> def f():\n   ...     try:\n   ...         1/0\n   ...     finally:\n   ...         return 42\n   ...\n   >>> f()\n   42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed.  Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n   >>> def foo():\n   ...     try:\n   ...         return \'try\'\n   ...     finally:\n   ...         return \'finally\'\n   ...\n   >>> foo()\n   \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe "with" statement\n====================\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n   with_stmt ::= "with" with_item ("," with_item)* ":" suite\n   with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n   is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n   value from "__enter__()" is assigned to it.\n\n   Note: The "with" statement guarantees that if the "__enter__()"\n     method returns without an error, then "__exit__()" will always be\n     called. Thus, if an error occurs during the assignment to the\n     target list, it will be treated the same as an error occurring\n     within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked.  If an\n   exception caused the suite to be exited, its type, value, and\n   traceback are passed as arguments to "__exit__()". Otherwise, three\n   "None" arguments are supplied.\n\n   If the suite was exited due to an exception, and the return value\n   from the "__exit__()" method was false, the exception is reraised.\n   If the return value was true, the exception is suppressed, and\n   execution continues with the statement following the "with"\n   statement.\n\n   If the suite was exited for any reason other than an exception, the\n   return value from "__exit__()" is ignored, and execution proceeds\n   at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n   with A() as a, B() as b:\n       suite\n\nis equivalent to\n\n   with A() as a:\n       with B() as b:\n           suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n     The specification, background, and examples for the Python "with"\n     statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n   funcdef        ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n   decorators     ::= decorator+\n   decorator      ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n   dotted_name    ::= identifier ("." identifier)*\n   parameter_list ::= (defparameter ",")*\n                      | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n                      | "**" parameter\n                      | defparameter [","] )\n   parameter      ::= identifier [":" expression]\n   defparameter   ::= parameter ["=" expression]\n   funcname       ::= identifier\n\nA function definition is an executable statement.  Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function).  This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition.  The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object.  Multiple decorators are applied in\nnested fashion. For example, the following code\n\n   @f1(arg)\n   @f2\n   def func(): pass\n\nis equivalent to\n\n   def func(): pass\n   func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted.  If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call.  This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended.  A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n   def whats_on_the_telly(penguin=None):\n       if penguin is None:\n           penguin = []\n       penguin.append("property of the zoo")\n       return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values.  If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple.  If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name.  Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier".  Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist.  These annotations can be any valid Python expression and are\nevaluated when the function definition is executed.  Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction.  The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions.  This uses lambda\nexpressions, described in section *Lambdas*.  Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression.  The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects.  A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around.  Free variables used\nin the nested function can access the local variables of the function\ncontaining the def.  See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n     The original specification for function annotations.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n   classdef    ::= [decorators] "class" classname [inheritance] ":" suite\n   inheritance ::= "(" [parameter_list] ")"\n   classname   ::= identifier\n\nA class definition is an executable statement.  The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.  Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n   class Foo:\n       pass\n\nis equivalent to\n\n   class Foo(object):\n       pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.)  When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n   @f1(arg)\n   @f2\n   class Foo: pass\n\nis equivalent to\n\n   class Foo: pass\n   Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators.  The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances.  Instance attributes\ncan be set in a method with "self.name = value".  Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way.  Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results.  *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n  Class Decorators\n\n\nCoroutines\n==========\n\nNew in version 3.5.\n\n\nCoroutine function definition\n-----------------------------\n\n   async_funcdef ::= [decorators] "async" "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n\nExecution of Python coroutines can be suspended and resumed at many\npoints (see *coroutine*).  In the body of a coroutine, any "await" and\n"async" identifiers become reserved keywords; "await" expressions,\n"async for" and "async with" can only be used in coroutine bodies.\n\nFunctions defined with "async def" syntax are always coroutine\nfunctions, even if they do not contain "await" or "async" keywords.\n\nIt is a "SyntaxError" to use "yield" expressions in "async def"\ncoroutines.\n\nAn example of a coroutine function:\n\n   async def func(param1, param2):\n       do_stuff()\n       await some_coroutine()\n\n\nThe "async for" statement\n-------------------------\n\n   async_for_stmt ::= "async" for_stmt\n\nAn *asynchronous iterable* is able to call asynchronous code in its\n*iter* implementation, and *asynchronous iterator* can call\nasynchronous code in its *next* method.\n\nThe "async for" statement allows convenient iteration over\nasynchronous iterators.\n\nThe following code:\n\n   async for TARGET in ITER:\n       BLOCK\n   else:\n       BLOCK2\n\nIs semantically equivalent to:\n\n   iter = (ITER)\n   iter = await type(iter).__aiter__(iter)\n   running = True\n   while running:\n       try:\n           TARGET = await type(iter).__anext__(iter)\n       except StopAsyncIteration:\n           running = False\n       else:\n           BLOCK\n   else:\n       BLOCK2\n\nSee also "__aiter__()" and "__anext__()" for details.\n\nIt is a "SyntaxError" to use "async for" statement outside of an\n"async def" function.\n\n\nThe "async with" statement\n--------------------------\n\n   async_with_stmt ::= "async" with_stmt\n\nAn *asynchronous context manager* is a *context manager* that is able\nto suspend execution in its *enter* and *exit* methods.\n\nThe following code:\n\n   async with EXPR as VAR:\n       BLOCK\n\nIs semantically equivalent to:\n\n   mgr = (EXPR)\n   aexit = type(mgr).__aexit__\n   aenter = type(mgr).__aenter__(mgr)\n   exc = True\n\n   VAR = await aenter\n   try:\n       BLOCK\n   except:\n       if not await aexit(mgr, *sys.exc_info()):\n           raise\n   else:\n       await aexit(mgr, None, None, None)\n\nSee also "__aenter__()" and "__aexit__()" for details.\n\nIt is a "SyntaxError" to use "async with" statement outside of an\n"async def" function.\n\nSee also: **PEP 492** - Coroutines with async and await syntax\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless\n    there is a "finally" clause which happens to raise another\n    exception. That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of\n    an exception or the execution of a "return", "continue", or\n    "break" statement.\n\n[3] A string literal appearing as the first statement in the\n    function body is transformed into the function\'s "__doc__"\n    attribute and therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n    body is transformed into the namespace\'s "__doc__" item and\n    therefore the class\'s *docstring*.\n',
- 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code.  Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n   Enter the runtime context related to this object. The "with"\n   statement will bind this method\'s return value to the target(s)\n   specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n   Exit the runtime context related to this object. The parameters\n   describe the exception that caused the context to be exited. If the\n   context was exited without an exception, all three arguments will\n   be "None".\n\n   If an exception is supplied, and the method wishes to suppress the\n   exception (i.e., prevent it from being propagated), it should\n   return a true value. Otherwise, the exception will be processed\n   normally upon exit from this method.\n\n   Note that "__exit__()" methods should not reraise the passed-in\n   exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n     The specification, background, and examples for the Python "with"\n     statement.\n',
+ 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way.  In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe "if", "while" and "for" statements implement traditional control\nflow constructs.  "try" specifies exception handlers and/or cleanup\ncode for a group of statements, while the "with" statement allows the\nexecution of initialization and finalization code around a block of\ncode.  Function and class definitions are also syntactically compound\nstatements.\n\nA compound statement consists of one or more \'clauses.\'  A clause\nconsists of a header and a \'suite.\'  The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon.  A suite is a group of statements controlled by a\nclause.  A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines.  Only the latter form of a suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which "if" clause a following "else" clause would belong:\n\n   if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n"print()" calls are executed:\n\n   if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n   compound_stmt ::= if_stmt\n                     | while_stmt\n                     | for_stmt\n                     | try_stmt\n                     | with_stmt\n                     | funcdef\n                     | classdef\n                     | async_with_stmt\n                     | async_for_stmt\n                     | async_funcdef\n   suite         ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n   statement     ::= stmt_list NEWLINE | compound_stmt\n   stmt_list     ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a "NEWLINE" possibly followed by a\n"DEDENT".  Also note that optional continuation clauses always begin\nwith a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling "else"\' problem is solved in Python by\nrequiring nested "if" statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe "if" statement\n==================\n\nThe "if" statement is used for conditional execution:\n\n   if_stmt ::= "if" expression ":" suite\n               ( "elif" expression ":" suite )*\n               ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n\n\nThe "while" statement\n=====================\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n   while_stmt ::= "while" expression ":" suite\n                  ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite.  A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n\n\nThe "for" statement\n===================\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n   for_stmt ::= "for" target_list "in" expression_list ":" suite\n                ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject.  An iterator is created for the result of the\n"expression_list".  The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator.  Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted.  When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite.  A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n   for i in range(10):\n       print(i)\n       i = 5             # this will not affect the for-loop\n                         # because i will be overwritten with the next\n                         # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop.  Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n  loop (this can only occur for mutable sequences, i.e. lists).  An\n  internal counter is used to keep track of which item is used next,\n  and this is incremented on each iteration.  When this counter has\n  reached the length of the sequence the loop terminates.  This means\n  that if the suite deletes the current (or a previous) item from the\n  sequence, the next item will be skipped (since it gets the index of\n  the current item which has already been treated).  Likewise, if the\n  suite inserts an item in the sequence before the current item, the\n  current item will be treated again the next time through the loop.\n  This can lead to nasty bugs that can be avoided by making a\n  temporary copy using a slice of the whole sequence, e.g.,\n\n     for x in a[:]:\n         if x < 0: a.remove(x)\n\n\nThe "try" statement\n===================\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n   try_stmt  ::= try1_stmt | try2_stmt\n   try1_stmt ::= "try" ":" suite\n                 ("except" [expression ["as" identifier]] ":" suite)+\n                 ["else" ":" suite]\n                 ["finally" ":" suite]\n   try2_stmt ::= "try" ":" suite\n                 "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started.  This search inspects the except clauses\nin turn until one is found that matches the exception.  An expression-\nless except clause, if present, must be last; it matches any\nexception.  For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception.  An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed.  All except\nclauses must have an executable block.  When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause.  This is as if\n\n   except E as N:\n       foo\n\nwas translated to\n\n   except E as N:\n       try:\n           foo\n       finally:\n           del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause.  Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred.  "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler.  The "try"\nclause is executed, including any "except" and "else" clauses.  If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed.  If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause.  If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n   >>> def f():\n   ...     try:\n   ...         1/0\n   ...     finally:\n   ...         return 42\n   ...\n   >>> f()\n   42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed.  Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n   >>> def foo():\n   ...     try:\n   ...         return \'try\'\n   ...     finally:\n   ...         return \'finally\'\n   ...\n   >>> foo()\n   \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe "with" statement\n====================\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n   with_stmt ::= "with" with_item ("," with_item)* ":" suite\n   with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n   is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n   value from "__enter__()" is assigned to it.\n\n   Note: The "with" statement guarantees that if the "__enter__()"\n     method returns without an error, then "__exit__()" will always be\n     called. Thus, if an error occurs during the assignment to the\n     target list, it will be treated the same as an error occurring\n     within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked.  If an\n   exception caused the suite to be exited, its type, value, and\n   traceback are passed as arguments to "__exit__()". Otherwise, three\n   "None" arguments are supplied.\n\n   If the suite was exited due to an exception, and the return value\n   from the "__exit__()" method was false, the exception is reraised.\n   If the return value was true, the exception is suppressed, and\n   execution continues with the statement following the "with"\n   statement.\n\n   If the suite was exited for any reason other than an exception, the\n   return value from "__exit__()" is ignored, and execution proceeds\n   at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n   with A() as a, B() as b:\n       suite\n\nis equivalent to\n\n   with A() as a:\n       with B() as b:\n           suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 343** - The "with" statement\n\n     The specification, background, and examples for the Python "with"\n     statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n   funcdef        ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n   decorators     ::= decorator+\n   decorator      ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n   dotted_name    ::= identifier ("." identifier)*\n   parameter_list ::= (defparameter ",")*\n                      | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n                      | "**" parameter\n                      | defparameter [","] )\n   parameter      ::= identifier [":" expression]\n   defparameter   ::= parameter ["=" expression]\n   funcname       ::= identifier\n\nA function definition is an executable statement.  Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function).  This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition.  The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object.  Multiple decorators are applied in\nnested fashion. For example, the following code\n\n   @f1(arg)\n   @f2\n   def func(): pass\n\nis equivalent to\n\n   def func(): pass\n   func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted.  If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call.  This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended.  A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n   def whats_on_the_telly(penguin=None):\n       if penguin is None:\n           penguin = []\n       penguin.append("property of the zoo")\n       return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values.  If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple.  If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name.  Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier".  Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist.  These annotations can be any valid Python expression and are\nevaluated when the function definition is executed.  Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction.  The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions.  This uses lambda\nexpressions, described in section *Lambdas*.  Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression.  The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects.  A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around.  Free variables used\nin the nested function can access the local variables of the function\ncontaining the def.  See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n     The original specification for function annotations.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n   classdef    ::= [decorators] "class" classname [inheritance] ":" suite\n   inheritance ::= "(" [argument_list] ")"\n   classname   ::= identifier\n\nA class definition is an executable statement.  The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.  Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n   class Foo:\n       pass\n\nis equivalent to\n\n   class Foo(object):\n       pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.)  When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n   @f1(arg)\n   @f2\n   class Foo: pass\n\nis equivalent to\n\n   class Foo: pass\n   Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators.  The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances.  Instance attributes\ncan be set in a method with "self.name = value".  Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way.  Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results.  *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n  Class Decorators\n\n\nCoroutines\n==========\n\nNew in version 3.5.\n\n\nCoroutine function definition\n-----------------------------\n\n   async_funcdef ::= [decorators] "async" "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n\nExecution of Python coroutines can be suspended and resumed at many\npoints (see *coroutine*).  In the body of a coroutine, any "await" and\n"async" identifiers become reserved keywords; "await" expressions,\n"async for" and "async with" can only be used in coroutine bodies.\n\nFunctions defined with "async def" syntax are always coroutine\nfunctions, even if they do not contain "await" or "async" keywords.\n\nIt is a "SyntaxError" to use "yield" expressions in "async def"\ncoroutines.\n\nAn example of a coroutine function:\n\n   async def func(param1, param2):\n       do_stuff()\n       await some_coroutine()\n\n\nThe "async for" statement\n-------------------------\n\n   async_for_stmt ::= "async" for_stmt\n\nAn *asynchronous iterable* is able to call asynchronous code in its\n*iter* implementation, and *asynchronous iterator* can call\nasynchronous code in its *next* method.\n\nThe "async for" statement allows convenient iteration over\nasynchronous iterators.\n\nThe following code:\n\n   async for TARGET in ITER:\n       BLOCK\n   else:\n       BLOCK2\n\nIs semantically equivalent to:\n\n   iter = (ITER)\n   iter = type(iter).__aiter__(iter)\n   running = True\n   while running:\n       try:\n           TARGET = await type(iter).__anext__(iter)\n       except StopAsyncIteration:\n           running = False\n       else:\n           BLOCK\n   else:\n       BLOCK2\n\nSee also "__aiter__()" and "__anext__()" for details.\n\nIt is a "SyntaxError" to use "async for" statement outside of an\n"async def" function.\n\n\nThe "async with" statement\n--------------------------\n\n   async_with_stmt ::= "async" with_stmt\n\nAn *asynchronous context manager* is a *context manager* that is able\nto suspend execution in its *enter* and *exit* methods.\n\nThe following code:\n\n   async with EXPR as VAR:\n       BLOCK\n\nIs semantically equivalent to:\n\n   mgr = (EXPR)\n   aexit = type(mgr).__aexit__\n   aenter = type(mgr).__aenter__(mgr)\n   exc = True\n\n   VAR = await aenter\n   try:\n       BLOCK\n   except:\n       if not await aexit(mgr, *sys.exc_info()):\n           raise\n   else:\n       await aexit(mgr, None, None, None)\n\nSee also "__aenter__()" and "__aexit__()" for details.\n\nIt is a "SyntaxError" to use "async with" statement outside of an\n"async def" function.\n\nSee also: **PEP 492** - Coroutines with async and await syntax\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless\n    there is a "finally" clause which happens to raise another\n    exception. That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of\n    an exception or the execution of a "return", "continue", or\n    "break" statement.\n\n[3] A string literal appearing as the first statement in the\n    function body is transformed into the function\'s "__doc__"\n    attribute and therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n    body is transformed into the namespace\'s "__doc__" item and\n    therefore the class\'s *docstring*.\n',
+ 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code.  Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n   Enter the runtime context related to this object. The "with"\n   statement will bind this method\'s return value to the target(s)\n   specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n   Exit the runtime context related to this object. The parameters\n   describe the exception that caused the context to be exited. If the\n   context was exited without an exception, all three arguments will\n   be "None".\n\n   If an exception is supplied, and the method wishes to suppress the\n   exception (i.e., prevent it from being propagated), it should\n   return a true value. Otherwise, the exception will be processed\n   normally upon exit from this method.\n\n   Note that "__exit__()" methods should not reraise the passed-in\n   exception; this is the caller\'s responsibility.\n\nSee also: **PEP 343** - The "with" statement\n\n     The specification, background, and examples for the Python "with"\n     statement.\n',
  'continue': u'\nThe "continue" statement\n************************\n\n   continue_stmt ::= "continue"\n\n"continue" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition or "finally"\nclause within that loop.  It continues with the next cycle of the\nnearest enclosing loop.\n\nWhen "continue" passes control out of a "try" statement with a\n"finally" clause, that "finally" clause is executed before really\nstarting the next loop cycle.\n',
  'conversions': u'\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works as follows:\n\n* If either argument is a complex number, the other is converted to\n  complex;\n\n* otherwise, if either argument is a floating point number, the\n  other is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string as a\nleft argument to the \'%\' operator).  Extensions must define their own\nconversion behavior.\n',
  'customization': u'\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n   Called to create a new instance of class *cls*.  "__new__()" is a\n   static method (special-cased so you need not declare it as such)\n   that takes the class of which an instance was requested as its\n   first argument.  The remaining arguments are those passed to the\n   object constructor expression (the call to the class).  The return\n   value of "__new__()" should be the new object instance (usually an\n   instance of *cls*).\n\n   Typical implementations create a new instance of the class by\n   invoking the superclass\'s "__new__()" method using\n   "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n   arguments and then modifying the newly-created instance as\n   necessary before returning it.\n\n   If "__new__()" returns an instance of *cls*, then the new\n   instance\'s "__init__()" method will be invoked like\n   "__init__(self[, ...])", where *self* is the new instance and the\n   remaining arguments are the same as were passed to "__new__()".\n\n   If "__new__()" does not return an instance of *cls*, then the new\n   instance\'s "__init__()" method will not be invoked.\n\n   "__new__()" is intended mainly to allow subclasses of immutable\n   types (like int, str, or tuple) to customize instance creation.  It\n   is also commonly overridden in custom metaclasses in order to\n   customize class creation.\n\nobject.__init__(self[, ...])\n\n   Called after the instance has been created (by "__new__()"), but\n   before it is returned to the caller.  The arguments are those\n   passed to the class constructor expression.  If a base class has an\n   "__init__()" method, the derived class\'s "__init__()" method, if\n   any, must explicitly call it to ensure proper initialization of the\n   base class part of the instance; for example:\n   "BaseClass.__init__(self, [args...])".\n\n   Because "__new__()" and "__init__()" work together in constructing\n   objects ("__new__()" to create it, and "__init__()" to customise\n   it), no non-"None" value may be returned by "__init__()"; doing so\n   will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n   Called when the instance is about to be destroyed.  This is also\n   called a destructor.  If a base class has a "__del__()" method, the\n   derived class\'s "__del__()" method, if any, must explicitly call it\n   to ensure proper deletion of the base class part of the instance.\n   Note that it is possible (though not recommended!) for the\n   "__del__()" method to postpone destruction of the instance by\n   creating a new reference to it.  It may then be called at a later\n   time when this new reference is deleted.  It is not guaranteed that\n   "__del__()" methods are called for objects that still exist when\n   the interpreter exits.\n\n   Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n     decrements the reference count for "x" by one, and the latter is\n     only called when "x"\'s reference count reaches zero.  Some common\n     situations that may prevent the reference count of an object from\n     going to zero include: circular references between objects (e.g.,\n     a doubly-linked list or a tree data structure with parent and\n     child pointers); a reference to the object on the stack frame of\n     a function that caught an exception (the traceback stored in\n     "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n     to the object on the stack frame that raised an unhandled\n     exception in interactive mode (the traceback stored in\n     "sys.last_traceback" keeps the stack frame alive).  The first\n     situation can only be remedied by explicitly breaking the cycles;\n     the second can be resolved by freeing the reference to the\n     traceback object when it is no longer useful, and the third can\n     be resolved by storing "None" in "sys.last_traceback". Circular\n     references which are garbage are detected and cleaned up when the\n     cyclic garbage collector is enabled (it\'s on by default). Refer\n     to the documentation for the "gc" module for more information\n     about this topic.\n\n   Warning: Due to the precarious circumstances under which\n     "__del__()" methods are invoked, exceptions that occur during\n     their execution are ignored, and a warning is printed to\n     "sys.stderr" instead. Also, when "__del__()" is invoked in\n     response to a module being deleted (e.g., when execution of the\n     program is done), other globals referenced by the "__del__()"\n     method may already have been deleted or in the process of being\n     torn down (e.g. the import machinery shutting down).  For this\n     reason, "__del__()" methods should do the absolute minimum needed\n     to maintain external invariants.  Starting with version 1.5,\n     Python guarantees that globals whose name begins with a single\n     underscore are deleted from their module before other globals are\n     deleted; if no other references to such globals exist, this may\n     help in assuring that imported modules are still available at the\n     time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n   Called by the "repr()" built-in function to compute the "official"\n   string representation of an object.  If at all possible, this\n   should look like a valid Python expression that could be used to\n   recreate an object with the same value (given an appropriate\n   environment).  If this is not possible, a string of the form\n   "<...some useful description...>" should be returned. The return\n   value must be a string object. If a class defines "__repr__()" but\n   not "__str__()", then "__repr__()" is also used when an "informal"\n   string representation of instances of that class is required.\n\n   This is typically used for debugging, so it is important that the\n   representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n   Called by "str(object)" and the built-in functions "format()" and\n   "print()" to compute the "informal" or nicely printable string\n   representation of an object.  The return value must be a *string*\n   object.\n\n   This method differs from "object.__repr__()" in that there is no\n   expectation that "__str__()" return a valid Python expression: a\n   more convenient or concise representation can be used.\n\n   The default implementation defined by the built-in type "object"\n   calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n   Called by "bytes()" to compute a byte-string representation of an\n   object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n   Called by the "format()" built-in function (and by extension, the\n   "str.format()" method of class "str") to produce a "formatted"\n   string representation of an object. The "format_spec" argument is a\n   string that contains a description of the formatting options\n   desired. The interpretation of the "format_spec" argument is up to\n   the type implementing "__format__()", however most classes will\n   either delegate formatting to one of the built-in types, or use a\n   similar formatting option syntax.\n\n   See *Format Specification Mini-Language* for a description of the\n   standard formatting syntax.\n\n   The return value must be a string object.\n\n   Changed in version 3.4: The __format__ method of "object" itself\n   raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n   These are the so-called "rich comparison" methods. The\n   correspondence between operator symbols and method names is as\n   follows: "x<y" calls "x.__lt__(y)", "x<=y" calls "x.__le__(y)",\n   "x==y" calls "x.__eq__(y)", "x!=y" calls "x.__ne__(y)", "x>y" calls\n   "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n   A rich comparison method may return the singleton "NotImplemented"\n   if it does not implement the operation for a given pair of\n   arguments. By convention, "False" and "True" are returned for a\n   successful comparison. However, these methods can return any value,\n   so if the comparison operator is used in a Boolean context (e.g.,\n   in the condition of an "if" statement), Python will call "bool()"\n   on the value to determine if the result is true or false.\n\n   By default, "__ne__()" delegates to "__eq__()" and inverts the\n   result unless it is "NotImplemented".  There are no other implied\n   relationships among the comparison operators, for example, the\n   truth of "(x<y or x==y)" does not imply "x<=y". To automatically\n   generate ordering operations from a single root operation, see\n   "functools.total_ordering()".\n\n   See the paragraph on "__hash__()" for some important notes on\n   creating *hashable* objects which support custom comparison\n   operations and are usable as dictionary keys.\n\n   There are no swapped-argument versions of these methods (to be used\n   when the left argument does not support the operation but the right\n   argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n   reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n   and "__eq__()" and "__ne__()" are their own reflection. If the\n   operands are of different types, and right operand\'s type is a\n   direct or indirect subclass of the left operand\'s type, the\n   reflected method of the right operand has priority, otherwise the\n   left operand\'s method has priority.  Virtual subclassing is not\n   considered.\n\nobject.__hash__(self)\n\n   Called by built-in function "hash()" and for operations on members\n   of hashed collections including "set", "frozenset", and "dict".\n   "__hash__()" should return an integer.  The only required property\n   is that objects which compare equal have the same hash value; it is\n   advised to somehow mix together (e.g. using exclusive or) the hash\n   values for the components of the object that also play a part in\n   comparison of objects.\n\n   Note: "hash()" truncates the value returned from an object\'s\n     custom "__hash__()" method to the size of a "Py_ssize_t".  This\n     is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit\n     builds. If an object\'s   "__hash__()" must interoperate on builds\n     of different bit sizes, be sure to check the width on all\n     supported builds.  An easy way to do this is with "python -c\n     "import sys; print(sys.hash_info.width)"".\n\n   If a class does not define an "__eq__()" method it should not\n   define a "__hash__()" operation either; if it defines "__eq__()"\n   but not "__hash__()", its instances will not be usable as items in\n   hashable collections.  If a class defines mutable objects and\n   implements an "__eq__()" method, it should not implement\n   "__hash__()", since the implementation of hashable collections\n   requires that a key\'s hash value is immutable (if the object\'s hash\n   value changes, it will be in the wrong hash bucket).\n\n   User-defined classes have "__eq__()" and "__hash__()" methods by\n   default; with them, all objects compare unequal (except with\n   themselves) and "x.__hash__()" returns an appropriate value such\n   that "x == y" implies both that "x is y" and "hash(x) == hash(y)".\n\n   A class that overrides "__eq__()" and does not define "__hash__()"\n   will have its "__hash__()" implicitly set to "None".  When the\n   "__hash__()" method of a class is "None", instances of the class\n   will raise an appropriate "TypeError" when a program attempts to\n   retrieve their hash value, and will also be correctly identified as\n   unhashable when checking "isinstance(obj, collections.Hashable)".\n\n   If a class that overrides "__eq__()" needs to retain the\n   implementation of "__hash__()" from a parent class, the interpreter\n   must be told this explicitly by setting "__hash__ =\n   <ParentClass>.__hash__".\n\n   If a class that does not override "__eq__()" wishes to suppress\n   hash support, it should include "__hash__ = None" in the class\n   definition. A class which defines its own "__hash__()" that\n   explicitly raises a "TypeError" would be incorrectly identified as\n   hashable by an "isinstance(obj, collections.Hashable)" call.\n\n   Note: By default, the "__hash__()" values of str, bytes and\n     datetime objects are "salted" with an unpredictable random value.\n     Although they remain constant within an individual Python\n     process, they are not predictable between repeated invocations of\n     Python.This is intended to provide protection against a denial-\n     of-service caused by carefully-chosen inputs that exploit the\n     worst case performance of a dict insertion, O(n^2) complexity.\n     See http://www.ocert.org/advisories/ocert-2011-003.html for\n     details.Changing hash values affects the iteration order of\n     dicts, sets and other mappings.  Python has never made guarantees\n     about this ordering (and it typically varies between 32-bit and\n     64-bit builds).See also "PYTHONHASHSEED".\n\n   Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n   Called to implement truth value testing and the built-in operation\n   "bool()"; should return "False" or "True".  When this method is not\n   defined, "__len__()" is called, if it is defined, and the object is\n   considered true if its result is nonzero.  If a class defines\n   neither "__len__()" nor "__bool__()", all its instances are\n   considered true.\n',
  'debugger': u'\n"pdb" --- The Python Debugger\n*****************************\n\n**Source code:** Lib/pdb.py\n\n======================================================================\n\nThe module "pdb" defines an interactive source code debugger for\nPython programs.  It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame.  It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible -- it is actually defined as the class\n"Pdb". This is currently undocumented but easily understood by reading\nthe source.  The extension interface uses the modules "bdb" and "cmd".\n\nThe debugger\'s prompt is "(Pdb)". Typical usage to run a program under\ncontrol of the debugger is:\n\n   >>> import pdb\n   >>> import mymodule\n   >>> pdb.run(\'mymodule.test()\')\n   > <string>(0)?()\n   (Pdb) continue\n   > <string>(1)?()\n   (Pdb) continue\n   NameError: \'spam\'\n   > <string>(1)?()\n   (Pdb)\n\nChanged in version 3.3: Tab-completion via the "readline" module is\navailable for commands and command arguments, e.g. the current global\nand local names are offered as arguments of the "p" command.\n\n"pdb.py" can also be invoked as a script to debug other scripts.  For\nexample:\n\n   python3 -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally.  After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program.  Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 3.2: "pdb.py" now accepts a "-c" option that executes\ncommands as if given in a ".pdbrc" file, see *Debugger Commands*.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n   import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger.  You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the "continue" command.\n\nThe typical usage to inspect a crashed program is:\n\n   >>> import pdb\n   >>> import mymodule\n   >>> mymodule.test()\n   Traceback (most recent call last):\n     File "<stdin>", line 1, in ?\n     File "./mymodule.py", line 4, in test\n       test2()\n     File "./mymodule.py", line 3, in test2\n       print(spam)\n   NameError: spam\n   >>> pdb.pm()\n   > ./mymodule.py(3)test2()\n   -> print(spam)\n   (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement, globals=None, locals=None)\n\n   Execute the *statement* (given as a string or a code object) under\n   debugger control.  The debugger prompt appears before any code is\n   executed; you can set breakpoints and type "continue", or you can\n   step through the statement using "step" or "next" (all these\n   commands are explained below).  The optional *globals* and *locals*\n   arguments specify the environment in which the code is executed; by\n   default the dictionary of the module "__main__" is used.  (See the\n   explanation of the built-in "exec()" or "eval()" functions.)\n\npdb.runeval(expression, globals=None, locals=None)\n\n   Evaluate the *expression* (given as a string or a code object)\n   under debugger control.  When "runeval()" returns, it returns the\n   value of the expression.  Otherwise this function is similar to\n   "run()".\n\npdb.runcall(function, *args, **kwds)\n\n   Call the *function* (a function or method object, not a string)\n   with the given arguments.  When "runcall()" returns, it returns\n   whatever the function call returned.  The debugger prompt appears\n   as soon as the function is entered.\n\npdb.set_trace()\n\n   Enter the debugger at the calling stack frame.  This is useful to\n   hard-code a breakpoint at a given point in a program, even if the\n   code is not otherwise being debugged (e.g. when an assertion\n   fails).\n\npdb.post_mortem(traceback=None)\n\n   Enter post-mortem debugging of the given *traceback* object.  If no\n   *traceback* is given, it uses the one of the exception that is\n   currently being handled (an exception must be being handled if the\n   default is to be used).\n\npdb.pm()\n\n   Enter post-mortem debugging of the traceback found in\n   "sys.last_traceback".\n\nThe "run*" functions and "set_trace()" are aliases for instantiating\nthe "Pdb" class and calling the method of the same name.  If you want\nto access further features, you have to do this yourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None, nosigint=False)\n\n   "Pdb" is the debugger class.\n\n   The *completekey*, *stdin* and *stdout* arguments are passed to the\n   underlying "cmd.Cmd" class; see the description there.\n\n   The *skip* argument, if given, must be an iterable of glob-style\n   module name patterns.  The debugger will not step into frames that\n   originate in a module that matches one of these patterns. [1]\n\n   By default, Pdb sets a handler for the SIGINT signal (which is sent\n   when the user presses "Ctrl-C" on the console) when you give a\n   "continue" command. This allows you to break into the debugger\n   again by pressing "Ctrl-C".  If you want Pdb not to touch the\n   SIGINT handler, set *nosigint* tot true.\n\n   Example call to enable tracing with *skip*:\n\n      import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n   New in version 3.1: The *skip* argument.\n\n   New in version 3.2: The *nosigint* argument.  Previously, a SIGINT\n   handler was never set by Pdb.\n\n   run(statement, globals=None, locals=None)\n   runeval(expression, globals=None, locals=None)\n   runcall(function, *args, **kwds)\n   set_trace()\n\n      See the documentation for the functions explained above.\n\n\nDebugger Commands\n=================\n\nThe commands recognized by the debugger are listed below.  Most\ncommands can be abbreviated to one or two letters as indicated; e.g.\n"h(elp)" means that either "h" or "help" can be used to enter the help\ncommand (but not "he" or "hel", nor "H" or "Help" or "HELP").\nArguments to commands must be separated by whitespace (spaces or\ntabs).  Optional arguments are enclosed in square brackets ("[]") in\nthe command syntax; the square brackets must not be typed.\nAlternatives in the command syntax are separated by a vertical bar\n("|").\n\nEntering a blank line repeats the last command entered.  Exception: if\nthe last command was a "list" command, the next 11 lines are listed.\n\nCommands that the debugger doesn\'t recognize are assumed to be Python\nstatements and are executed in the context of the program being\ndebugged.  Python statements can also be prefixed with an exclamation\npoint ("!").  This is a powerful way to inspect the program being\ndebugged; it is even possible to change a variable or call a function.\nWhen an exception occurs in such a statement, the exception name is\nprinted but the debugger\'s state is not changed.\n\nThe debugger supports *aliases*.  Aliases can have parameters which\nallows one a certain level of adaptability to the context under\nexamination.\n\nMultiple commands may be entered on a single line, separated by ";;".\n(A single ";" is not used as it is the separator for multiple commands\nin a line that is passed to the Python parser.)  No intelligence is\napplied to separating the commands; the input is split at the first\n";;" pair, even if it is in the middle of a quoted string.\n\nIf a file ".pdbrc" exists in the user\'s home directory or in the\ncurrent directory, it is read in and executed as if it had been typed\nat the debugger prompt.  This is particularly useful for aliases.  If\nboth files exist, the one in the home directory is read first and\naliases defined there can be overridden by the local file.\n\nChanged in version 3.2: ".pdbrc" can now contain commands that\ncontinue debugging, such as "continue" or "next".  Previously, these\ncommands had no effect.\n\nh(elp) [command]\n\n   Without argument, print the list of available commands.  With a\n   *command* as argument, print help about that command.  "help pdb"\n   displays the full documentation (the docstring of the "pdb"\n   module).  Since the *command* argument must be an identifier, "help\n   exec" must be entered to get help on the "!" command.\n\nw(here)\n\n   Print a stack trace, with the most recent frame at the bottom.  An\n   arrow indicates the current frame, which determines the context of\n   most commands.\n\nd(own) [count]\n\n   Move the current frame *count* (default one) levels down in the\n   stack trace (to a newer frame).\n\nu(p) [count]\n\n   Move the current frame *count* (default one) levels up in the stack\n   trace (to an older frame).\n\nb(reak) [([filename:]lineno | function) [, condition]]\n\n   With a *lineno* argument, set a break there in the current file.\n   With a *function* argument, set a break at the first executable\n   statement within that function.  The line number may be prefixed\n   with a filename and a colon, to specify a breakpoint in another\n   file (probably one that hasn\'t been loaded yet).  The file is\n   searched on "sys.path".  Note that each breakpoint is assigned a\n   number to which all the other breakpoint commands refer.\n\n   If a second argument is present, it is an expression which must\n   evaluate to true before the breakpoint is honored.\n\n   Without argument, list all breaks, including for each breakpoint,\n   the number of times that breakpoint has been hit, the current\n   ignore count, and the associated condition if any.\n\ntbreak [([filename:]lineno | function) [, condition]]\n\n   Temporary breakpoint, which is removed automatically when it is\n   first hit. The arguments are the same as for "break".\n\ncl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n\n   With a *filename:lineno* argument, clear all the breakpoints at\n   this line. With a space separated list of breakpoint numbers, clear\n   those breakpoints. Without argument, clear all breaks (but first\n   ask confirmation).\n\ndisable [bpnumber [bpnumber ...]]\n\n   Disable the breakpoints given as a space separated list of\n   breakpoint numbers.  Disabling a breakpoint means it cannot cause\n   the program to stop execution, but unlike clearing a breakpoint, it\n   remains in the list of breakpoints and can be (re-)enabled.\n\nenable [bpnumber [bpnumber ...]]\n\n   Enable the breakpoints specified.\n\nignore bpnumber [count]\n\n   Set the ignore count for the given breakpoint number.  If count is\n   omitted, the ignore count is set to 0.  A breakpoint becomes active\n   when the ignore count is zero.  When non-zero, the count is\n   decremented each time the breakpoint is reached and the breakpoint\n   is not disabled and any associated condition evaluates to true.\n\ncondition bpnumber [condition]\n\n   Set a new *condition* for the breakpoint, an expression which must\n   evaluate to true before the breakpoint is honored.  If *condition*\n   is absent, any existing condition is removed; i.e., the breakpoint\n   is made unconditional.\n\ncommands [bpnumber]\n\n   Specify a list of commands for breakpoint number *bpnumber*.  The\n   commands themselves appear on the following lines.  Type a line\n   containing just "end" to terminate the commands. An example:\n\n      (Pdb) commands 1\n      (com) p some_variable\n      (com) end\n      (Pdb)\n\n   To remove all commands from a breakpoint, type commands and follow\n   it immediately with "end"; that is, give no commands.\n\n   With no *bpnumber* argument, commands refers to the last breakpoint\n   set.\n\n   You can use breakpoint commands to start your program up again.\n   Simply use the continue command, or step, or any other command that\n   resumes execution.\n\n   Specifying any command resuming execution (currently continue,\n   step, next, return, jump, quit and their abbreviations) terminates\n   the command list (as if that command was immediately followed by\n   end). This is because any time you resume execution (even with a\n   simple next or step), you may encounter another breakpoint--which\n   could have its own command list, leading to ambiguities about which\n   list to execute.\n\n   If you use the \'silent\' command in the command list, the usual\n   message about stopping at a breakpoint is not printed.  This may be\n   desirable for breakpoints that are to print a specific message and\n   then continue.  If none of the other commands print anything, you\n   see no sign that the breakpoint was reached.\n\ns(tep)\n\n   Execute the current line, stop at the first possible occasion\n   (either in a function that is called or on the next line in the\n   current function).\n\nn(ext)\n\n   Continue execution until the next line in the current function is\n   reached or it returns.  (The difference between "next" and "step"\n   is that "step" stops inside a called function, while "next"\n   executes called functions at (nearly) full speed, only stopping at\n   the next line in the current function.)\n\nunt(il) [lineno]\n\n   Without argument, continue execution until the line with a number\n   greater than the current one is reached.\n\n   With a line number, continue execution until a line with a number\n   greater or equal to that is reached.  In both cases, also stop when\n   the current frame returns.\n\n   Changed in version 3.2: Allow giving an explicit line number.\n\nr(eturn)\n\n   Continue execution until the current function returns.\n\nc(ont(inue))\n\n   Continue execution, only stop when a breakpoint is encountered.\n\nj(ump) lineno\n\n   Set the next line that will be executed.  Only available in the\n   bottom-most frame.  This lets you jump back and execute code again,\n   or jump forward to skip code that you don\'t want to run.\n\n   It should be noted that not all jumps are allowed -- for instance\n   it is not possible to jump into the middle of a "for" loop or out\n   of a "finally" clause.\n\nl(ist) [first[, last]]\n\n   List source code for the current file.  Without arguments, list 11\n   lines around the current line or continue the previous listing.\n   With "." as argument, list 11 lines around the current line.  With\n   one argument, list 11 lines around at that line.  With two\n   arguments, list the given range; if the second argument is less\n   than the first, it is interpreted as a count.\n\n   The current line in the current frame is indicated by "->".  If an\n   exception is being debugged, the line where the exception was\n   originally raised or propagated is indicated by ">>", if it differs\n   from the current line.\n\n   New in version 3.2: The ">>" marker.\n\nll | longlist\n\n   List all source code for the current function or frame.\n   Interesting lines are marked as for "list".\n\n   New in version 3.2.\n\na(rgs)\n\n   Print the argument list of the current function.\n\np expression\n\n   Evaluate the *expression* in the current context and print its\n   value.\n\n   Note: "print()" can also be used, but is not a debugger command\n     --- this executes the Python "print()" function.\n\npp expression\n\n   Like the "p" command, except the value of the expression is pretty-\n   printed using the "pprint" module.\n\nwhatis expression\n\n   Print the type of the *expression*.\n\nsource expression\n\n   Try to get source code for the given object and display it.\n\n   New in version 3.2.\n\ndisplay [expression]\n\n   Display the value of the expression if it changed, each time\n   execution stops in the current frame.\n\n   Without expression, list all display expressions for the current\n   frame.\n\n   New in version 3.2.\n\nundisplay [expression]\n\n   Do not display the expression any more in the current frame.\n   Without expression, clear all display expressions for the current\n   frame.\n\n   New in version 3.2.\n\ninteract\n\n   Start an interative interpreter (using the "code" module) whose\n   global namespace contains all the (global and local) names found in\n   the current scope.\n\n   New in version 3.2.\n\nalias [name [command]]\n\n   Create an alias called *name* that executes *command*.  The command\n   must *not* be enclosed in quotes.  Replaceable parameters can be\n   indicated by "%1", "%2", and so on, while "%*" is replaced by all\n   the parameters. If no command is given, the current alias for\n   *name* is shown. If no arguments are given, all aliases are listed.\n\n   Aliases may be nested and can contain anything that can be legally\n   typed at the pdb prompt.  Note that internal pdb commands *can* be\n   overridden by aliases.  Such a command is then hidden until the\n   alias is removed.  Aliasing is recursively applied to the first\n   word of the command line; all other words in the line are left\n   alone.\n\n   As an example, here are two useful aliases (especially when placed\n   in the ".pdbrc" file):\n\n      # Print instance variables (usage "pi classInst")\n      alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])\n      # Print instance variables in self\n      alias ps pi self\n\nunalias name\n\n   Delete the specified alias.\n\n! statement\n\n   Execute the (one-line) *statement* in the context of the current\n   stack frame. The exclamation point can be omitted unless the first\n   word of the statement resembles a debugger command.  To set a\n   global variable, you can prefix the assignment command with a\n   "global" statement on the same line, e.g.:\n\n      (Pdb) global list_options; list_options = [\'-l\']\n      (Pdb)\n\nrun [args ...]\nrestart [args ...]\n\n   Restart the debugged Python program.  If an argument is supplied,\n   it is split with "shlex" and the result is used as the new\n   "sys.argv". History, breakpoints, actions and debugger options are\n   preserved. "restart" is an alias for "run".\n\nq(uit)\n\n   Quit from the debugger.  The program being executed is aborted.\n\n-[ Footnotes ]-\n\n[1] Whether a frame is considered to originate in a certain module\n    is determined by the "__name__" in the frame globals.\n',
  'del': u'\nThe "del" statement\n*******************\n\n   del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather than spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a "global"\nstatement in the same code block.  If the name is unbound, a\n"NameError" exception will be raised.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n\nChanged in version 3.2: Previously it was illegal to delete a name\nfrom the local namespace if it occurs as a free variable in a nested\nblock.\n',
- 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n   dict_display       ::= "{" [key_datum_list | dict_comprehension] "}"\n   key_datum_list     ::= key_datum ("," key_datum)* [","]\n   key_datum          ::= expression ":" expression\n   dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum.  This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*.  (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.)  Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n',
+ 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n   dict_display       ::= "{" [key_datum_list | dict_comprehension] "}"\n   key_datum_list     ::= key_datum ("," key_datum)* [","]\n   key_datum          ::= expression ":" expression | "**" or_expr\n   dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum.  This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA double asterisk "**" denotes *dictionary unpacking*. Its operand\nmust be a *mapping*.  Each mapping item is added to the new\ndictionary.  Later values replace values already set by earlier\nkey/datum pairs and earlier dictionary unpackings.\n\nNew in version 3.5: Unpacking into dictionary displays, originally\nproposed by **PEP 448**.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*.  (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.)  Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n',
  'dynamic-features': u'\nInteraction with dynamic features\n*********************************\n\nName resolution of free variables occurs at runtime, not at compile\ntime. This means that the following code will print 42:\n\n   i = 10\n   def f():\n       print(i)\n   i = 42\n   f()\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name.  An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names.  Names may be resolved in the local\nand global namespaces of the caller.  Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace.  [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace.  If only one namespace is\nspecified, it is used for both.\n',
  'else': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n   if_stmt ::= "if" expression ":" suite\n               ( "elif" expression ":" suite )*\n               ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n',
  'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions.  An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero).  A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement.  The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop.  In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances.  The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof.  The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nNote: Exception messages are not part of the Python API.  Their\n  contents may change from one version of Python to the next without\n  warning and should not be relied on by code which will run under\n  multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section *The try\nstatement* and "raise" statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n    these operations is not available at the time the module is\n    compiled.\n',
  'execmodel': u'\nExecution model\n***************\n\n\nStructure of a program\n======================\n\nA Python program is constructed from code blocks. A *block* is a piece\nof Python program text that is executed as a unit. The following are\nblocks: a module, a function body, and a class definition. Each\ncommand typed interactively is a block.  A script file (a file given\nas standard input to the interpreter or specified as a command line\nargument to the interpreter) is a code block.  A script command (a\ncommand specified on the interpreter command line with the \'**-c**\'\noption) is a code block.  The string argument passed to the built-in\nfunctions "eval()" and "exec()" is a code block.\n\nA code block is executed in an *execution frame*.  A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\n\nNaming and binding\n==================\n\n\nBinding of names\n----------------\n\n*Names* refer to objects.  Names are introduced by name binding\noperations.\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, or after\n"as" in a "with" statement or "except" clause. The "import" statement\nof the form "from ... import *" binds all names defined in the\nimported module, except those beginning with an underscore.  This form\nmay only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as "nonlocal" or "global".  If a name is bound at the\nmodule level, it is a global variable.  (The variables of the module\ncode block are local and global.)  If a variable is used in a code\nblock but not defined there, it is a *free variable*.\n\nEach occurrence of a name in the program text refers to the *binding*\nof that name established by the following name resolution rules.\n\n\nResolution of names\n-------------------\n\nA *scope* defines the visibility of a name within a block.  If a local\nvariable is defined in a block, its scope includes that block.  If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name.\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope.  The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nWhen a name is not found at all, a "NameError" exception is raised. If\nthe current scope is a function scope, and the name refers to a local\nvariable that has not yet been bound to a value at the point where the\nname is used, an "UnboundLocalError" exception is raised.\n"UnboundLocalError" is a subclass of "NameError".\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block.  This can lead to errors when a name is used within a\nblock before it is bound.  This rule is subtle.  Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block.  The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the "global" statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace.  Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "builtins".  The global namespace is searched first.  If\nthe name is not found there, the builtins namespace is searched.  The\n"global" statement must precede all uses of the name.\n\nThe "global" statement has the same scope as a name binding operation\nin the same block.  If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nThe "nonlocal" statement causes corresponding names to refer to\npreviously bound variables in the nearest enclosing function scope.\n"SyntaxError" is raised at compile time if the given name does not\nexist in any enclosing function scope.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported.  The main module for a script is always called\n"__main__".\n\nClass definition blocks and arguments to "exec()" and "eval()" are\nspecial in the context of name resolution. A class definition is an\nexecutable statement that may use and define names. These references\nfollow the normal rules for name resolution with an exception that\nunbound local variables are looked up in the global namespace. The\nnamespace of the class definition becomes the attribute dictionary of\nthe class. The scope of names defined in a class block is limited to\nthe class block; it does not extend to the code blocks of methods --\nthis includes comprehensions and generator expressions since they are\nimplemented using a function scope.  This means that the following\nwill fail:\n\n   class A:\n       a = 42\n       b = list(a + i for i in range(10))\n\n\nBuiltins and restricted execution\n---------------------------------\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used).  By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "builtins"; when in any\nother module, "__builtins__" is an alias for the dictionary of the\n"builtins" module itself.  "__builtins__" can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail.  Users\nwanting to override values in the builtins namespace should "import"\nthe "builtins" module and modify its attributes appropriately.\n\n\nInteraction with dynamic features\n---------------------------------\n\nName resolution of free variables occurs at runtime, not at compile\ntime. This means that the following code will print 42:\n\n   i = 10\n   def f():\n       print(i)\n   i = 42\n   f()\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name.  An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names.  Names may be resolved in the local\nand global namespaces of the caller.  Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace.  [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace.  If only one namespace is\nspecified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions.  An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero).  A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement.  The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop.  In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances.  The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof.  The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nNote: Exception messages are not part of the Python API.  Their\n  contents may change from one version of Python to the next without\n  warning and should not be relied on by code which will run under\n  multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section *The try\nstatement* and "raise" statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n    these operations is not available at the time the module is\n    compiled.\n',
- 'exprlists': u'\nExpression lists\n****************\n\n   expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple.  The\nlength of the tuple is the number of expressions in the list.  The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases.  A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: "()".)\n',
+ 'exprlists': u'\nExpression lists\n****************\n\n   expression_list    ::= expression ( "," expression )* [","]\n   starred_list       ::= starred_item ( "," starred_item )* [","]\n   starred_expression ::= expression | ( starred_item "," )* [starred_item]\n   starred_item       ::= expression | "*" or_expr\n\nExcept when part of a list or set display, an expression list\ncontaining at least one comma yields a tuple.  The length of the tuple\nis the number of expressions in the list.  The expressions are\nevaluated from left to right.\n\nAn asterisk "*" denotes *iterable unpacking*.  Its operand must be an\n*iterable*.  The iterable is expanded into a sequence of items, which\nare included in the new tuple, list, or set, at the site of the\nunpacking.\n\nNew in version 3.5: Iterable unpacking in expression lists, originally\nproposed by **PEP 448**.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases.  A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: "()".)\n',
  'floating': u'\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n   floatnumber   ::= pointfloat | exponentfloat\n   pointfloat    ::= [intpart] fraction | intpart "."\n   exponentfloat ::= (intpart | pointfloat) exponent\n   intpart       ::= digit+\n   fraction      ::= "." digit+\n   exponent      ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts are always interpreted using\nradix 10. For example, "077e010" is legal, and denotes the same number\nas "77e10". The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n   3.14    10.    .001    1e100    3.14e-10    0e0\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator "-" and the\nliteral "1".\n',
  'for': u'\nThe "for" statement\n*******************\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n   for_stmt ::= "for" target_list "in" expression_list ":" suite\n                ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject.  An iterator is created for the result of the\n"expression_list".  The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator.  Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted.  When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite.  A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n   for i in range(10):\n       print(i)\n       i = 5             # this will not affect the for-loop\n                         # because i will be overwritten with the next\n                         # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop.  Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n  loop (this can only occur for mutable sequences, i.e. lists).  An\n  internal counter is used to keep track of which item is used next,\n  and this is incremented on each iteration.  When this counter has\n  reached the length of the sequence the loop terminates.  This means\n  that if the suite deletes the current (or a previous) item from the\n  sequence, the next item will be skipped (since it gets the index of\n  the current item which has already been treated).  Likewise, if the\n  suite inserts an item in the sequence before the current item, the\n  current item will be treated again the next time through the loop.\n  This can lead to nasty bugs that can be avoided by making a\n  temporary copy using a slice of the whole sequence, e.g.,\n\n     for x in a[:]:\n         if x < 0: a.remove(x)\n',
- 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe "str.format()" method and the "Formatter" class share the same\nsyntax for format strings (although in the case of "Formatter",\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n"{}". Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output.  If you need to include\na brace character in the literal text, it can be escaped by doubling:\n"{{" and "}}".\n\nThe grammar for a replacement field is as follows:\n\n      replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n      field_name        ::= arg_name ("." attribute_name | "[" element_index "]")*\n      arg_name          ::= [identifier | integer]\n      attribute_name    ::= identifier\n      element_index     ::= integer | index_string\n      index_string      ::= <any source character except "]"> +\n      conversion        ::= "r" | "s" | "a"\n      format_spec       ::= <described in the next section>\n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a  *conversion* field, which is\npreceded by an exclamation point "\'!\'", and a *format_spec*, which is\npreceded by a colon "\':\'".  These specify a non-default format for the\nreplacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword.  If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument.  If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings "\'10\'" or\n"\':-]\'") within a format string. The *arg_name* can be followed by any\nnumber of index or attribute expressions. An expression of the form\n"\'.name\'" selects the named attribute using "getattr()", while an\nexpression of the form "\'[index]\'" does an index lookup using\n"__getitem__()".\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so "\'{} {}\'" is equivalent to "\'{0} {1}\'".\n\nSome simple format string examples:\n\n   "First, thou shalt count to {0}" # References first positional argument\n   "Bring me a {}"                  # Implicitly references the first positional argument\n   "From {} to {}"                  # Same as "From {0} to {1}"\n   "My quest is {name}"             # References keyword argument \'name\'\n   "Weight in tons {0.weight}"      # \'weight\' attribute of first positional arg\n   "Units destroyed: {players[0]}"  # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the "__format__()"\nmethod of the value itself.  However, in some cases it is desirable to\nforce a type to be formatted as a string, overriding its own\ndefinition of formatting.  By converting the value to a string before\ncalling "__format__()", the normal formatting logic is bypassed.\n\nThree conversion flags are currently supported: "\'!s\'" which calls\n"str()" on the value, "\'!r\'" which calls "repr()" and "\'!a\'" which\ncalls "ascii()".\n\nSome examples:\n\n   "Harold\'s a clever {0!s}"        # Calls str() on the argument first\n   "Bring out the holy {name!r}"    # Calls repr() on the argument first\n   "More {!a}"                      # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on.  Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed.  The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*).  They can also be passed directly to the\nbuilt-in "format()" function.  Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string ("""") produces\nthe same result as if you had called "str()" on the value. A non-empty\nformat string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n   format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n   fill        ::= <any character>\n   align       ::= "<" | ">" | "=" | "^"\n   sign        ::= "+" | "-" | " "\n   width       ::= integer\n   precision   ::= integer\n   type        ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use "{" and "}" as *fill*\nchar while using the "str.format()" method; this limitation however\ndoesn\'t affect the "format()" function.\n\nThe meaning of the various alignment options is as follows:\n\n   +-----------+------------------------------------------------------------+\n   | Option    | Meaning                                                    |\n   +===========+============================================================+\n   | "\'<\'"     | Forces the field to be left-aligned within the available   |\n   |           | space (this is the default for most objects).              |\n   +-----------+------------------------------------------------------------+\n   | "\'>\'"     | Forces the field to be right-aligned within the available  |\n   |           | space (this is the default for numbers).                   |\n   +-----------+------------------------------------------------------------+\n   | "\'=\'"     | Forces the padding to be placed after the sign (if any)    |\n   |           | but before the digits.  This is used for printing fields   |\n   |           | in the form \'+000000120\'. This alignment option is only    |\n   |           | valid for numeric types.                                   |\n   +-----------+------------------------------------------------------------+\n   | "\'^\'"     | Forces the field to be centered within the available       |\n   |           | space.                                                     |\n   +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n   +-----------+------------------------------------------------------------+\n   | Option    | Meaning                                                    |\n   +===========+============================================================+\n   | "\'+\'"     | indicates that a sign should be used for both positive as  |\n   |           | well as negative numbers.                                  |\n   +-----------+------------------------------------------------------------+\n   | "\'-\'"     | indicates that a sign should be used only for negative     |\n   |           | numbers (this is the default behavior).                    |\n   +-----------+------------------------------------------------------------+\n   | space     | indicates that a leading space should be used on positive  |\n   |           | numbers, and a minus sign on negative numbers.             |\n   +-----------+------------------------------------------------------------+\n\nThe "\'#\'" option causes the "alternate form" to be used for the\nconversion.  The alternate form is defined differently for different\ntypes.  This option is only valid for integer, float, complex and\nDecimal types. For integers, when binary, octal, or hexadecimal output\nis used, this option adds the prefix respective "\'0b\'", "\'0o\'", or\n"\'0x\'" to the output value. For floats, complex and Decimal the\nalternate form causes the result of the conversion to always contain a\ndecimal-point character, even if no digits follow it. Normally, a\ndecimal-point character appears in the result of these conversions\nonly if a digit follows it. In addition, for "\'g\'" and "\'G\'"\nconversions, trailing zeros are not removed from the result.\n\nThe "\',\'" option signals the use of a comma for a thousands separator.\nFor a locale aware separator, use the "\'n\'" integer presentation type\ninstead.\n\nChanged in version 3.1: Added the "\',\'" option (see also **PEP 378**).\n\n*width* is a decimal integer defining the minimum field width.  If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero ("\'0\'") character enables sign-\naware zero-padding for numeric types.  This is equivalent to a *fill*\ncharacter of "\'0\'" with an *alignment* type of "\'=\'".\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with "\'f\'" and "\'F\'", or before and after the decimal point\nfor a floating point value formatted with "\'g\'" or "\'G\'".  For non-\nnumber types the field indicates the maximum field size - in other\nwords, how many characters will be used from the field content. The\n*precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | "\'s\'"     | String format. This is the default type for strings and    |\n   |           | may be omitted.                                            |\n   +-----------+------------------------------------------------------------+\n   | None      | The same as "\'s\'".                                         |\n   +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | "\'b\'"     | Binary format. Outputs the number in base 2.               |\n   +-----------+------------------------------------------------------------+\n   | "\'c\'"     | Character. Converts the integer to the corresponding       |\n   |           | unicode character before printing.                         |\n   +-----------+------------------------------------------------------------+\n   | "\'d\'"     | Decimal Integer. Outputs the number in base 10.            |\n   +-----------+------------------------------------------------------------+\n   | "\'o\'"     | Octal format. Outputs the number in base 8.                |\n   +-----------+------------------------------------------------------------+\n   | "\'x\'"     | Hex format. Outputs the number in base 16, using lower-    |\n   |           | case letters for the digits above 9.                       |\n   +-----------+------------------------------------------------------------+\n   | "\'X\'"     | Hex format. Outputs the number in base 16, using upper-    |\n   |           | case letters for the digits above 9.                       |\n   +-----------+------------------------------------------------------------+\n   | "\'n\'"     | Number. This is the same as "\'d\'", except that it uses the |\n   |           | current locale setting to insert the appropriate number    |\n   |           | separator characters.                                      |\n   +-----------+------------------------------------------------------------+\n   | None      | The same as "\'d\'".                                         |\n   +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except "\'n\'"\nand None). When doing so, "float()" is used to convert the integer to\na floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | "\'e\'"     | Exponent notation. Prints the number in scientific         |\n   |           | notation using the letter \'e\' to indicate the exponent.    |\n   |           | The default precision is "6".                              |\n   +-----------+------------------------------------------------------------+\n   | "\'E\'"     | Exponent notation. Same as "\'e\'" except it uses an upper   |\n   |           | case \'E\' as the separator character.                       |\n   +-----------+------------------------------------------------------------+\n   | "\'f\'"     | Fixed point. Displays the number as a fixed-point number.  |\n   |           | The default precision is "6".                              |\n   +-----------+------------------------------------------------------------+\n   | "\'F\'"     | Fixed point. Same as "\'f\'", but converts "nan" to "NAN"    |\n   |           | and "inf" to "INF".                                        |\n   +-----------+------------------------------------------------------------+\n   | "\'g\'"     | General format.  For a given precision "p >= 1", this      |\n   |           | rounds the number to "p" significant digits and then       |\n   |           | formats the result in either fixed-point format or in      |\n   |           | scientific notation, depending on its magnitude.  The      |\n   |           | precise rules are as follows: suppose that the result      |\n   |           | formatted with presentation type "\'e\'" and precision "p-1" |\n   |           | would have exponent "exp".  Then if "-4 <= exp < p", the   |\n   |           | number is formatted with presentation type "\'f\'" and       |\n   |           | precision "p-1-exp".  Otherwise, the number is formatted   |\n   |           | with presentation type "\'e\'" and precision "p-1". In both  |\n   |           | cases insignificant trailing zeros are removed from the    |\n   |           | significand, and the decimal point is also removed if      |\n   |           | there are no remaining digits following it.  Positive and  |\n   |           | negative infinity, positive and negative zero, and nans,   |\n   |           | are formatted as "inf", "-inf", "0", "-0" and "nan"        |\n   |           | respectively, regardless of the precision.  A precision of |\n   |           | "0" is treated as equivalent to a precision of "1". The    |\n   |           | default precision is "6".                                  |\n   +-----------+------------------------------------------------------------+\n   | "\'G\'"     | General format. Same as "\'g\'" except switches to "\'E\'" if  |\n   |           | the number gets too large. The representations of infinity |\n   |           | and NaN are uppercased, too.                               |\n   +-----------+------------------------------------------------------------+\n   | "\'n\'"     | Number. This is the same as "\'g\'", except that it uses the |\n   |           | current locale setting to insert the appropriate number    |\n   |           | separator characters.                                      |\n   +-----------+------------------------------------------------------------+\n   | "\'%\'"     | Percentage. Multiplies the number by 100 and displays in   |\n   |           | fixed ("\'f\'") format, followed by a percent sign.          |\n   +-----------+------------------------------------------------------------+\n   | None      | Similar to "\'g\'", except that fixed-point notation, when   |\n   |           | used, has at least one digit past the decimal point. The   |\n   |           | default precision is as high as needed to represent the    |\n   |           | particular value. The overall effect is to match the       |\n   |           | output of "str()" as altered by the other format           |\n   |           | modifiers.                                                 |\n   +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old "%"-formatting.\n\nIn most of the cases the syntax is similar to the old "%"-formatting,\nwith the addition of the "{}" and with ":" used instead of "%". For\nexample, "\'%03.2f\'" can be translated to "\'{:03.2f}\'".\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n   >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n   \'a, b, c\'\n   >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\')  # 3.1+ only\n   \'a, b, c\'\n   >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n   \'c, b, a\'\n   >>> \'{2}, {1}, {0}\'.format(*\'abc\')      # unpacking argument sequence\n   \'c, b, a\'\n   >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\')   # arguments\' indices can be repeated\n   \'abracadabra\'\n\nAccessing arguments by name:\n\n   >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n   \'Coordinates: 37.24N, -115.81W\'\n   >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n   >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n   \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n   >>> c = 3-5j\n   >>> (\'The complex number {0} is formed from the real part {0.real} \'\n   ...  \'and the imaginary part {0.imag}.\').format(c)\n   \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n   >>> class Point:\n   ...     def __init__(self, x, y):\n   ...         self.x, self.y = x, y\n   ...     def __str__(self):\n   ...         return \'Point({self.x}, {self.y})\'.format(self=self)\n   ...\n   >>> str(Point(4, 2))\n   \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n   >>> coord = (3, 5)\n   >>> \'X: {0[0]};  Y: {0[1]}\'.format(coord)\n   \'X: 3;  Y: 5\'\n\nReplacing "%s" and "%r":\n\n   >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n   "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n   >>> \'{:<30}\'.format(\'left aligned\')\n   \'left aligned                  \'\n   >>> \'{:>30}\'.format(\'right aligned\')\n   \'                 right aligned\'\n   >>> \'{:^30}\'.format(\'centered\')\n   \'           centered           \'\n   >>> \'{:*^30}\'.format(\'centered\')  # use \'*\' as a fill char\n   \'***********centered***********\'\n\nReplacing "%+f", "%-f", and "% f" and specifying a sign:\n\n   >>> \'{:+f}; {:+f}\'.format(3.14, -3.14)  # show it always\n   \'+3.140000; -3.140000\'\n   >>> \'{: f}; {: f}\'.format(3.14, -3.14)  # show a space for positive numbers\n   \' 3.140000; -3.140000\'\n   >>> \'{:-f}; {:-f}\'.format(3.14, -3.14)  # show only the minus -- same as \'{:f}; {:f}\'\n   \'3.140000; -3.140000\'\n\nReplacing "%x" and "%o" and converting the value to different bases:\n\n   >>> # format also supports binary numbers\n   >>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)\n   \'int: 42;  hex: 2a;  oct: 52;  bin: 101010\'\n   >>> # with 0x, 0o, or 0b as prefix:\n   >>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)\n   \'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n   >>> \'{:,}\'.format(1234567890)\n   \'1,234,567,890\'\n\nExpressing a percentage:\n\n   >>> points = 19\n   >>> total = 22\n   >>> \'Correct answers: {:.2%}\'.format(points/total)\n   \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n   >>> import datetime\n   >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n   >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n   \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n   >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n   ...     \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n   ...\n   \'left<<<<<<<<<<<<\'\n   \'^^^^^center^^^^^\'\n   \'>>>>>>>>>>>right\'\n   >>>\n   >>> octets = [192, 168, 0, 1]\n   >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n   \'C0A80001\'\n   >>> int(_, 16)\n   3232235521\n   >>>\n   >>> width = 5\n   >>> for num in range(5,12): #doctest: +NORMALIZE_WHITESPACE\n   ...     for base in \'dXob\':\n   ...         print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n   ...     print()\n   ...\n       5     5     5   101\n       6     6     6   110\n       7     7     7   111\n       8     8    10  1000\n       9     9    11  1001\n      10     A    12  1010\n      11     B    13  1011\n',
- 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n   funcdef        ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n   decorators     ::= decorator+\n   decorator      ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n   dotted_name    ::= identifier ("." identifier)*\n   parameter_list ::= (defparameter ",")*\n                      | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n                      | "**" parameter\n                      | defparameter [","] )\n   parameter      ::= identifier [":" expression]\n   defparameter   ::= parameter ["=" expression]\n   funcname       ::= identifier\n\nA function definition is an executable statement.  Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function).  This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition.  The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object.  Multiple decorators are applied in\nnested fashion. For example, the following code\n\n   @f1(arg)\n   @f2\n   def func(): pass\n\nis equivalent to\n\n   def func(): pass\n   func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted.  If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call.  This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended.  A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n   def whats_on_the_telly(penguin=None):\n       if penguin is None:\n           penguin = []\n       penguin.append("property of the zoo")\n       return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values.  If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple.  If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name.  Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier".  Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist.  These annotations can be any valid Python expression and are\nevaluated when the function definition is executed.  Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction.  The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions.  This uses lambda\nexpressions, described in section *Lambdas*.  Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression.  The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects.  A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around.  Free variables used\nin the nested function can access the local variables of the function\ncontaining the def.  See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n     The original specification for function annotations.\n',
+ 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe "str.format()" method and the "Formatter" class share the same\nsyntax for format strings (although in the case of "Formatter",\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n"{}". Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output.  If you need to include\na brace character in the literal text, it can be escaped by doubling:\n"{{" and "}}".\n\nThe grammar for a replacement field is as follows:\n\n      replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n      field_name        ::= arg_name ("." attribute_name | "[" element_index "]")*\n      arg_name          ::= [identifier | integer]\n      attribute_name    ::= identifier\n      element_index     ::= integer | index_string\n      index_string      ::= <any source character except "]"> +\n      conversion        ::= "r" | "s" | "a"\n      format_spec       ::= <described in the next section>\n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a  *conversion* field, which is\npreceded by an exclamation point "\'!\'", and a *format_spec*, which is\npreceded by a colon "\':\'".  These specify a non-default format for the\nreplacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword.  If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument.  If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings "\'10\'" or\n"\':-]\'") within a format string. The *arg_name* can be followed by any\nnumber of index or attribute expressions. An expression of the form\n"\'.name\'" selects the named attribute using "getattr()", while an\nexpression of the form "\'[index]\'" does an index lookup using\n"__getitem__()".\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so "\'{} {}\'" is equivalent to "\'{0} {1}\'".\n\nSome simple format string examples:\n\n   "First, thou shalt count to {0}"  # References first positional argument\n   "Bring me a {}"                   # Implicitly references the first positional argument\n   "From {} to {}"                   # Same as "From {0} to {1}"\n   "My quest is {name}"              # References keyword argument \'name\'\n   "Weight in tons {0.weight}"       # \'weight\' attribute of first positional arg\n   "Units destroyed: {players[0]}"   # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the "__format__()"\nmethod of the value itself.  However, in some cases it is desirable to\nforce a type to be formatted as a string, overriding its own\ndefinition of formatting.  By converting the value to a string before\ncalling "__format__()", the normal formatting logic is bypassed.\n\nThree conversion flags are currently supported: "\'!s\'" which calls\n"str()" on the value, "\'!r\'" which calls "repr()" and "\'!a\'" which\ncalls "ascii()".\n\nSome examples:\n\n   "Harold\'s a clever {0!s}"        # Calls str() on the argument first\n   "Bring out the holy {name!r}"    # Calls repr() on the argument first\n   "More {!a}"                      # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on.  Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields may contain a field name,\nconversion flag and format specification, but deeper nesting is not\nallowed.  The replacement fields within the format_spec are\nsubstituted before the *format_spec* string is interpreted. This\nallows the formatting of a value to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*).  They can also be passed directly to the\nbuilt-in "format()" function.  Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string ("""") produces\nthe same result as if you had called "str()" on the value. A non-empty\nformat string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n   format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n   fill        ::= <any character>\n   align       ::= "<" | ">" | "=" | "^"\n   sign        ::= "+" | "-" | " "\n   width       ::= integer\n   precision   ::= integer\n   type        ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. It is not possible to use a literal curly brace (""{"" or\n""}"") as the *fill* character when using the "str.format()" method.\nHowever, it is possible to insert a curly brace with a nested\nreplacement field.  This limitation doesn\'t affect the "format()"\nfunction.\n\nThe meaning of the various alignment options is as follows:\n\n   +-----------+------------------------------------------------------------+\n   | Option    | Meaning                                                    |\n   +===========+============================================================+\n   | "\'<\'"     | Forces the field to be left-aligned within the available   |\n   |           | space (this is the default for most objects).              |\n   +-----------+------------------------------------------------------------+\n   | "\'>\'"     | Forces the field to be right-aligned within the available  |\n   |           | space (this is the default for numbers).                   |\n   +-----------+------------------------------------------------------------+\n   | "\'=\'"     | Forces the padding to be placed after the sign (if any)    |\n   |           | but before the digits.  This is used for printing fields   |\n   |           | in the form \'+000000120\'. This alignment option is only    |\n   |           | valid for numeric types.  It becomes the default when \'0\'  |\n   |           | immediately precedes the field width.                      |\n   +-----------+------------------------------------------------------------+\n   | "\'^\'"     | Forces the field to be centered within the available       |\n   |           | space.                                                     |\n   +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n   +-----------+------------------------------------------------------------+\n   | Option    | Meaning                                                    |\n   +===========+============================================================+\n   | "\'+\'"     | indicates that a sign should be used for both positive as  |\n   |           | well as negative numbers.                                  |\n   +-----------+------------------------------------------------------------+\n   | "\'-\'"     | indicates that a sign should be used only for negative     |\n   |           | numbers (this is the default behavior).                    |\n   +-----------+------------------------------------------------------------+\n   | space     | indicates that a leading space should be used on positive  |\n   |           | numbers, and a minus sign on negative numbers.             |\n   +-----------+------------------------------------------------------------+\n\nThe "\'#\'" option causes the "alternate form" to be used for the\nconversion.  The alternate form is defined differently for different\ntypes.  This option is only valid for integer, float, complex and\nDecimal types. For integers, when binary, octal, or hexadecimal output\nis used, this option adds the prefix respective "\'0b\'", "\'0o\'", or\n"\'0x\'" to the output value. For floats, complex and Decimal the\nalternate form causes the result of the conversion to always contain a\ndecimal-point character, even if no digits follow it. Normally, a\ndecimal-point character appears in the result of these conversions\nonly if a digit follows it. In addition, for "\'g\'" and "\'G\'"\nconversions, trailing zeros are not removed from the result.\n\nThe "\',\'" option signals the use of a comma for a thousands separator.\nFor a locale aware separator, use the "\'n\'" integer presentation type\ninstead.\n\nChanged in version 3.1: Added the "\',\'" option (see also **PEP 378**).\n\n*width* is a decimal integer defining the minimum field width.  If not\nspecified, then the field width will be determined by the content.\n\nWhen no explicit alignment is given, preceding the *width* field by a\nzero ("\'0\'") character enables sign-aware zero-padding for numeric\ntypes.  This is equivalent to a *fill* character of "\'0\'" with an\n*alignment* type of "\'=\'".\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with "\'f\'" and "\'F\'", or before and after the decimal point\nfor a floating point value formatted with "\'g\'" or "\'G\'".  For non-\nnumber types the field indicates the maximum field size - in other\nwords, how many characters will be used from the field content. The\n*precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | "\'s\'"     | String format. This is the default type for strings and    |\n   |           | may be omitted.                                            |\n   +-----------+------------------------------------------------------------+\n   | None      | The same as "\'s\'".                                         |\n   +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | "\'b\'"     | Binary format. Outputs the number in base 2.               |\n   +-----------+------------------------------------------------------------+\n   | "\'c\'"     | Character. Converts the integer to the corresponding       |\n   |           | unicode character before printing.                         |\n   +-----------+------------------------------------------------------------+\n   | "\'d\'"     | Decimal Integer. Outputs the number in base 10.            |\n   +-----------+------------------------------------------------------------+\n   | "\'o\'"     | Octal format. Outputs the number in base 8.                |\n   +-----------+------------------------------------------------------------+\n   | "\'x\'"     | Hex format. Outputs the number in base 16, using lower-    |\n   |           | case letters for the digits above 9.                       |\n   +-----------+------------------------------------------------------------+\n   | "\'X\'"     | Hex format. Outputs the number in base 16, using upper-    |\n   |           | case letters for the digits above 9.                       |\n   +-----------+------------------------------------------------------------+\n   | "\'n\'"     | Number. This is the same as "\'d\'", except that it uses the |\n   |           | current locale setting to insert the appropriate number    |\n   |           | separator characters.                                      |\n   +-----------+------------------------------------------------------------+\n   | None      | The same as "\'d\'".                                         |\n   +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except "\'n\'"\nand None). When doing so, "float()" is used to convert the integer to\na floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | "\'e\'"     | Exponent notation. Prints the number in scientific         |\n   |           | notation using the letter \'e\' to indicate the exponent.    |\n   |           | The default precision is "6".                              |\n   +-----------+------------------------------------------------------------+\n   | "\'E\'"     | Exponent notation. Same as "\'e\'" except it uses an upper   |\n   |           | case \'E\' as the separator character.                       |\n   +-----------+------------------------------------------------------------+\n   | "\'f\'"     | Fixed point. Displays the number as a fixed-point number.  |\n   |           | The default precision is "6".                              |\n   +-----------+------------------------------------------------------------+\n   | "\'F\'"     | Fixed point. Same as "\'f\'", but converts "nan" to "NAN"    |\n   |           | and "inf" to "INF".                                        |\n   +-----------+------------------------------------------------------------+\n   | "\'g\'"     | General format.  For a given precision "p >= 1", this      |\n   |           | rounds the number to "p" significant digits and then       |\n   |           | formats the result in either fixed-point format or in      |\n   |           | scientific notation, depending on its magnitude.  The      |\n   |           | precise rules are as follows: suppose that the result      |\n   |           | formatted with presentation type "\'e\'" and precision "p-1" |\n   |           | would have exponent "exp".  Then if "-4 <= exp < p", the   |\n   |           | number is formatted with presentation type "\'f\'" and       |\n   |           | precision "p-1-exp".  Otherwise, the number is formatted   |\n   |           | with presentation type "\'e\'" and precision "p-1". In both  |\n   |           | cases insignificant trailing zeros are removed from the    |\n   |           | significand, and the decimal point is also removed if      |\n   |           | there are no remaining digits following it.  Positive and  |\n   |           | negative infinity, positive and negative zero, and nans,   |\n   |           | are formatted as "inf", "-inf", "0", "-0" and "nan"        |\n   |           | respectively, regardless of the precision.  A precision of |\n   |           | "0" is treated as equivalent to a precision of "1". The    |\n   |           | default precision is "6".                                  |\n   +-----------+------------------------------------------------------------+\n   | "\'G\'"     | General format. Same as "\'g\'" except switches to "\'E\'" if  |\n   |           | the number gets too large. The representations of infinity |\n   |           | and NaN are uppercased, too.                               |\n   +-----------+------------------------------------------------------------+\n   | "\'n\'"     | Number. This is the same as "\'g\'", except that it uses the |\n   |           | current locale setting to insert the appropriate number    |\n   |           | separator characters.                                      |\n   +-----------+------------------------------------------------------------+\n   | "\'%\'"     | Percentage. Multiplies the number by 100 and displays in   |\n   |           | fixed ("\'f\'") format, followed by a percent sign.          |\n   +-----------+------------------------------------------------------------+\n   | None      | Similar to "\'g\'", except that fixed-point notation, when   |\n   |           | used, has at least one digit past the decimal point. The   |\n   |           | default precision is as high as needed to represent the    |\n   |           | particular value. The overall effect is to match the       |\n   |           | output of "str()" as altered by the other format           |\n   |           | modifiers.                                                 |\n   +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the "str.format()" syntax and\ncomparison with the old "%"-formatting.\n\nIn most of the cases the syntax is similar to the old "%"-formatting,\nwith the addition of the "{}" and with ":" used instead of "%". For\nexample, "\'%03.2f\'" can be translated to "\'{:03.2f}\'".\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n   >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n   \'a, b, c\'\n   >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\')  # 3.1+ only\n   \'a, b, c\'\n   >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n   \'c, b, a\'\n   >>> \'{2}, {1}, {0}\'.format(*\'abc\')      # unpacking argument sequence\n   \'c, b, a\'\n   >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\')   # arguments\' indices can be repeated\n   \'abracadabra\'\n\nAccessing arguments by name:\n\n   >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n   \'Coordinates: 37.24N, -115.81W\'\n   >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n   >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n   \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n   >>> c = 3-5j\n   >>> (\'The complex number {0} is formed from the real part {0.real} \'\n   ...  \'and the imaginary part {0.imag}.\').format(c)\n   \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n   >>> class Point:\n   ...     def __init__(self, x, y):\n   ...         self.x, self.y = x, y\n   ...     def __str__(self):\n   ...         return \'Point({self.x}, {self.y})\'.format(self=self)\n   ...\n   >>> str(Point(4, 2))\n   \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n   >>> coord = (3, 5)\n   >>> \'X: {0[0]};  Y: {0[1]}\'.format(coord)\n   \'X: 3;  Y: 5\'\n\nReplacing "%s" and "%r":\n\n   >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n   "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n   >>> \'{:<30}\'.format(\'left aligned\')\n   \'left aligned                  \'\n   >>> \'{:>30}\'.format(\'right aligned\')\n   \'                 right aligned\'\n   >>> \'{:^30}\'.format(\'centered\')\n   \'           centered           \'\n   >>> \'{:*^30}\'.format(\'centered\')  # use \'*\' as a fill char\n   \'***********centered***********\'\n\nReplacing "%+f", "%-f", and "% f" and specifying a sign:\n\n   >>> \'{:+f}; {:+f}\'.format(3.14, -3.14)  # show it always\n   \'+3.140000; -3.140000\'\n   >>> \'{: f}; {: f}\'.format(3.14, -3.14)  # show a space for positive numbers\n   \' 3.140000; -3.140000\'\n   >>> \'{:-f}; {:-f}\'.format(3.14, -3.14)  # show only the minus -- same as \'{:f}; {:f}\'\n   \'3.140000; -3.140000\'\n\nReplacing "%x" and "%o" and converting the value to different bases:\n\n   >>> # format also supports binary numbers\n   >>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)\n   \'int: 42;  hex: 2a;  oct: 52;  bin: 101010\'\n   >>> # with 0x, 0o, or 0b as prefix:\n   >>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)\n   \'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n   >>> \'{:,}\'.format(1234567890)\n   \'1,234,567,890\'\n\nExpressing a percentage:\n\n   >>> points = 19\n   >>> total = 22\n   >>> \'Correct answers: {:.2%}\'.format(points/total)\n   \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n   >>> import datetime\n   >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n   >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n   \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n   >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n   ...     \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n   ...\n   \'left<<<<<<<<<<<<\'\n   \'^^^^^center^^^^^\'\n   \'>>>>>>>>>>>right\'\n   >>>\n   >>> octets = [192, 168, 0, 1]\n   >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n   \'C0A80001\'\n   >>> int(_, 16)\n   3232235521\n   >>>\n   >>> width = 5\n   >>> for num in range(5,12): #doctest: +NORMALIZE_WHITESPACE\n   ...     for base in \'dXob\':\n   ...         print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n   ...     print()\n   ...\n       5     5     5   101\n       6     6     6   110\n       7     7     7   111\n       8     8    10  1000\n       9     9    11  1001\n      10     A    12  1010\n      11     B    13  1011\n',
+ 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n   funcdef        ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n   decorators     ::= decorator+\n   decorator      ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n   dotted_name    ::= identifier ("." identifier)*\n   parameter_list ::= (defparameter ",")*\n                      | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n                      | "**" parameter\n                      | defparameter [","] )\n   parameter      ::= identifier [":" expression]\n   defparameter   ::= parameter ["=" expression]\n   funcname       ::= identifier\n\nA function definition is an executable statement.  Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function).  This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition.  The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object.  Multiple decorators are applied in\nnested fashion. For example, the following code\n\n   @f1(arg)\n   @f2\n   def func(): pass\n\nis equivalent to\n\n   def func(): pass\n   func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted.  If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call.  This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended.  A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n   def whats_on_the_telly(penguin=None):\n       if penguin is None:\n           penguin = []\n       penguin.append("property of the zoo")\n       return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values.  If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple.  If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name.  Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier".  Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist.  These annotations can be any valid Python expression and are\nevaluated when the function definition is executed.  Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction.  The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions.  This uses lambda\nexpressions, described in section *Lambdas*.  Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression.  The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects.  A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around.  Free variables used\nin the nested function can access the local variables of the function\ncontaining the def.  See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n     The original specification for function annotations.\n',
  'global': u'\nThe "global" statement\n**********************\n\n   global_stmt ::= "global" identifier ("," identifier)*\n\nThe "global" statement is a declaration which holds for the entire\ncurrent code block.  It means that the listed identifiers are to be\ninterpreted as globals.  It would be impossible to assign to a global\nvariable without "global", although free variables may refer to\nglobals without being declared global.\n\nNames listed in a "global" statement must not be used in the same code\nblock textually preceding that "global" statement.\n\nNames listed in a "global" statement must not be defined as formal\nparameters or in a "for" loop control target, "class" definition,\nfunction definition, or "import" statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the two restrictions, but programs should not abuse this\nfreedom, as future implementations may enforce them or silently change\nthe meaning of the program.\n\n**Programmer\'s note:** the "global" is a directive to the parser.  It\napplies only to code parsed at the same time as the "global"\nstatement. In particular, a "global" statement contained in a string\nor code object supplied to the built-in "exec()" function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by "global" statements in the\ncode containing the function call.  The same applies to the "eval()"\nand "compile()" functions.\n',
  'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings.  These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n   Not imported by "from module import *".  The special identifier "_"\n   is used in the interactive interpreter to store the result of the\n   last evaluation; it is stored in the "builtins" module.  When not\n   in interactive mode, "_" has no special meaning and is not defined.\n   See section *The import statement*.\n\n   Note: The name "_" is often used in conjunction with\n     internationalization; refer to the documentation for the\n     "gettext" module for more information on this convention.\n\n"__*__"\n   System-defined names. These names are defined by the interpreter\n   and its implementation (including the standard library).  Current\n   system names are discussed in the *Special method names* section\n   and elsewhere.  More will likely be defined in future versions of\n   Python.  *Any* use of "__*__" names, in any context, that does not\n   follow explicitly documented use, is subject to breakage without\n   warning.\n\n"__*"\n   Class-private names.  Names in this category, when used within the\n   context of a class definition, are re-written to use a mangled form\n   to help avoid name clashes between "private" attributes of base and\n   derived classes. See section *Identifiers (Names)*.\n',
- 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters "A" through "Z", the underscore "_" and, except for the first\ncharacter, the digits "0" through "9".\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**).  For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n"unicodedata" module.\n\nIdentifiers are unlimited in length.  Case is significant.\n\n   identifier   ::= xid_start xid_continue*\n   id_start     ::= <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property>\n   id_continue  ::= <all characters in id_start, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>\n   xid_start    ::= <all characters in id_start whose NFKC normalization is in "id_start xid_continue*">\n   xid_continue ::= <all characters in id_continue whose NFKC normalization is in "id_continue*">\n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\n* *Other_ID_Start* - explicit list of characters in PropList.txt to\n  support backwards compatibility\n\n* *Other_ID_Continue* - likewise\n\nAll identifiers are converted into the normal form NFKC while parsing;\ncomparison of identifiers is based on NFKC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers.  They must\nbe spelled exactly as written here:\n\n   False      class      finally    is         return\n   None       continue   for        lambda     try\n   True       def        from       nonlocal   while\n   and        del        global     not        with\n   as         elif       if         or         yield\n   assert     else       import     pass\n   break      except     in         raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings.  These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n   Not imported by "from module import *".  The special identifier "_"\n   is used in the interactive interpreter to store the result of the\n   last evaluation; it is stored in the "builtins" module.  When not\n   in interactive mode, "_" has no special meaning and is not defined.\n   See section *The import statement*.\n\n   Note: The name "_" is often used in conjunction with\n     internationalization; refer to the documentation for the\n     "gettext" module for more information on this convention.\n\n"__*__"\n   System-defined names. These names are defined by the interpreter\n   and its implementation (including the standard library).  Current\n   system names are discussed in the *Special method names* section\n   and elsewhere.  More will likely be defined in future versions of\n   Python.  *Any* use of "__*__" names, in any context, that does not\n   follow explicitly documented use, is subject to breakage without\n   warning.\n\n"__*"\n   Class-private names.  Names in this category, when used within the\n   context of a class definition, are re-written to use a mangled form\n   to help avoid name clashes between "private" attributes of base and\n   derived classes. See section *Identifiers (Names)*.\n',
+ 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters "A" through "Z", the underscore "_" and, except for the first\ncharacter, the digits "0" through "9".\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**).  For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n"unicodedata" module.\n\nIdentifiers are unlimited in length.  Case is significant.\n\n   identifier   ::= xid_start xid_continue*\n   id_start     ::= <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property>\n   id_continue  ::= <all characters in id_start, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>\n   xid_start    ::= <all characters in id_start whose NFKC normalization is in "id_start xid_continue*">\n   xid_continue ::= <all characters in id_continue whose NFKC normalization is in "id_continue*">\n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\n* *Other_ID_Start* - explicit list of characters in PropList.txt to\n  support backwards compatibility\n\n* *Other_ID_Continue* - likewise\n\nAll identifiers are converted into the normal form NFKC while parsing;\ncomparison of identifiers is based on NFKC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at https://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers.  They must\nbe spelled exactly as written here:\n\n   False      class      finally    is         return\n   None       continue   for        lambda     try\n   True       def        from       nonlocal   while\n   and        del        global     not        with\n   as         elif       if         or         yield\n   assert     else       import     pass\n   break      except     in         raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings.  These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n   Not imported by "from module import *".  The special identifier "_"\n   is used in the interactive interpreter to store the result of the\n   last evaluation; it is stored in the "builtins" module.  When not\n   in interactive mode, "_" has no special meaning and is not defined.\n   See section *The import statement*.\n\n   Note: The name "_" is often used in conjunction with\n     internationalization; refer to the documentation for the\n     "gettext" module for more information on this convention.\n\n"__*__"\n   System-defined names. These names are defined by the interpreter\n   and its implementation (including the standard library).  Current\n   system names are discussed in the *Special method names* section\n   and elsewhere.  More will likely be defined in future versions of\n   Python.  *Any* use of "__*__" names, in any context, that does not\n   follow explicitly documented use, is subject to breakage without\n   warning.\n\n"__*"\n   Class-private names.  Names in this category, when used within the\n   context of a class definition, are re-written to use a mangled form\n   to help avoid name clashes between "private" attributes of base and\n   derived classes. See section *Identifiers (Names)*.\n',
  'if': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n   if_stmt ::= "if" expression ":" suite\n               ( "elif" expression ":" suite )*\n               ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n',
  'imaginary': u'\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n   imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range.  To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., "(3+4j)".  Some examples of imaginary literals:\n\n   3.14j   10.j    10j     .001j   1e100j  3.14e-10j\n',
- 'import': u'\nThe "import" statement\n**********************\n\n   import_stmt     ::= "import" module ["as" name] ( "," module ["as" name] )*\n                   | "from" relative_module "import" identifier ["as" name]\n                   ( "," identifier ["as" name] )*\n                   | "from" relative_module "import" "(" identifier ["as" name]\n                   ( "," identifier ["as" name] )* [","] ")"\n                   | "from" module "import" "*"\n   module          ::= (identifier ".")* identifier\n   relative_module ::= "."* module | "."+\n   name            ::= identifier\n\nThe basic import statement (no "from" clause) is executed in two\nsteps:\n\n1. find a module, loading and initializing it if necessary\n\n2. define a name or names in the local namespace for the scope\n   where the "import" statement occurs.\n\nWhen the statement contains multiple clauses (separated by commas) the\ntwo steps are carried out separately for each clause, just as though\nthe clauses had been separated out into individiual import statements.\n\nThe details of the first step, finding and loading modules are\ndescribed in greater detail in the section on the *import system*,\nwhich also describes the various types of packages and modules that\ncan be imported, as well as all the hooks that can be used to\ncustomize the import system. Note that failures in this step may\nindicate either that the module could not be located, *or* that an\nerror occurred while initializing the module, which includes execution\nof the module\'s code.\n\nIf the requested module is retrieved successfully, it will be made\navailable in the local namespace in one of three ways:\n\n* If the module name is followed by "as", then the name following\n  "as" is bound directly to the imported module.\n\n* If no other name is specified, and the module being imported is a\n  top level module, the module\'s name is bound in the local namespace\n  as a reference to the imported module\n\n* If the module being imported is *not* a top level module, then the\n  name of the top level package that contains the module is bound in\n  the local namespace as a reference to the top level package. The\n  imported module must be accessed using its full qualified name\n  rather than directly\n\nThe "from" form uses a slightly more complex process:\n\n1. find the module specified in the "from" clause, loading and\n   initializing it if necessary;\n\n2. for each of the identifiers specified in the "import" clauses:\n\n   1. check if the imported module has an attribute by that name\n\n   2. if not, attempt to import a submodule with that name and then\n      check the imported module again for that attribute\n\n   3. if the attribute is not found, "ImportError" is raised.\n\n   4. otherwise, a reference to that value is stored in the local\n      namespace, using the name in the "as" clause if it is present,\n      otherwise using the attribute name\n\nExamples:\n\n   import foo                 # foo imported and bound locally\n   import foo.bar.baz         # foo.bar.baz imported, foo bound locally\n   import foo.bar.baz as fbb  # foo.bar.baz imported and bound as fbb\n   from foo.bar import baz    # foo.bar.baz imported and bound as baz\n   from foo import attr       # foo imported and foo.attr bound as attr\n\nIf the list of identifiers is replaced by a star ("\'*\'"), all public\nnames defined in the module are bound in the local namespace for the\nscope where the "import" statement occurs.\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named "__all__"; if defined, it must\nbe a sequence of strings which are names defined or imported by that\nmodule.  The names given in "__all__" are all considered public and\nare required to exist.  If "__all__" is not defined, the set of public\nnames includes all names found in the module\'s namespace which do not\nbegin with an underscore character ("\'_\'").  "__all__" should contain\nthe entire public API. It is intended to avoid accidentally exporting\nitems that are not part of the API (such as library modules which were\nimported and used within the module).\n\nThe wild card form of import --- "from module import *" --- is only\nallowed at the module level.  Attempting to use it in class or\nfunction definitions will raise a "SyntaxError".\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after "from" you\ncan specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n"from . import mod" from a module in the "pkg" package then you will\nend up importing "pkg.mod". If you execute "from ..subpkg2 import mod"\nfrom within "pkg.subpkg1" you will import "pkg.subpkg2.mod". The\nspecification for relative imports is contained within **PEP 328**.\n\n"importlib.import_module()" is provided to support applications that\ndetermine dynamically the modules to be loaded.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python where the feature\nbecomes standard.\n\nThe future statement is intended to ease migration to future versions\nof Python that introduce incompatible changes to the language.  It\nallows use of the new features on a per-module basis before the\nrelease in which the feature becomes standard.\n\n   future_statement ::= "from" "__future__" "import" feature ["as" name]\n                        ("," feature ["as" name])*\n                        | "from" "__future__" "import" "(" feature ["as" name]\n                        ("," feature ["as" name])* [","] ")"\n   feature          ::= identifier\n   name             ::= identifier\n\nA future statement must appear near the top of the module.  The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are "absolute_import",\n"division", "generators", "unicode_literals", "print_function",\n"nested_scopes" and "with_statement".  They are all redundant because\nthey are always enabled, and only kept for backwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code.  It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently.  Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module "__future__", described later, and it will\nbe imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n   import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions "exec()" and\n"compile()" that occur in a module "M" containing a future statement\nwill, by default, use the new syntax or semantics associated with the\nfuture statement.  This can be controlled by optional arguments to\n"compile()" --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session.  If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also: **PEP 236** - Back to the __future__\n\n     The original proposal for the __future__ mechanism.\n',
+ 'import': u'\nThe "import" statement\n**********************\n\n   import_stmt     ::= "import" module ["as" name] ( "," module ["as" name] )*\n                   | "from" relative_module "import" identifier ["as" name]\n                   ( "," identifier ["as" name] )*\n                   | "from" relative_module "import" "(" identifier ["as" name]\n                   ( "," identifier ["as" name] )* [","] ")"\n                   | "from" module "import" "*"\n   module          ::= (identifier ".")* identifier\n   relative_module ::= "."* module | "."+\n   name            ::= identifier\n\nThe basic import statement (no "from" clause) is executed in two\nsteps:\n\n1. find a module, loading and initializing it if necessary\n\n2. define a name or names in the local namespace for the scope\n   where the "import" statement occurs.\n\nWhen the statement contains multiple clauses (separated by commas) the\ntwo steps are carried out separately for each clause, just as though\nthe clauses had been separated out into individual import statements.\n\nThe details of the first step, finding and loading modules are\ndescribed in greater detail in the section on the *import system*,\nwhich also describes the various types of packages and modules that\ncan be imported, as well as all the hooks that can be used to\ncustomize the import system. Note that failures in this step may\nindicate either that the module could not be located, *or* that an\nerror occurred while initializing the module, which includes execution\nof the module\'s code.\n\nIf the requested module is retrieved successfully, it will be made\navailable in the local namespace in one of three ways:\n\n* If the module name is followed by "as", then the name following\n  "as" is bound directly to the imported module.\n\n* If no other name is specified, and the module being imported is a\n  top level module, the module\'s name is bound in the local namespace\n  as a reference to the imported module\n\n* If the module being imported is *not* a top level module, then the\n  name of the top level package that contains the module is bound in\n  the local namespace as a reference to the top level package. The\n  imported module must be accessed using its full qualified name\n  rather than directly\n\nThe "from" form uses a slightly more complex process:\n\n1. find the module specified in the "from" clause, loading and\n   initializing it if necessary;\n\n2. for each of the identifiers specified in the "import" clauses:\n\n   1. check if the imported module has an attribute by that name\n\n   2. if not, attempt to import a submodule with that name and then\n      check the imported module again for that attribute\n\n   3. if the attribute is not found, "ImportError" is raised.\n\n   4. otherwise, a reference to that value is stored in the local\n      namespace, using the name in the "as" clause if it is present,\n      otherwise using the attribute name\n\nExamples:\n\n   import foo                 # foo imported and bound locally\n   import foo.bar.baz         # foo.bar.baz imported, foo bound locally\n   import foo.bar.baz as fbb  # foo.bar.baz imported and bound as fbb\n   from foo.bar import baz    # foo.bar.baz imported and bound as baz\n   from foo import attr       # foo imported and foo.attr bound as attr\n\nIf the list of identifiers is replaced by a star ("\'*\'"), all public\nnames defined in the module are bound in the local namespace for the\nscope where the "import" statement occurs.\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named "__all__"; if defined, it must\nbe a sequence of strings which are names defined or imported by that\nmodule.  The names given in "__all__" are all considered public and\nare required to exist.  If "__all__" is not defined, the set of public\nnames includes all names found in the module\'s namespace which do not\nbegin with an underscore character ("\'_\'").  "__all__" should contain\nthe entire public API. It is intended to avoid accidentally exporting\nitems that are not part of the API (such as library modules which were\nimported and used within the module).\n\nThe wild card form of import --- "from module import *" --- is only\nallowed at the module level.  Attempting to use it in class or\nfunction definitions will raise a "SyntaxError".\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after "from" you\ncan specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n"from . import mod" from a module in the "pkg" package then you will\nend up importing "pkg.mod". If you execute "from ..subpkg2 import mod"\nfrom within "pkg.subpkg1" you will import "pkg.subpkg2.mod". The\nspecification for relative imports is contained within **PEP 328**.\n\n"importlib.import_module()" is provided to support applications that\ndetermine dynamically the modules to be loaded.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python where the feature\nbecomes standard.\n\nThe future statement is intended to ease migration to future versions\nof Python that introduce incompatible changes to the language.  It\nallows use of the new features on a per-module basis before the\nrelease in which the feature becomes standard.\n\n   future_statement ::= "from" "__future__" "import" feature ["as" name]\n                        ("," feature ["as" name])*\n                        | "from" "__future__" "import" "(" feature ["as" name]\n                        ("," feature ["as" name])* [","] ")"\n   feature          ::= identifier\n   name             ::= identifier\n\nA future statement must appear near the top of the module.  The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are "absolute_import",\n"division", "generators", "unicode_literals", "print_function",\n"nested_scopes" and "with_statement".  They are all redundant because\nthey are always enabled, and only kept for backwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code.  It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently.  Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module "__future__", described later, and it will\nbe imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n   import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions "exec()" and\n"compile()" that occur in a module "M" containing a future statement\nwill, by default, use the new syntax or semantics associated with the\nfuture statement.  This can be controlled by optional arguments to\n"compile()" --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session.  If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also: **PEP 236** - Back to the __future__\n\n     The original proposal for the __future__ mechanism.\n',
  'in': u'\nMembership test operations\n**************************\n\nThe operators "in" and "not in" test for membership.  "x in s"\nevaluates to true if *x* is a member of *s*, and false otherwise.  "x\nnot in s" returns the negation of "x in s".  All built-in sequences\nand set types support this as well as dictionary, for which "in" tests\nwhether the dictionary has a given key. For container types such as\nlist, tuple, set, frozenset, dict, or collections.deque, the\nexpression "x in y" is equivalent to "any(x is e or x == e for e in\ny)".\n\nFor the string and bytes types, "x in y" is true if and only if *x* is\na substring of *y*.  An equivalent test is "y.find(x) != -1".  Empty\nstrings are always considered to be a substring of any other string,\nso """ in "abc"" will return "True".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y".  If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception.  (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n',
  'integers': u'\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n   integer        ::= decimalinteger | octinteger | hexinteger | bininteger\n   decimalinteger ::= nonzerodigit digit* | "0"+\n   nonzerodigit   ::= "1"..."9"\n   digit          ::= "0"..."9"\n   octinteger     ::= "0" ("o" | "O") octdigit+\n   hexinteger     ::= "0" ("x" | "X") hexdigit+\n   bininteger     ::= "0" ("b" | "B") bindigit+\n   octdigit       ::= "0"..."7"\n   hexdigit       ::= digit | "a"..."f" | "A"..."F"\n   bindigit       ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n   7     2147483647                        0o177    0b100110111\n   3     79228162514264337593543950336     0o377    0xdeadbeef\n',
  'lambda': u'\nLambdas\n*******\n\n   lambda_expr        ::= "lambda" [parameter_list]: expression\n   lambda_expr_nocond ::= "lambda" [parameter_list]: expression_nocond\n\nLambda expressions (sometimes called lambda forms) are used to create\nanonymous functions. The expression "lambda arguments: expression"\nyields a function object.  The unnamed object behaves like a function\nobject defined with\n\n   def <lambda>(arguments):\n       return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda expressions cannot contain\nstatements or annotations.\n',
- 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n   list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension.  When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n',
+ 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n   list_display ::= "[" [starred_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension.  When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n',
  'naming': u'\nNaming and binding\n******************\n\n\nBinding of names\n================\n\n*Names* refer to objects.  Names are introduced by name binding\noperations.\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, or after\n"as" in a "with" statement or "except" clause. The "import" statement\nof the form "from ... import *" binds all names defined in the\nimported module, except those beginning with an underscore.  This form\nmay only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as "nonlocal" or "global".  If a name is bound at the\nmodule level, it is a global variable.  (The variables of the module\ncode block are local and global.)  If a variable is used in a code\nblock but not defined there, it is a *free variable*.\n\nEach occurrence of a name in the program text refers to the *binding*\nof that name established by the following name resolution rules.\n\n\nResolution of names\n===================\n\nA *scope* defines the visibility of a name within a block.  If a local\nvariable is defined in a block, its scope includes that block.  If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name.\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope.  The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nWhen a name is not found at all, a "NameError" exception is raised. If\nthe current scope is a function scope, and the name refers to a local\nvariable that has not yet been bound to a value at the point where the\nname is used, an "UnboundLocalError" exception is raised.\n"UnboundLocalError" is a subclass of "NameError".\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block.  This can lead to errors when a name is used within a\nblock before it is bound.  This rule is subtle.  Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block.  The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the "global" statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace.  Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "builtins".  The global namespace is searched first.  If\nthe name is not found there, the builtins namespace is searched.  The\n"global" statement must precede all uses of the name.\n\nThe "global" statement has the same scope as a name binding operation\nin the same block.  If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nThe "nonlocal" statement causes corresponding names to refer to\npreviously bound variables in the nearest enclosing function scope.\n"SyntaxError" is raised at compile time if the given name does not\nexist in any enclosing function scope.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported.  The main module for a script is always called\n"__main__".\n\nClass definition blocks and arguments to "exec()" and "eval()" are\nspecial in the context of name resolution. A class definition is an\nexecutable statement that may use and define names. These references\nfollow the normal rules for name resolution with an exception that\nunbound local variables are looked up in the global namespace. The\nnamespace of the class definition becomes the attribute dictionary of\nthe class. The scope of names defined in a class block is limited to\nthe class block; it does not extend to the code blocks of methods --\nthis includes comprehensions and generator expressions since they are\nimplemented using a function scope.  This means that the following\nwill fail:\n\n   class A:\n       a = 42\n       b = list(a + i for i in range(10))\n\n\nBuiltins and restricted execution\n=================================\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used).  By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "builtins"; when in any\nother module, "__builtins__" is an alias for the dictionary of the\n"builtins" module itself.  "__builtins__" can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail.  Users\nwanting to override values in the builtins namespace should "import"\nthe "builtins" module and modify its attributes appropriately.\n\n\nInteraction with dynamic features\n=================================\n\nName resolution of free variables occurs at runtime, not at compile\ntime. This means that the following code will print 42:\n\n   i = 10\n   def f():\n       print(i)\n   i = 42\n   f()\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name.  An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names.  Names may be resolved in the local\nand global namespaces of the caller.  Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace.  [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace.  If only one namespace is\nspecified, it is used for both.\n',
  'nonlocal': u'\nThe "nonlocal" statement\n************************\n\n   nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n\nThe "nonlocal" statement causes the listed identifiers to refer to\npreviously bound variables in the nearest enclosing scope excluding\nglobals. This is important because the default behavior for binding is\nto search the local namespace first.  The statement allows\nencapsulated code to rebind variables outside of the local scope\nbesides the global (module) scope.\n\nNames listed in a "nonlocal" statement, unlike those listed in a\n"global" statement, must refer to pre-existing bindings in an\nenclosing scope (the scope in which a new binding should be created\ncannot be determined unambiguously).\n\nNames listed in a "nonlocal" statement must not collide with pre-\nexisting bindings in the local scope.\n\nSee also: **PEP 3104** - Access to Names in Outer Scopes\n\n     The specification for the "nonlocal" statement.\n',
  'numbers': u'\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers.  There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator \'"-"\' and the\nliteral "1".\n',
@@ -53,16 +53,16 @@ topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert
  'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data.  All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value.  An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory.  The \'"is"\' operator compares the\nidentity of two objects; the "id()" function returns an integer\nrepresenting its identity.\n\n**CPython implementation detail:** For CPython, "id(x)" is the memory\naddress where "x" is stored.\n\nAn object\'s type determines the operations that the object supports\n(e.g., "does it have a length?") and also defines the possible values\nfor objects of that type.  The "type()" function returns an object\'s\ntype (which is an object itself).  Like its identity, an object\'s\n*type* is also unchangeable. [1]\n\nThe *value* of some objects can change.  Objects whose value can\nchange are said to be *mutable*; objects whose value is unchangeable\nonce they are created are called *immutable*. (The value of an\nimmutable container object that contains a reference to a mutable\nobject can change when the latter\'s value is changed; however the\ncontainer is still considered immutable, because the collection of\nobjects it contains cannot be changed.  So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected.  An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references.  See the documentation of the "gc" module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (so\nyou should always close files explicitly).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'"try"..."except"\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows.  It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a "close()" method. Programs\nare strongly recommended to explicitly close such objects.  The\n\'"try"..."finally"\' statement and the \'"with"\' statement provide\nconvenient ways to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries.  The references are part of a container\'s value.  In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied.  So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior.  Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed.  E.g., after "a = 1; b = 1",\n"a" and "b" may or may not refer to the same object with the value\none, depending on the implementation, but after "c = []; d = []", "c"\nand "d" are guaranteed to refer to two different, unique, newly\ncreated empty lists. (Note that "c = d = []" assigns the same object\nto both "c" and "d".)\n',
  'operator-summary': u'\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedence in Python, from\nlowest precedence (least binding) to highest precedence (most\nbinding).  Operators in the same box have the same precedence.  Unless\nthe syntax is explicitly given, operators are binary.  Operators in\nthe same box group left to right (except for exponentiation, which\ngroups from right to left).\n\nNote that comparisons, membership tests, and identity tests, all have\nthe same precedence and have a left-to-right chaining feature as\ndescribed in the *Comparisons* section.\n\n+-------------------------------------------------+---------------------------------------+\n| Operator                                        | Description                           |\n+=================================================+=======================================+\n| "lambda"                                        | Lambda expression                     |\n+-------------------------------------------------+---------------------------------------+\n| "if" -- "else"                                  | Conditional expression                |\n+-------------------------------------------------+---------------------------------------+\n| "or"                                            | Boolean OR                            |\n+-------------------------------------------------+---------------------------------------+\n| "and"                                           | Boolean AND                           |\n+-------------------------------------------------+---------------------------------------+\n| "not" "x"                                       | Boolean NOT                           |\n+-------------------------------------------------+---------------------------------------+\n| "in", "not in", "is", "is not", "<", "<=", ">", | Comparisons, including membership     |\n| ">=", "!=", "=="                                | tests and identity tests              |\n+-------------------------------------------------+---------------------------------------+\n| "|"                                             | Bitwise OR                            |\n+-------------------------------------------------+---------------------------------------+\n| "^"                                             | Bitwise XOR                           |\n+-------------------------------------------------+---------------------------------------+\n| "&"                                             | Bitwise AND                           |\n+-------------------------------------------------+---------------------------------------+\n| "<<", ">>"                                      | Shifts                                |\n+-------------------------------------------------+---------------------------------------+\n| "+", "-"                                        | Addition and subtraction              |\n+-------------------------------------------------+---------------------------------------+\n| "*", "@", "/", "//", "%"                        | Multiplication, matrix multiplication |\n|                                                 | division, remainder [5]               |\n+-------------------------------------------------+---------------------------------------+\n| "+x", "-x", "~x"                                | Positive, negative, bitwise NOT       |\n+-------------------------------------------------+---------------------------------------+\n| "**"                                            | Exponentiation [6]                    |\n+-------------------------------------------------+---------------------------------------+\n| "await" "x"                                     | Await expression                      |\n+-------------------------------------------------+---------------------------------------+\n| "x[index]", "x[index:index]",                   | Subscription, slicing, call,          |\n| "x(arguments...)", "x.attribute"                | attribute reference                   |\n+-------------------------------------------------+---------------------------------------+\n| "(expressions...)", "[expressions...]", "{key:  | Binding or tuple display, list        |\n| value...}", "{expressions...}"                  | display, dictionary display, set      |\n|                                                 | display                               |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While "abs(x%y) < abs(y)" is true mathematically, for floats\n    it may not be true numerically due to roundoff.  For example, and\n    assuming a platform on which a Python float is an IEEE 754 double-\n    precision number, in order that "-1e-100 % 1e100" have the same\n    sign as "1e100", the computed result is "-1e-100 + 1e100", which\n    is numerically exactly equal to "1e100".  The function\n    "math.fmod()" returns a result whose sign matches the sign of the\n    first argument instead, and so returns "-1e-100" in this case.\n    Which approach is more appropriate depends on the application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n    possible for "x//y" to be one larger than "(x-x%y)//y" due to\n    rounding.  In such cases, Python returns the latter result, in\n    order to preserve that "divmod(x,y)[0] * y + x % y" be very close\n    to "x".\n\n[3] The Unicode standard distinguishes between *code points* (e.g.\n    U+0041) and *abstract characters* (e.g. "LATIN CAPITAL LETTER A").\n    While most abstract characters in Unicode are only represented\n    using one code point, there is a number of abstract characters\n    that can in addition be represented using a sequence of more than\n    one code point.  For example, the abstract character "LATIN\n    CAPITAL LETTER C WITH CEDILLA" can be represented as a single\n    *precomposed character* at code position U+00C7, or as a sequence\n    of a *base character* at code position U+0043 (LATIN CAPITAL\n    LETTER C), followed by a *combining character* at code position\n    U+0327 (COMBINING CEDILLA).\n\n    The comparison operators on strings compare at the level of\n    Unicode code points. This may be counter-intuitive to humans.  For\n    example, ""\\u00C7" == "\\u0043\\u0327"" is "False", even though both\n    strings represent the same abstract character "LATIN CAPITAL\n    LETTER C WITH CEDILLA".\n\n    To compare strings at the level of abstract characters (that is,\n    in a way intuitive to humans), use "unicodedata.normalize()".\n\n[4] Due to automatic garbage-collection, free lists, and the\n    dynamic nature of descriptors, you may notice seemingly unusual\n    behaviour in certain uses of the "is" operator, like those\n    involving comparisons between instance methods, or constants.\n    Check their documentation for more info.\n\n[5] The "%" operator is also used for string formatting; the same\n    precedence applies.\n\n[6] The power operator "**" binds less tightly than an arithmetic\n    or bitwise unary operator on its right, that is, "2**-1" is "0.5".\n',
  'pass': u'\nThe "pass" statement\n********************\n\n   pass_stmt ::= "pass"\n\n"pass" is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n   def f(arg): pass    # a function that does nothing (yet)\n\n   class C: pass       # a class with no methods (yet)\n',
- 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right.  The\nsyntax is:\n\n   power ::= await ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): "-1**2" results in "-1".\n\nThe power operator has the same semantics as the built-in "pow()"\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument.  The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n"10**2" returns "100", but "10**-2" returns "0.01".\n\nRaising "0.0" to a negative power results in a "ZeroDivisionError".\nRaising a negative number to a fractional power results in a "complex"\nnumber. (In earlier versions it raised a "ValueError".)\n',
+ 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right.  The\nsyntax is:\n\n   power ::= ( await_expr | primary ) ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): "-1**2" results in "-1".\n\nThe power operator has the same semantics as the built-in "pow()"\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument.  The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n"10**2" returns "100", but "10**-2" returns "0.01".\n\nRaising "0.0" to a negative power results in a "ZeroDivisionError".\nRaising a negative number to a fractional power results in a "complex"\nnumber. (In earlier versions it raised a "ValueError".)\n',
  'raise': u'\nThe "raise" statement\n*********************\n\n   raise_stmt ::= "raise" [expression ["from" expression]]\n\nIf no expressions are present, "raise" re-raises the last exception\nthat was active in the current scope.  If no exception is active in\nthe current scope, a "RuntimeError" exception is raised indicating\nthat this is an error.\n\nOtherwise, "raise" evaluates the first expression as the exception\nobject.  It must be either a subclass or an instance of\n"BaseException". If it is a class, the exception instance will be\nobtained when needed by instantiating the class with no arguments.\n\nThe *type* of the exception is the exception instance\'s class, the\n*value* is the instance itself.\n\nA traceback object is normally created automatically when an exception\nis raised and attached to it as the "__traceback__" attribute, which\nis writable. You can create an exception and set your own traceback in\none step using the "with_traceback()" exception method (which returns\nthe same exception instance, with its traceback set to its argument),\nlike so:\n\n   raise Exception("foo occurred").with_traceback(tracebackobj)\n\nThe "from" clause is used for exception chaining: if given, the second\n*expression* must be another exception class or instance, which will\nthen be attached to the raised exception as the "__cause__" attribute\n(which is writable).  If the raised exception is not handled, both\nexceptions will be printed:\n\n   >>> try:\n   ...     print(1 / 0)\n   ... except Exception as exc:\n   ...     raise RuntimeError("Something bad happened") from exc\n   ...\n   Traceback (most recent call last):\n     File "<stdin>", line 2, in <module>\n   ZeroDivisionError: int division or modulo by zero\n\n   The above exception was the direct cause of the following exception:\n\n   Traceback (most recent call last):\n     File "<stdin>", line 4, in <module>\n   RuntimeError: Something bad happened\n\nA similar mechanism works implicitly if an exception is raised inside\nan exception handler or a "finally" clause: the previous exception is\nthen attached as the new exception\'s "__context__" attribute:\n\n   >>> try:\n   ...     print(1 / 0)\n   ... except:\n   ...     raise RuntimeError("Something bad happened")\n   ...\n   Traceback (most recent call last):\n     File "<stdin>", line 2, in <module>\n   ZeroDivisionError: int division or modulo by zero\n\n   During handling of the above exception, another exception occurred:\n\n   Traceback (most recent call last):\n     File "<stdin>", line 4, in <module>\n   RuntimeError: Something bad happened\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n',
  'return': u'\nThe "return" statement\n**********************\n\n   return_stmt ::= "return" [expression_list]\n\n"return" may only occur syntactically nested in a function definition,\nnot within a nested class definition.\n\nIf an expression list is present, it is evaluated, else "None" is\nsubstituted.\n\n"return" leaves the current function call with the expression list (or\n"None") as return value.\n\nWhen "return" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nfunction.\n\nIn a generator function, the "return" statement indicates that the\ngenerator is done and will cause "StopIteration" to be raised. The\nreturned value (if any) is used as an argument to construct\n"StopIteration" and becomes the "StopIteration.value" attribute.\n',
  'sequence-types': u'\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well.  The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items.  It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects.  Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators.  It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values.  It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n   Called to implement the built-in function "len()".  Should return\n   the length of the object, an integer ">=" 0.  Also, an object that\n   doesn\'t define a "__bool__()" method and whose "__len__()" method\n   returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n   Called to implement "operator.length_hint()". Should return an\n   estimated length for the object (which may be greater or less than\n   the actual length). The length must be an integer ">=" 0. This\n   method is purely an optimization and is never required for\n   correctness.\n\n   New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n  A call like\n\n     a[1:2] = b\n\n  is translated to\n\n     a[slice(1, 2, None)] = b\n\n  and so forth.  Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n   Called to implement evaluation of "self[key]". For sequence types,\n   the accepted keys should be integers and slice objects.  Note that\n   the special interpretation of negative indexes (if the class wishes\n   to emulate a sequence type) is up to the "__getitem__()" method. If\n   *key* is of an inappropriate type, "TypeError" may be raised; if of\n   a value outside the set of indexes for the sequence (after any\n   special interpretation of negative values), "IndexError" should be\n   raised. For mapping types, if *key* is missing (not in the\n   container), "KeyError" should be raised.\n\n   Note: "for" loops expect that an "IndexError" will be raised for\n     illegal indexes to allow proper detection of the end of the\n     sequence.\n\nobject.__missing__(self, key)\n\n   Called by "dict"."__getitem__()" to implement "self[key]" for dict\n   subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n   Called to implement assignment to "self[key]".  Same note as for\n   "__getitem__()".  This should only be implemented for mappings if\n   the objects support changes to the values for keys, or if new keys\n   can be added, or for sequences if elements can be replaced.  The\n   same exceptions should be raised for improper *key* values as for\n   the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n   Called to implement deletion of "self[key]".  Same note as for\n   "__getitem__()".  This should only be implemented for mappings if\n   the objects support removal of keys, or for sequences if elements\n   can be removed from the sequence.  The same exceptions should be\n   raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n   This method is called when an iterator is required for a container.\n   This method should return a new iterator object that can iterate\n   over all the objects in the container.  For mappings, it should\n   iterate over the keys of the container.\n\n   Iterator objects also need to implement this method; they are\n   required to return themselves.  For more information on iterator\n   objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n   Called (if present) by the "reversed()" built-in to implement\n   reverse iteration.  It should return a new iterator object that\n   iterates over all the objects in the container in reverse order.\n\n   If the "__reversed__()" method is not provided, the "reversed()"\n   built-in will fall back to using the sequence protocol ("__len__()"\n   and "__getitem__()").  Objects that support the sequence protocol\n   should only provide "__reversed__()" if they can provide an\n   implementation that is more efficient than the one provided by\n   "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence.  However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n   Called to implement membership test operators.  Should return true\n   if *item* is in *self*, false otherwise.  For mapping objects, this\n   should consider the keys of the mapping rather than the values or\n   the key-item pairs.\n\n   For objects that don\'t define "__contains__()", the membership test\n   first tries iteration via "__iter__()", then the old sequence\n   iteration protocol via "__getitem__()", see *this section in the\n   language reference*.\n',
  'shifting': u'\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n   shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept integers as arguments.  They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as floor division by "pow(2,n)".\nA left shift by *n* bits is defined as multiplication with "pow(2,n)".\n\nNote: In the current implementation, the right-hand operand is\n  required to be at most "sys.maxsize".  If the right-hand operand is\n  larger than "sys.maxsize" an "OverflowError" exception is raised.\n',
  'slicings': u'\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list).  Slicings may be used as expressions or as\ntargets in assignment or "del" statements.  The syntax for a slicing:\n\n   slicing      ::= primary "[" slice_list "]"\n   slice_list   ::= slice_item ("," slice_item)* [","]\n   slice_item   ::= expression | proper_slice\n   proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n   lower_bound  ::= expression\n   upper_bound  ::= expression\n   stride       ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing.  Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows.  The primary is indexed\n(using the same "__getitem__()" method as normal subscription) with a\nkey that is constructed from the slice list, as follows.  If the slice\nlist contains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key.  The conversion of a slice item that is an\nexpression is that expression.  The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n"start", "stop" and "step" attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting "None" for missing expressions.\n',
  'specialattrs': u'\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant.  Some of these are not reported\nby the "dir()" built-in function.\n\nobject.__dict__\n\n   A dictionary or other mapping object used to store an object\'s\n   (writable) attributes.\n\ninstance.__class__\n\n   The class to which a class instance belongs.\n\nclass.__bases__\n\n   The tuple of base classes of a class object.\n\nclass.__name__\n\n   The name of the class or type.\n\nclass.__qualname__\n\n   The *qualified name* of the class or type.\n\n   New in version 3.3.\n\nclass.__mro__\n\n   This attribute is a tuple of classes that are considered when\n   looking for base classes during method resolution.\n\nclass.mro()\n\n   This method can be overridden by a metaclass to customize the\n   method resolution order for its instances.  It is called at class\n   instantiation, and its result is stored in "__mro__".\n\nclass.__subclasses__()\n\n   Each class keeps a list of weak references to its immediate\n   subclasses.  This method returns a list of all those references\n   still alive. Example:\n\n      >>> int.__subclasses__()\n      [<class \'bool\'>]\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found\n    in the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list "[1, 2]" is considered equal to\n    "[1.0, 2.0]", and similarly for tuples.\n\n[3] They must have since the parser can\'t tell the type of the\n    operands.\n\n[4] Cased characters are those with general category property\n    being one of "Lu" (Letter, uppercase), "Ll" (Letter, lowercase),\n    or "Lt" (Letter, titlecase).\n\n[5] To format only a tuple you should therefore provide a\n    singleton tuple whose only element is the tuple to be formatted.\n',
- 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators.  For instance, if a class defines\na method named "__getitem__()", and "x" is an instance of this class,\nthen "x[i]" is roughly equivalent to "type(x).__getitem__(x, i)".\nExcept where mentioned, attempts to execute an operation raise an\nexception when no appropriate method is defined (typically\n"AttributeError" or "TypeError").\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled.  For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense.  (One example of this is the\n"NodeList" interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n   Called to create a new instance of class *cls*.  "__new__()" is a\n   static method (special-cased so you need not declare it as such)\n   that takes the class of which an instance was requested as its\n   first argument.  The remaining arguments are those passed to the\n   object constructor expression (the call to the class).  The return\n   value of "__new__()" should be the new object instance (usually an\n   instance of *cls*).\n\n   Typical implementations create a new instance of the class by\n   invoking the superclass\'s "__new__()" method using\n   "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n   arguments and then modifying the newly-created instance as\n   necessary before returning it.\n\n   If "__new__()" returns an instance of *cls*, then the new\n   instance\'s "__init__()" method will be invoked like\n   "__init__(self[, ...])", where *self* is the new instance and the\n   remaining arguments are the same as were passed to "__new__()".\n\n   If "__new__()" does not return an instance of *cls*, then the new\n   instance\'s "__init__()" method will not be invoked.\n\n   "__new__()" is intended mainly to allow subclasses of immutable\n   types (like int, str, or tuple) to customize instance creation.  It\n   is also commonly overridden in custom metaclasses in order to\n   customize class creation.\n\nobject.__init__(self[, ...])\n\n   Called after the instance has been created (by "__new__()"), but\n   before it is returned to the caller.  The arguments are those\n   passed to the class constructor expression.  If a base class has an\n   "__init__()" method, the derived class\'s "__init__()" method, if\n   any, must explicitly call it to ensure proper initialization of the\n   base class part of the instance; for example:\n   "BaseClass.__init__(self, [args...])".\n\n   Because "__new__()" and "__init__()" work together in constructing\n   objects ("__new__()" to create it, and "__init__()" to customise\n   it), no non-"None" value may be returned by "__init__()"; doing so\n   will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n   Called when the instance is about to be destroyed.  This is also\n   called a destructor.  If a base class has a "__del__()" method, the\n   derived class\'s "__del__()" method, if any, must explicitly call it\n   to ensure proper deletion of the base class part of the instance.\n   Note that it is possible (though not recommended!) for the\n   "__del__()" method to postpone destruction of the instance by\n   creating a new reference to it.  It may then be called at a later\n   time when this new reference is deleted.  It is not guaranteed that\n   "__del__()" methods are called for objects that still exist when\n   the interpreter exits.\n\n   Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n     decrements the reference count for "x" by one, and the latter is\n     only called when "x"\'s reference count reaches zero.  Some common\n     situations that may prevent the reference count of an object from\n     going to zero include: circular references between objects (e.g.,\n     a doubly-linked list or a tree data structure with parent and\n     child pointers); a reference to the object on the stack frame of\n     a function that caught an exception (the traceback stored in\n     "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n     to the object on the stack frame that raised an unhandled\n     exception in interactive mode (the traceback stored in\n     "sys.last_traceback" keeps the stack frame alive).  The first\n     situation can only be remedied by explicitly breaking the cycles;\n     the second can be resolved by freeing the reference to the\n     traceback object when it is no longer useful, and the third can\n     be resolved by storing "None" in "sys.last_traceback". Circular\n     references which are garbage are detected and cleaned up when the\n     cyclic garbage collector is enabled (it\'s on by default). Refer\n     to the documentation for the "gc" module for more information\n     about this topic.\n\n   Warning: Due to the precarious circumstances under which\n     "__del__()" methods are invoked, exceptions that occur during\n     their execution are ignored, and a warning is printed to\n     "sys.stderr" instead. Also, when "__del__()" is invoked in\n     response to a module being deleted (e.g., when execution of the\n     program is done), other globals referenced by the "__del__()"\n     method may already have been deleted or in the process of being\n     torn down (e.g. the import machinery shutting down).  For this\n     reason, "__del__()" methods should do the absolute minimum needed\n     to maintain external invariants.  Starting with version 1.5,\n     Python guarantees that globals whose name begins with a single\n     underscore are deleted from their module before other globals are\n     deleted; if no other references to such globals exist, this may\n     help in assuring that imported modules are still available at the\n     time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n   Called by the "repr()" built-in function to compute the "official"\n   string representation of an object.  If at all possible, this\n   should look like a valid Python expression that could be used to\n   recreate an object with the same value (given an appropriate\n   environment).  If this is not possible, a string of the form\n   "<...some useful description...>" should be returned. The return\n   value must be a string object. If a class defines "__repr__()" but\n   not "__str__()", then "__repr__()" is also used when an "informal"\n   string representation of instances of that class is required.\n\n   This is typically used for debugging, so it is important that the\n   representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n   Called by "str(object)" and the built-in functions "format()" and\n   "print()" to compute the "informal" or nicely printable string\n   representation of an object.  The return value must be a *string*\n   object.\n\n   This method differs from "object.__repr__()" in that there is no\n   expectation that "__str__()" return a valid Python expression: a\n   more convenient or concise representation can be used.\n\n   The default implementation defined by the built-in type "object"\n   calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n   Called by "bytes()" to compute a byte-string representation of an\n   object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n   Called by the "format()" built-in function (and by extension, the\n   "str.format()" method of class "str") to produce a "formatted"\n   string representation of an object. The "format_spec" argument is a\n   string that contains a description of the formatting options\n   desired. The interpretation of the "format_spec" argument is up to\n   the type implementing "__format__()", however most classes will\n   either delegate formatting to one of the built-in types, or use a\n   similar formatting option syntax.\n\n   See *Format Specification Mini-Language* for a description of the\n   standard formatting syntax.\n\n   The return value must be a string object.\n\n   Changed in version 3.4: The __format__ method of "object" itself\n   raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n   These are the so-called "rich comparison" methods. The\n   correspondence between operator symbols and method names is as\n   follows: "x<y" calls "x.__lt__(y)", "x<=y" calls "x.__le__(y)",\n   "x==y" calls "x.__eq__(y)", "x!=y" calls "x.__ne__(y)", "x>y" calls\n   "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n   A rich comparison method may return the singleton "NotImplemented"\n   if it does not implement the operation for a given pair of\n   arguments. By convention, "False" and "True" are returned for a\n   successful comparison. However, these methods can return any value,\n   so if the comparison operator is used in a Boolean context (e.g.,\n   in the condition of an "if" statement), Python will call "bool()"\n   on the value to determine if the result is true or false.\n\n   By default, "__ne__()" delegates to "__eq__()" and inverts the\n   result unless it is "NotImplemented".  There are no other implied\n   relationships among the comparison operators, for example, the\n   truth of "(x<y or x==y)" does not imply "x<=y". To automatically\n   generate ordering operations from a single root operation, see\n   "functools.total_ordering()".\n\n   See the paragraph on "__hash__()" for some important notes on\n   creating *hashable* objects which support custom comparison\n   operations and are usable as dictionary keys.\n\n   There are no swapped-argument versions of these methods (to be used\n   when the left argument does not support the operation but the right\n   argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n   reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n   and "__eq__()" and "__ne__()" are their own reflection. If the\n   operands are of different types, and right operand\'s type is a\n   direct or indirect subclass of the left operand\'s type, the\n   reflected method of the right operand has priority, otherwise the\n   left operand\'s method has priority.  Virtual subclassing is not\n   considered.\n\nobject.__hash__(self)\n\n   Called by built-in function "hash()" and for operations on members\n   of hashed collections including "set", "frozenset", and "dict".\n   "__hash__()" should return an integer.  The only required property\n   is that objects which compare equal have the same hash value; it is\n   advised to somehow mix together (e.g. using exclusive or) the hash\n   values for the components of the object that also play a part in\n   comparison of objects.\n\n   Note: "hash()" truncates the value returned from an object\'s\n     custom "__hash__()" method to the size of a "Py_ssize_t".  This\n     is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit\n     builds. If an object\'s   "__hash__()" must interoperate on builds\n     of different bit sizes, be sure to check the width on all\n     supported builds.  An easy way to do this is with "python -c\n     "import sys; print(sys.hash_info.width)"".\n\n   If a class does not define an "__eq__()" method it should not\n   define a "__hash__()" operation either; if it defines "__eq__()"\n   but not "__hash__()", its instances will not be usable as items in\n   hashable collections.  If a class defines mutable objects and\n   implements an "__eq__()" method, it should not implement\n   "__hash__()", since the implementation of hashable collections\n   requires that a key\'s hash value is immutable (if the object\'s hash\n   value changes, it will be in the wrong hash bucket).\n\n   User-defined classes have "__eq__()" and "__hash__()" methods by\n   default; with them, all objects compare unequal (except with\n   themselves) and "x.__hash__()" returns an appropriate value such\n   that "x == y" implies both that "x is y" and "hash(x) == hash(y)".\n\n   A class that overrides "__eq__()" and does not define "__hash__()"\n   will have its "__hash__()" implicitly set to "None".  When the\n   "__hash__()" method of a class is "None", instances of the class\n   will raise an appropriate "TypeError" when a program attempts to\n   retrieve their hash value, and will also be correctly identified as\n   unhashable when checking "isinstance(obj, collections.Hashable)".\n\n   If a class that overrides "__eq__()" needs to retain the\n   implementation of "__hash__()" from a parent class, the interpreter\n   must be told this explicitly by setting "__hash__ =\n   <ParentClass>.__hash__".\n\n   If a class that does not override "__eq__()" wishes to suppress\n   hash support, it should include "__hash__ = None" in the class\n   definition. A class which defines its own "__hash__()" that\n   explicitly raises a "TypeError" would be incorrectly identified as\n   hashable by an "isinstance(obj, collections.Hashable)" call.\n\n   Note: By default, the "__hash__()" values of str, bytes and\n     datetime objects are "salted" with an unpredictable random value.\n     Although they remain constant within an individual Python\n     process, they are not predictable between repeated invocations of\n     Python.This is intended to provide protection against a denial-\n     of-service caused by carefully-chosen inputs that exploit the\n     worst case performance of a dict insertion, O(n^2) complexity.\n     See http://www.ocert.org/advisories/ocert-2011-003.html for\n     details.Changing hash values affects the iteration order of\n     dicts, sets and other mappings.  Python has never made guarantees\n     about this ordering (and it typically varies between 32-bit and\n     64-bit builds).See also "PYTHONHASHSEED".\n\n   Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n   Called to implement truth value testing and the built-in operation\n   "bool()"; should return "False" or "True".  When this method is not\n   defined, "__len__()" is called, if it is defined, and the object is\n   considered true if its result is nonzero.  If a class defines\n   neither "__len__()" nor "__bool__()", all its instances are\n   considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n   Called when an attribute lookup has not found the attribute in the\n   usual places (i.e. it is not an instance attribute nor is it found\n   in the class tree for "self").  "name" is the attribute name. This\n   method should return the (computed) attribute value or raise an\n   "AttributeError" exception.\n\n   Note that if the attribute is found through the normal mechanism,\n   "__getattr__()" is not called.  (This is an intentional asymmetry\n   between "__getattr__()" and "__setattr__()".) This is done both for\n   efficiency reasons and because otherwise "__getattr__()" would have\n   no way to access other attributes of the instance.  Note that at\n   least for instance variables, you can fake total control by not\n   inserting any values in the instance attribute dictionary (but\n   instead inserting them in another object).  See the\n   "__getattribute__()" method below for a way to actually get total\n   control over attribute access.\n\nobject.__getattribute__(self, name)\n\n   Called unconditionally to implement attribute accesses for\n   instances of the class. If the class also defines "__getattr__()",\n   the latter will not be called unless "__getattribute__()" either\n   calls it explicitly or raises an "AttributeError". This method\n   should return the (computed) attribute value or raise an\n   "AttributeError" exception. In order to avoid infinite recursion in\n   this method, its implementation should always call the base class\n   method with the same name to access any attributes it needs, for\n   example, "object.__getattribute__(self, name)".\n\n   Note: This method may still be bypassed when looking up special\n     methods as the result of implicit invocation via language syntax\n     or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n   Called when an attribute assignment is attempted.  This is called\n   instead of the normal mechanism (i.e. store the value in the\n   instance dictionary). *name* is the attribute name, *value* is the\n   value to be assigned to it.\n\n   If "__setattr__()" wants to assign to an instance attribute, it\n   should call the base class method with the same name, for example,\n   "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n   Like "__setattr__()" but for attribute deletion instead of\n   assignment.  This should only be implemented if "del obj.name" is\n   meaningful for the object.\n\nobject.__dir__(self)\n\n   Called when "dir()" is called on the object. A sequence must be\n   returned. "dir()" converts the returned sequence to a list and\n   sorts it.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents).  In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n   Called to get the attribute of the owner class (class attribute\n   access) or of an instance of that class (instance attribute\n   access). *owner* is always the owner class, while *instance* is the\n   instance that the attribute was accessed through, or "None" when\n   the attribute is accessed through the *owner*.  This method should\n   return the (computed) attribute value or raise an "AttributeError"\n   exception.\n\nobject.__set__(self, instance, value)\n\n   Called to set the attribute on an instance *instance* of the owner\n   class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n   Called to delete the attribute on an instance *instance* of the\n   owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol:  "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead.  Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n   The simplest and least common call is when user code directly\n   invokes a descriptor method:    "x.__get__(a)".\n\nInstance Binding\n   If binding to an object instance, "a.x" is transformed into the\n   call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n   If binding to a class, "A.x" is transformed into the call:\n   "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n   If "a" is an instance of "super", then the binding "super(B,\n   obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n   immediately preceding "B" and then invokes the descriptor with the\n   call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined.  A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()".  If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary.  If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor.  Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method.  Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary.  In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors.  Accordingly, instances can\nredefine and override methods.  This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage.  This wastes space for objects having very few instance\nvariables.  The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable.  Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n   This class variable can be assigned a string, iterable, or sequence\n   of strings with variable names used by instances.  *__slots__*\n   reserves space for the declared variables and prevents the\n   automatic creation of *__dict__* and *__weakref__* for each\n   instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n  attribute of that class will always be accessible, so a *__slots__*\n  definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n  variables not listed in the *__slots__* definition.  Attempts to\n  assign to an unlisted variable name raises "AttributeError". If\n  dynamic assignment of new variables is desired, then add\n  "\'__dict__\'" to the sequence of strings in the *__slots__*\n  declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n  defining *__slots__* do not support weak references to its\n  instances. If weak reference support is needed, then add\n  "\'__weakref__\'" to the sequence of strings in the *__slots__*\n  declaration.\n\n* *__slots__* are implemented at the class level by creating\n  descriptors (*Implementing Descriptors*) for each variable name.  As\n  a result, class attributes cannot be used to set default values for\n  instance variables defined by *__slots__*; otherwise, the class\n  attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n  where it is defined.  As a result, subclasses will have a *__dict__*\n  unless they also define *__slots__* (which must only contain names\n  of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n  instance variable defined by the base class slot is inaccessible\n  (except by retrieving its descriptor directly from the base class).\n  This renders the meaning of the program undefined.  In the future, a\n  check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n  "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n  may also be used; however, in the future, special meaning may be\n  assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n  *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using "type()". The class body is\nexecuted in a new namespace and the class name is bound locally to the\nresult of "type(name, bases, namespace)".\n\nThe class creation process can be customised by passing the\n"metaclass" keyword argument in the class definition line, or by\ninheriting from an existing class that included such an argument. In\nthe following example, both "MyClass" and "MySubclass" are instances\nof "Meta":\n\n   class Meta(type):\n       pass\n\n   class MyClass(metaclass=Meta):\n       pass\n\n   class MySubclass(MyClass):\n       pass\n\nAny other keyword arguments that are specified in the class definition\nare passed through to all metaclass operations described below.\n\nWhen a class definition is executed, the following steps occur:\n\n* the appropriate metaclass is determined\n\n* the class namespace is prepared\n\n* the class body is executed\n\n* the class object is created\n\n\nDetermining the appropriate metaclass\n-------------------------------------\n\nThe appropriate metaclass for a class definition is determined as\nfollows:\n\n* if no bases and no explicit metaclass are given, then "type()" is\n  used\n\n* if an explicit metaclass is given and it is *not* an instance of\n  "type()", then it is used directly as the metaclass\n\n* if an instance of "type()" is given as the explicit metaclass, or\n  bases are defined, then the most derived metaclass is used\n\nThe most derived metaclass is selected from the explicitly specified\nmetaclass (if any) and the metaclasses (i.e. "type(cls)") of all\nspecified base classes. The most derived metaclass is one which is a\nsubtype of *all* of these candidate metaclasses. If none of the\ncandidate metaclasses meets that criterion, then the class definition\nwill fail with "TypeError".\n\n\nPreparing the class namespace\n-----------------------------\n\nOnce the appropriate metaclass has been identified, then the class\nnamespace is prepared. If the metaclass has a "__prepare__" attribute,\nit is called as "namespace = metaclass.__prepare__(name, bases,\n**kwds)" (where the additional keyword arguments, if any, come from\nthe class definition).\n\nIf the metaclass has no "__prepare__" attribute, then the class\nnamespace is initialised as an empty "dict()" instance.\n\nSee also: **PEP 3115** - Metaclasses in Python 3000\n\n     Introduced the "__prepare__" namespace hook\n\n\nExecuting the class body\n------------------------\n\nThe class body is executed (approximately) as "exec(body, globals(),\nnamespace)". The key difference from a normal call to "exec()" is that\nlexical scoping allows the class body (including any methods) to\nreference names from the current and outer scopes when the class\ndefinition occurs inside a function.\n\nHowever, even when the class definition occurs inside the function,\nmethods defined inside the class still cannot see names defined at the\nclass scope. Class variables must be accessed through the first\nparameter of instance or class methods, and cannot be accessed at all\nfrom static methods.\n\n\nCreating the class object\n-------------------------\n\nOnce the class namespace has been populated by executing the class\nbody, the class object is created by calling "metaclass(name, bases,\nnamespace, **kwds)" (the additional keywords passed here are the same\nas those passed to "__prepare__").\n\nThis class object is the one that will be referenced by the zero-\nargument form of "super()". "__class__" is an implicit closure\nreference created by the compiler if any methods in a class body refer\nto either "__class__" or "super". This allows the zero argument form\nof "super()" to correctly identify the class being defined based on\nlexical scoping, while the class or instance that was used to make the\ncurrent call is identified based on the first argument passed to the\nmethod.\n\nAfter the class object is created, it is passed to the class\ndecorators included in the class definition (if any) and the resulting\nobject is bound in the local namespace as the defined class.\n\nSee also: **PEP 3135** - New super\n\n     Describes the implicit "__class__" closure reference\n\n\nMetaclass example\n-----------------\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored include logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n"collections.OrderedDict" to remember the order that class variables\nare defined:\n\n   class OrderedClass(type):\n\n        @classmethod\n        def __prepare__(metacls, name, bases, **kwds):\n           return collections.OrderedDict()\n\n        def __new__(cls, name, bases, namespace, **kwds):\n           result = type.__new__(cls, name, bases, dict(namespace))\n           result.members = tuple(namespace)\n           return result\n\n   class A(metaclass=OrderedClass):\n       def one(self): pass\n       def two(self): pass\n       def three(self): pass\n       def four(self): pass\n\n   >>> A.members\n   (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s "__prepare__()" method which returns an\nempty "collections.OrderedDict".  That mapping records the methods and\nattributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s "__new__()" method gets\ninvoked.  That method builds the new type and it saves the ordered\ndictionary keys in an attribute called "members".\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n"isinstance()" and "issubclass()" built-in functions.\n\nIn particular, the metaclass "abc.ABCMeta" implements these methods in\norder to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n   Return true if *instance* should be considered a (direct or\n   indirect) instance of *class*. If defined, called to implement\n   "isinstance(instance, class)".\n\nclass.__subclasscheck__(self, subclass)\n\n   Return true if *subclass* should be considered a (direct or\n   indirect) subclass of *class*.  If defined, called to implement\n   "issubclass(subclass, class)".\n\nNote that these methods are looked up on the type (metaclass) of a\nclass.  They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also: **PEP 3119** - Introducing Abstract Base Classes\n\n     Includes the specification for customizing "isinstance()" and\n     "issubclass()" behavior through "__instancecheck__()" and\n     "__subclasscheck__()", with motivation for this functionality in\n     the context of adding Abstract Base Classes (see the "abc"\n     module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n   Called when the instance is "called" as a function; if this method\n   is defined, "x(arg1, arg2, ...)" is a shorthand for\n   "x.__call__(arg1, arg2, ...)".\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well.  The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items.  It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects.  Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators.  It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values.  It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n   Called to implement the built-in function "len()".  Should return\n   the length of the object, an integer ">=" 0.  Also, an object that\n   doesn\'t define a "__bool__()" method and whose "__len__()" method\n   returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n   Called to implement "operator.length_hint()". Should return an\n   estimated length for the object (which may be greater or less than\n   the actual length). The length must be an integer ">=" 0. This\n   method is purely an optimization and is never required for\n   correctness.\n\n   New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n  A call like\n\n     a[1:2] = b\n\n  is translated to\n\n     a[slice(1, 2, None)] = b\n\n  and so forth.  Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n   Called to implement evaluation of "self[key]". For sequence types,\n   the accepted keys should be integers and slice objects.  Note that\n   the special interpretation of negative indexes (if the class wishes\n   to emulate a sequence type) is up to the "__getitem__()" method. If\n   *key* is of an inappropriate type, "TypeError" may be raised; if of\n   a value outside the set of indexes for the sequence (after any\n   special interpretation of negative values), "IndexError" should be\n   raised. For mapping types, if *key* is missing (not in the\n   container), "KeyError" should be raised.\n\n   Note: "for" loops expect that an "IndexError" will be raised for\n     illegal indexes to allow proper detection of the end of the\n     sequence.\n\nobject.__missing__(self, key)\n\n   Called by "dict"."__getitem__()" to implement "self[key]" for dict\n   subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n   Called to implement assignment to "self[key]".  Same note as for\n   "__getitem__()".  This should only be implemented for mappings if\n   the objects support changes to the values for keys, or if new keys\n   can be added, or for sequences if elements can be replaced.  The\n   same exceptions should be raised for improper *key* values as for\n   the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n   Called to implement deletion of "self[key]".  Same note as for\n   "__getitem__()".  This should only be implemented for mappings if\n   the objects support removal of keys, or for sequences if elements\n   can be removed from the sequence.  The same exceptions should be\n   raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n   This method is called when an iterator is required for a container.\n   This method should return a new iterator object that can iterate\n   over all the objects in the container.  For mappings, it should\n   iterate over the keys of the container.\n\n   Iterator objects also need to implement this method; they are\n   required to return themselves.  For more information on iterator\n   objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n   Called (if present) by the "reversed()" built-in to implement\n   reverse iteration.  It should return a new iterator object that\n   iterates over all the objects in the container in reverse order.\n\n   If the "__reversed__()" method is not provided, the "reversed()"\n   built-in will fall back to using the sequence protocol ("__len__()"\n   and "__getitem__()").  Objects that support the sequence protocol\n   should only provide "__reversed__()" if they can provide an\n   implementation that is more efficient than the one provided by\n   "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence.  However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n   Called to implement membership test operators.  Should return true\n   if *item* is in *self*, false otherwise.  For mapping objects, this\n   should consider the keys of the mapping rather than the values or\n   the key-item pairs.\n\n   For objects that don\'t define "__contains__()", the membership test\n   first tries iteration via "__iter__()", then the old sequence\n   iteration protocol via "__getitem__()", see *this section in the\n   language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__matmul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n   "pow()", "**", "<<", ">>", "&", "^", "|").  For instance, to\n   evaluate the expression "x + y", where *x* is an instance of a\n   class that has an "__add__()" method, "x.__add__(y)" is called.\n   The "__divmod__()" method should be the equivalent to using\n   "__floordiv__()" and "__mod__()"; it should not be related to\n   "__truediv__()".  Note that "__pow__()" should be defined to accept\n   an optional third argument if the ternary version of the built-in\n   "pow()" function is to be supported.\n\n   If one of those methods does not support the operation with the\n   supplied arguments, it should return "NotImplemented".\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rmatmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n   "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)\n   operands.  These functions are only called if the left operand does\n   not support the corresponding operation and the operands are of\n   different types. [2] For instance, to evaluate the expression "x -\n   y", where *y* is an instance of a class that has an "__rsub__()"\n   method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n   *NotImplemented*.\n\n   Note that ternary "pow()" will not try calling "__rpow__()" (the\n   coercion rules would become too complicated).\n\n   Note: If the right operand\'s type is a subclass of the left\n     operand\'s type and that subclass provides the reflected method\n     for the operation, this method will be called before the left\n     operand\'s non-reflected method.  This behavior allows subclasses\n     to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__imatmul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n   These methods are called to implement the augmented arithmetic\n   assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", "**=",\n   "<<=", ">>=", "&=", "^=", "|=").  These methods should attempt to\n   do the operation in-place (modifying *self*) and return the result\n   (which could be, but does not have to be, *self*).  If a specific\n   method is not defined, the augmented assignment falls back to the\n   normal methods.  For instance, if *x* is an instance of a class\n   with an "__iadd__()" method, "x += y" is equivalent to "x =\n   x.__iadd__(y)" . Otherwise, "x.__add__(y)" and "y.__radd__(x)" are\n   considered, as with the evaluation of "x + y". In certain\n   situations, augmented assignment can result in unexpected errors\n   (see *Why does a_tuple[i] += [\'item\'] raise an exception when the\n   addition works?*), but this behavior is in fact part of the data\n   model.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n   Called to implement the unary arithmetic operations ("-", "+",\n   "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n   Called to implement the built-in functions "complex()", "int()",\n   "float()" and "round()".  Should return a value of the appropriate\n   type.\n\nobject.__index__(self)\n\n   Called to implement "operator.index()", and whenever Python needs\n   to losslessly convert the numeric object to an integer object (such\n   as in slicing, or in the built-in "bin()", "hex()" and "oct()"\n   functions). Presence of this method indicates that the numeric\n   object is an integer type.  Must return an integer.\n\n   Note: In order to have a coherent integer type class, when\n     "__index__()" is defined "__int__()" should also be defined, and\n     both should return the same value.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code.  Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n   Enter the runtime context related to this object. The "with"\n   statement will bind this method\'s return value to the target(s)\n   specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n   Exit the runtime context related to this object. The parameters\n   describe the exception that caused the context to be exited. If the\n   context was exited without an exception, all three arguments will\n   be "None".\n\n   If an exception is supplied, and the method wishes to suppress the\n   exception (i.e., prevent it from being propagated), it should\n   return a true value. Otherwise, the exception will be processed\n   normally upon exit from this method.\n\n   Note that "__exit__()" methods should not reraise the passed-in\n   exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n     The specification, background, and examples for the Python "with"\n     statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary.  That behaviour is the reason why\nthe following code raises an exception:\n\n   >>> class C:\n   ...     pass\n   ...\n   >>> c = C()\n   >>> c.__len__ = lambda: 5\n   >>> len(c)\n   Traceback (most recent call last):\n     File "<stdin>", line 1, in <module>\n   TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as "__hash__()" and "__repr__()" that are implemented by\nall objects, including type objects. If the implicit lookup of these\nmethods used the conventional lookup process, they would fail when\ninvoked on the type object itself:\n\n   >>> 1 .__hash__() == hash(1)\n   True\n   >>> int.__hash__() == hash(int)\n   Traceback (most recent call last):\n     File "<stdin>", line 1, in <module>\n   TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n   >>> type(1).__hash__(1) == hash(1)\n   True\n   >>> type(int).__hash__(int) == hash(int)\n   True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe "__getattribute__()" method even of the object\'s metaclass:\n\n   >>> class Meta(type):\n   ...     def __getattribute__(*args):\n   ...         print("Metaclass getattribute invoked")\n   ...         return type.__getattribute__(*args)\n   ...\n   >>> class C(object, metaclass=Meta):\n   ...     def __len__(self):\n   ...         return 10\n   ...     def __getattribute__(*args):\n   ...         print("Class getattribute invoked")\n   ...         return object.__getattribute__(*args)\n   ...\n   >>> c = C()\n   >>> c.__len__()                 # Explicit lookup via instance\n   Class getattribute invoked\n   10\n   >>> type(c).__len__(c)          # Explicit lookup via type\n   Metaclass getattribute invoked\n   10\n   >>> len(c)                      # Implicit lookup\n   10\n\nBypassing the "__getattribute__()" machinery in this fashion provides\nsignificant scope for speed optimisations within the interpreter, at\nthe cost of some flexibility in the handling of special methods (the\nspecial method *must* be set on the class object itself in order to be\nconsistently invoked by the interpreter).\n',
- 'string-methods': u'\nString Methods\n**************\n\nStrings implement all of the *common* sequence operations, along with\nthe additional methods described below.\n\nStrings also support two styles of string formatting, one providing a\nlarge degree of flexibility and customization (see "str.format()",\n*Format String Syntax* and *String Formatting*) and the other based on\nC "printf" style formatting that handles a narrower range of types and\nis slightly harder to use correctly, but is often faster for the cases\nit can handle (*printf-style String Formatting*).\n\nThe *Text Processing Services* section of the standard library covers\na number of other modules that provide various text related utilities\n(including regular expression support in the "re" module).\n\nstr.capitalize()\n\n   Return a copy of the string with its first character capitalized\n   and the rest lowercased.\n\nstr.casefold()\n\n   Return a casefolded copy of the string. Casefolded strings may be\n   used for caseless matching.\n\n   Casefolding is similar to lowercasing but more aggressive because\n   it is intended to remove all case distinctions in a string. For\n   example, the German lowercase letter "\'\xdf\'" is equivalent to ""ss"".\n   Since it is already lowercase, "lower()" would do nothing to "\'\xdf\'";\n   "casefold()" converts it to ""ss"".\n\n   The casefolding algorithm is described in section 3.13 of the\n   Unicode Standard.\n\n   New in version 3.3.\n\nstr.center(width[, fillchar])\n\n   Return centered in a string of length *width*. Padding is done\n   using the specified *fillchar* (default is an ASCII space). The\n   original string is returned if *width* is less than or equal to\n   "len(s)".\n\nstr.count(sub[, start[, end]])\n\n   Return the number of non-overlapping occurrences of substring *sub*\n   in the range [*start*, *end*].  Optional arguments *start* and\n   *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n   Return an encoded version of the string as a bytes object. Default\n   encoding is "\'utf-8\'". *errors* may be given to set a different\n   error handling scheme. The default for *errors* is "\'strict\'",\n   meaning that encoding errors raise a "UnicodeError". Other possible\n   values are "\'ignore\'", "\'replace\'", "\'xmlcharrefreplace\'",\n   "\'backslashreplace\'" and any other name registered via\n   "codecs.register_error()", see section *Error Handlers*. For a list\n   of possible encodings, see section *Standard Encodings*.\n\n   Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n   Return "True" if the string ends with the specified *suffix*,\n   otherwise return "False".  *suffix* can also be a tuple of suffixes\n   to look for.  With optional *start*, test beginning at that\n   position.  With optional *end*, stop comparing at that position.\n\nstr.expandtabs(tabsize=8)\n\n   Return a copy of the string where all tab characters are replaced\n   by one or more spaces, depending on the current column and the\n   given tab size.  Tab positions occur every *tabsize* characters\n   (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n   To expand the string, the current column is set to zero and the\n   string is examined character by character.  If the character is a\n   tab ("\\t"), one or more space characters are inserted in the result\n   until the current column is equal to the next tab position. (The\n   tab character itself is not copied.)  If the character is a newline\n   ("\\n") or return ("\\r"), it is copied and the current column is\n   reset to zero.  Any other character is copied unchanged and the\n   current column is incremented by one regardless of how the\n   character is represented when printed.\n\n   >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n   \'01      012     0123    01234\'\n   >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n   \'01  012 0123    01234\'\n\nstr.find(sub[, start[, end]])\n\n   Return the lowest index in the string where substring *sub* is\n   found, such that *sub* is contained in the slice "s[start:end]".\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return "-1" if *sub* is not found.\n\n   Note: The "find()" method should be used only if you need to know\n     the position of *sub*.  To check if *sub* is a substring or not,\n     use the "in" operator:\n\n        >>> \'Py\' in \'Python\'\n        True\n\nstr.format(*args, **kwargs)\n\n   Perform a string formatting operation.  The string on which this\n   method is called can contain literal text or replacement fields\n   delimited by braces "{}".  Each replacement field contains either\n   the numeric index of a positional argument, or the name of a\n   keyword argument.  Returns a copy of the string where each\n   replacement field is replaced with the string value of the\n   corresponding argument.\n\n   >>> "The sum of 1 + 2 is {0}".format(1+2)\n   \'The sum of 1 + 2 is 3\'\n\n   See *Format String Syntax* for a description of the various\n   formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n   Similar to "str.format(**mapping)", except that "mapping" is used\n   directly and not copied to a "dict".  This is useful if for example\n   "mapping" is a dict subclass:\n\n   >>> class Default(dict):\n   ...     def __missing__(self, key):\n   ...         return key\n   ...\n   >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n   \'Guido was born in country\'\n\n   New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n   Like "find()", but raise "ValueError" when the substring is not\n   found.\n\nstr.isalnum()\n\n   Return true if all characters in the string are alphanumeric and\n   there is at least one character, false otherwise.  A character "c"\n   is alphanumeric if one of the following returns "True":\n   "c.isalpha()", "c.isdecimal()", "c.isdigit()", or "c.isnumeric()".\n\nstr.isalpha()\n\n   Return true if all characters in the string are alphabetic and\n   there is at least one character, false otherwise.  Alphabetic\n   characters are those characters defined in the Unicode character\n   database as "Letter", i.e., those with general category property\n   being one of "Lm", "Lt", "Lu", "Ll", or "Lo".  Note that this is\n   different from the "Alphabetic" property defined in the Unicode\n   Standard.\n\nstr.isdecimal()\n\n   Return true if all characters in the string are decimal characters\n   and there is at least one character, false otherwise. Decimal\n   characters are those from general category "Nd". This category\n   includes digit characters, and all characters that can be used to\n   form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n   Return true if all characters in the string are digits and there is\n   at least one character, false otherwise.  Digits include decimal\n   characters and digits that need special handling, such as the\n   compatibility superscript digits.  Formally, a digit is a character\n   that has the property value Numeric_Type=Digit or\n   Numeric_Type=Decimal.\n\nstr.isidentifier()\n\n   Return true if the string is a valid identifier according to the\n   language definition, section *Identifiers and keywords*.\n\n   Use "keyword.iskeyword()" to test for reserved identifiers such as\n   "def" and "class".\n\nstr.islower()\n\n   Return true if all cased characters [4] in the string are lowercase\n   and there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n   Return true if all characters in the string are numeric characters,\n   and there is at least one character, false otherwise. Numeric\n   characters include digit characters, and all characters that have\n   the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n   ONE FIFTH.  Formally, numeric characters are those with the\n   property value Numeric_Type=Digit, Numeric_Type=Decimal or\n   Numeric_Type=Numeric.\n\nstr.isprintable()\n\n   Return true if all characters in the string are printable or the\n   string is empty, false otherwise.  Nonprintable characters are\n   those characters defined in the Unicode character database as\n   "Other" or "Separator", excepting the ASCII space (0x20) which is\n   considered printable.  (Note that printable characters in this\n   context are those which should not be escaped when "repr()" is\n   invoked on a string.  It has no bearing on the handling of strings\n   written to "sys.stdout" or "sys.stderr".)\n\nstr.isspace()\n\n   Return true if there are only whitespace characters in the string\n   and there is at least one character, false otherwise.  Whitespace\n   characters  are those characters defined in the Unicode character\n   database as "Other" or "Separator" and those with bidirectional\n   property being one of "WS", "B", or "S".\n\nstr.istitle()\n\n   Return true if the string is a titlecased string and there is at\n   least one character, for example uppercase characters may only\n   follow uncased characters and lowercase characters only cased ones.\n   Return false otherwise.\n\nstr.isupper()\n\n   Return true if all cased characters [4] in the string are uppercase\n   and there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n   Return a string which is the concatenation of the strings in the\n   *iterable* *iterable*.  A "TypeError" will be raised if there are\n   any non-string values in *iterable*, including "bytes" objects.\n   The separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n   Return the string left justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is an ASCII\n   space). The original string is returned if *width* is less than or\n   equal to "len(s)".\n\nstr.lower()\n\n   Return a copy of the string with all the cased characters [4]\n   converted to lowercase.\n\n   The lowercasing algorithm used is described in section 3.13 of the\n   Unicode Standard.\n\nstr.lstrip([chars])\n\n   Return a copy of the string with leading characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or "None", the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a prefix; rather,\n   all combinations of its values are stripped:\n\n      >>> \'   spacious   \'.lstrip()\n      \'spacious   \'\n      >>> \'www.example.com\'.lstrip(\'cmowz.\')\n      \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n   This static method returns a translation table usable for\n   "str.translate()".\n\n   If there is only one argument, it must be a dictionary mapping\n   Unicode ordinals (integers) or characters (strings of length 1) to\n   Unicode ordinals, strings (of arbitrary lengths) or None.\n   Character keys will then be converted to ordinals.\n\n   If there are two arguments, they must be strings of equal length,\n   and in the resulting dictionary, each character in x will be mapped\n   to the character at the same position in y.  If there is a third\n   argument, it must be a string, whose characters will be mapped to\n   None in the result.\n\nstr.partition(sep)\n\n   Split the string at the first occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing the string itself, followed by\n   two empty strings.\n\nstr.replace(old, new[, count])\n\n   Return a copy of the string with all occurrences of substring *old*\n   replaced by *new*.  If the optional argument *count* is given, only\n   the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n   Return the highest index in the string where substring *sub* is\n   found, such that *sub* is contained within "s[start:end]".\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return "-1" on failure.\n\nstr.rindex(sub[, start[, end]])\n\n   Like "rfind()" but raises "ValueError" when the substring *sub* is\n   not found.\n\nstr.rjust(width[, fillchar])\n\n   Return the string right justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is an ASCII\n   space). The original string is returned if *width* is less than or\n   equal to "len(s)".\n\nstr.rpartition(sep)\n\n   Split the string at the last occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing two empty strings, followed by\n   the string itself.\n\nstr.rsplit(sep=None, maxsplit=-1)\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n   are done, the *rightmost* ones.  If *sep* is not specified or\n   "None", any whitespace string is a separator.  Except for splitting\n   from the right, "rsplit()" behaves like "split()" which is\n   described in detail below.\n\nstr.rstrip([chars])\n\n   Return a copy of the string with trailing characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or "None", the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a suffix; rather,\n   all combinations of its values are stripped:\n\n      >>> \'   spacious   \'.rstrip()\n      \'   spacious\'\n      >>> \'mississippi\'.rstrip(\'ipz\')\n      \'mississ\'\n\nstr.split(sep=None, maxsplit=-1)\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string.  If *maxsplit* is given, at most *maxsplit*\n   splits are done (thus, the list will have at most "maxsplit+1"\n   elements).  If *maxsplit* is not specified or "-1", then there is\n   no limit on the number of splits (all possible splits are made).\n\n   If *sep* is given, consecutive delimiters are not grouped together\n   and are deemed to delimit empty strings (for example,\n   "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', \'2\']").  The *sep* argument\n   may consist of multiple characters (for example,\n   "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', \'3\']"). Splitting an\n   empty string with a specified separator returns "[\'\']".\n\n   For example:\n\n      >>> \'1,2,3\'.split(\',\')\n      [\'1\', \'2\', \'3\']\n      >>> \'1,2,3\'.split(\',\', maxsplit=1)\n      [\'1\', \'2,3\']\n      >>> \'1,2,,3,\'.split(\',\')\n      [\'1\', \'2\', \'\', \'3\', \'\']\n\n   If *sep* is not specified or is "None", a different splitting\n   algorithm is applied: runs of consecutive whitespace are regarded\n   as a single separator, and the result will contain no empty strings\n   at the start or end if the string has leading or trailing\n   whitespace.  Consequently, splitting an empty string or a string\n   consisting of just whitespace with a "None" separator returns "[]".\n\n   For example:\n\n      >>> \'1 2 3\'.split()\n      [\'1\', \'2\', \'3\']\n      >>> \'1 2 3\'.split(maxsplit=1)\n      [\'1\', \'2 3\']\n      >>> \'   1   2   3   \'.split()\n      [\'1\', \'2\', \'3\']\n\nstr.splitlines([keepends])\n\n   Return a list of the lines in the string, breaking at line\n   boundaries.  Line breaks are not included in the resulting list\n   unless *keepends* is given and true.\n\n   This method splits on the following line boundaries.  In\n   particular, the boundaries are a superset of *universal newlines*.\n\n   +-------------------------+-------------------------------+\n   | Representation          | Description                   |\n   +=========================+===============================+\n   | "\\n"                    | Line Feed                     |\n   +-------------------------+-------------------------------+\n   | "\\r"                    | Carriage Return               |\n   +-------------------------+-------------------------------+\n   | "\\r\\n"                  | Carriage Return + Line Feed   |\n   +-------------------------+-------------------------------+\n   | "\\v" or "\\x0b"          | Line Tabulation               |\n   +-------------------------+-------------------------------+\n   | "\\f" or "\\x0c"          | Form Feed                     |\n   +-------------------------+-------------------------------+\n   | "\\x1c"                  | File Separator                |\n   +-------------------------+-------------------------------+\n   | "\\x1d"                  | Group Separator               |\n   +-------------------------+-------------------------------+\n   | "\\x1e"                  | Record Separator              |\n   +-------------------------+-------------------------------+\n   | "\\x85"                  | Next Line (C1 Control Code)   |\n   +-------------------------+-------------------------------+\n   | "\\u2028"                | Line Separator                |\n   +-------------------------+-------------------------------+\n   | "\\u2029"                | Paragraph Separator           |\n   +-------------------------+-------------------------------+\n\n   Changed in version 3.2: "\\v" and "\\f" added to list of line\n   boundaries.\n\n   For example:\n\n      >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()\n      [\'ab c\', \'\', \'de fg\', \'kl\']\n      >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines(keepends=True)\n      [\'ab c\\n\', \'\\n\', \'de fg\\r\', \'kl\\r\\n\']\n\n   Unlike "split()" when a delimiter string *sep* is given, this\n   method returns an empty list for the empty string, and a terminal\n   line break does not result in an extra line:\n\n      >>> "".splitlines()\n      []\n      >>> "One line\\n".splitlines()\n      [\'One line\']\n\n   For comparison, "split(\'\\n\')" gives:\n\n      >>> \'\'.split(\'\\n\')\n      [\'\']\n      >>> \'Two lines\\n\'.split(\'\\n\')\n      [\'Two lines\', \'\']\n\nstr.startswith(prefix[, start[, end]])\n\n   Return "True" if string starts with the *prefix*, otherwise return\n   "False". *prefix* can also be a tuple of prefixes to look for.\n   With optional *start*, test string beginning at that position.\n   With optional *end*, stop comparing string at that position.\n\nstr.strip([chars])\n\n   Return a copy of the string with the leading and trailing\n   characters removed. The *chars* argument is a string specifying the\n   set of characters to be removed. If omitted or "None", the *chars*\n   argument defaults to removing whitespace. The *chars* argument is\n   not a prefix or suffix; rather, all combinations of its values are\n   stripped:\n\n      >>> \'   spacious   \'.strip()\n      \'spacious\'\n      >>> \'www.example.com\'.strip(\'cmowz.\')\n      \'example\'\n\n   The outermost leading and trailing *chars* argument values are\n   stripped from the string. Characters are removed from the leading\n   end until reaching a string character that is not contained in the\n   set of characters in *chars*. A similar action takes place on the\n   trailing end. For example:\n\n      >>> comment_string = \'#....... Section 3.2.1 Issue #32 .......\'\n      >>> comment_string.strip(\'.#! \')\n      \'Section 3.2.1 Issue #32\'\n\nstr.swapcase()\n\n   Return a copy of the string with uppercase characters converted to\n   lowercase and vice versa. Note that it is not necessarily true that\n   "s.swapcase().swapcase() == s".\n\nstr.title()\n\n   Return a titlecased version of the string where words start with an\n   uppercase character and the remaining characters are lowercase.\n\n   For example:\n\n      >>> \'Hello world\'.title()\n      \'Hello World\'\n\n   The algorithm uses a simple language-independent definition of a\n   word as groups of consecutive letters.  The definition works in\n   many contexts but it means that apostrophes in contractions and\n   possessives form word boundaries, which may not be the desired\n   result:\n\n      >>> "they\'re bill\'s friends from the UK".title()\n      "They\'Re Bill\'S Friends From The Uk"\n\n   A workaround for apostrophes can be constructed using regular\n   expressions:\n\n      >>> import re\n      >>> def titlecase(s):\n      ...     return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n      ...                   lambda mo: mo.group(0)[0].upper() +\n      ...                              mo.group(0)[1:].lower(),\n      ...                   s)\n      ...\n      >>> titlecase("they\'re bill\'s friends.")\n      "They\'re Bill\'s Friends."\n\nstr.translate(table)\n\n   Return a copy of the string in which each character has been mapped\n   through the given translation table.  The table must be an object\n   that implements indexing via "__getitem__()", typically a *mapping*\n   or *sequence*.  When indexed by a Unicode ordinal (an integer), the\n   table object can do any of the following: return a Unicode ordinal\n   or a string, to map the character to one or more other characters;\n   return "None", to delete the character from the return string; or\n   raise a "LookupError" exception, to map the character to itself.\n\n   You can use "str.maketrans()" to create a translation map from\n   character-to-character mappings in different formats.\n\n   See also the "codecs" module for a more flexible approach to custom\n   character mappings.\n\nstr.upper()\n\n   Return a copy of the string with all the cased characters [4]\n   converted to uppercase.  Note that "str.upper().isupper()" might be\n   "False" if "s" contains uncased characters or if the Unicode\n   category of the resulting character(s) is not "Lu" (Letter,\n   uppercase), but e.g. "Lt" (Letter, titlecase).\n\n   The uppercasing algorithm used is described in section 3.13 of the\n   Unicode Standard.\n\nstr.zfill(width)\n\n   Return a copy of the string left filled with ASCII "\'0\'" digits to\n   make a string of length *width*. A leading sign prefix\n   ("\'+\'"/"\'-\'") is handled by inserting the padding *after* the sign\n   character rather than before. The original string is returned if\n   *width* is less than or equal to "len(s)".\n\n   For example:\n\n      >>> "42".zfill(5)\n      \'00042\'\n      >>> "-42".zfill(5)\n      \'-0042\'\n',
- 'strings': u'\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n   stringliteral   ::= [stringprefix](shortstring | longstring)\n   stringprefix    ::= "r" | "u" | "R" | "U"\n   shortstring     ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n   longstring      ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n   shortstringitem ::= shortstringchar | stringescapeseq\n   longstringitem  ::= longstringchar | stringescapeseq\n   shortstringchar ::= <any source character except "\\" or newline or the quote>\n   longstringchar  ::= <any source character except "\\">\n   stringescapeseq ::= "\\" <any source character>\n\n   bytesliteral   ::= bytesprefix(shortbytes | longbytes)\n   bytesprefix    ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"\n   shortbytes     ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n   longbytes      ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n   shortbytesitem ::= shortbyteschar | bytesescapeseq\n   longbytesitem  ::= longbyteschar | bytesescapeseq\n   shortbyteschar ::= <any ASCII character except "\\" or newline or the quote>\n   longbyteschar  ::= <any ASCII character except "\\">\n   bytesescapeseq ::= "\\" <any ASCII character>\n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the "stringprefix" or "bytesprefix"\nand the rest of the literal. The source character set is defined by\nthe encoding declaration; it is UTF-8 if no encoding declaration is\ngiven in the source file; see section *Encoding declarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes ("\'") or double quotes (""").  They can also be enclosed\nin matching groups of three single or double quotes (these are\ngenerally referred to as *triple-quoted strings*).  The backslash\n("\\") character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with "\'b\'" or "\'B\'"; they produce\nan instance of the "bytes" type instead of the "str" type.  They may\nonly contain ASCII characters; bytes with a numeric value of 128 or\ngreater must be expressed with escapes.\n\nAs of Python 3.3 it is possible again to prefix string literals with a\n"u" prefix to simplify maintenance of dual 2.x and 3.x codebases.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter "\'r\'" or "\'R\'"; such strings are called *raw strings* and treat\nbackslashes as literal characters.  As a result, in string literals,\n"\'\\U\'" and "\'\\u\'" escapes in raw strings are not treated specially.\nGiven that Python 2.x\'s raw unicode literals behave differently than\nPython 3.x\'s the "\'ur\'" syntax is not supported.\n\nNew in version 3.3: The "\'rb\'" prefix of raw bytes literals has been\nadded as a synonym of "\'br\'".\n\nNew in version 3.3: Support for the unicode legacy literal\n("u\'value\'") was reintroduced to simplify the maintenance of dual\nPython 2.x and 3.x codebases. See **PEP 414** for more information.\n\nIn triple-quoted literals, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the literal.  (A "quote" is the character used to open the\nliteral, i.e. either "\'" or """.)\n\nUnless an "\'r\'" or "\'R\'" prefix is present, escape sequences in string\nand bytes literals are interpreted according to rules similar to those\nused by Standard C.  The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence   | Meaning                           | Notes   |\n+===================+===================================+=========+\n| "\\newline"        | Backslash and newline ignored     |         |\n+-------------------+-----------------------------------+---------+\n| "\\\\"              | Backslash ("\\")                   |         |\n+-------------------+-----------------------------------+---------+\n| "\\\'"              | Single quote ("\'")                |         |\n+-------------------+-----------------------------------+---------+\n| "\\""              | Double quote (""")                |         |\n+-------------------+-----------------------------------+---------+\n| "\\a"              | ASCII Bell (BEL)                  |         |\n+-------------------+-----------------------------------+---------+\n| "\\b"              | ASCII Backspace (BS)              |         |\n+-------------------+-----------------------------------+---------+\n| "\\f"              | ASCII Formfeed (FF)               |         |\n+-------------------+-----------------------------------+---------+\n| "\\n"              | ASCII Linefeed (LF)               |         |\n+-------------------+-----------------------------------+---------+\n| "\\r"              | ASCII Carriage Return (CR)        |         |\n+-------------------+-----------------------------------+---------+\n| "\\t"              | ASCII Horizontal Tab (TAB)        |         |\n+-------------------+-----------------------------------+---------+\n| "\\v"              | ASCII Vertical Tab (VT)           |         |\n+-------------------+-----------------------------------+---------+\n| "\\ooo"            | Character with octal value *ooo*  | (1,3)   |\n+-------------------+-----------------------------------+---------+\n| "\\xhh"            | Character with hex value *hh*     | (2,3)   |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence   | Meaning                           | Notes   |\n+===================+===================================+=========+\n| "\\N{name}"        | Character named *name* in the     | (4)     |\n|                   | Unicode database                  |         |\n+-------------------+-----------------------------------+---------+\n| "\\uxxxx"          | Character with 16-bit hex value   | (5)     |\n|                   | *xxxx*                            |         |\n+-------------------+-----------------------------------+---------+\n| "\\Uxxxxxxxx"      | Character with 32-bit hex value   | (6)     |\n|                   | *xxxxxxxx*                        |         |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the\n   byte with the given value. In a string literal, these escapes\n   denote a Unicode character with the given value.\n\n4. Changed in version 3.3: Support for name aliases [1] has been\n   added.\n\n5. Individual code units which form parts of a surrogate pair can\n   be encoded using this escape sequence.  Exactly four hex digits are\n   required.\n\n6. Any Unicode character can be encoded this way.  Exactly eight\n   hex digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the result*.  (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.)  It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw literal, quotes can be escaped with a backslash, but the\nbackslash remains in the result; for example, "r"\\""" is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; "r"\\"" is not a valid string literal (even a raw string cannot\nend in an odd number of backslashes).  Specifically, *a raw literal\ncannot end in a single backslash* (since the backslash would escape\nthe following quote character).  Note also that a single backslash\nfollowed by a newline is interpreted as those two characters as part\nof the literal, *not* as a line continuation.\n',
+ 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators.  For instance, if a class defines\na method named "__getitem__()", and "x" is an instance of this class,\nthen "x[i]" is roughly equivalent to "type(x).__getitem__(x, i)".\nExcept where mentioned, attempts to execute an operation raise an\nexception when no appropriate method is defined (typically\n"AttributeError" or "TypeError").\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled.  For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense.  (One example of this is the\n"NodeList" interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n   Called to create a new instance of class *cls*.  "__new__()" is a\n   static method (special-cased so you need not declare it as such)\n   that takes the class of which an instance was requested as its\n   first argument.  The remaining arguments are those passed to the\n   object constructor expression (the call to the class).  The return\n   value of "__new__()" should be the new object instance (usually an\n   instance of *cls*).\n\n   Typical implementations create a new instance of the class by\n   invoking the superclass\'s "__new__()" method using\n   "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n   arguments and then modifying the newly-created instance as\n   necessary before returning it.\n\n   If "__new__()" returns an instance of *cls*, then the new\n   instance\'s "__init__()" method will be invoked like\n   "__init__(self[, ...])", where *self* is the new instance and the\n   remaining arguments are the same as were passed to "__new__()".\n\n   If "__new__()" does not return an instance of *cls*, then the new\n   instance\'s "__init__()" method will not be invoked.\n\n   "__new__()" is intended mainly to allow subclasses of immutable\n   types (like int, str, or tuple) to customize instance creation.  It\n   is also commonly overridden in custom metaclasses in order to\n   customize class creation.\n\nobject.__init__(self[, ...])\n\n   Called after the instance has been created (by "__new__()"), but\n   before it is returned to the caller.  The arguments are those\n   passed to the class constructor expression.  If a base class has an\n   "__init__()" method, the derived class\'s "__init__()" method, if\n   any, must explicitly call it to ensure proper initialization of the\n   base class part of the instance; for example:\n   "BaseClass.__init__(self, [args...])".\n\n   Because "__new__()" and "__init__()" work together in constructing\n   objects ("__new__()" to create it, and "__init__()" to customise\n   it), no non-"None" value may be returned by "__init__()"; doing so\n   will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n   Called when the instance is about to be destroyed.  This is also\n   called a destructor.  If a base class has a "__del__()" method, the\n   derived class\'s "__del__()" method, if any, must explicitly call it\n   to ensure proper deletion of the base class part of the instance.\n   Note that it is possible (though not recommended!) for the\n   "__del__()" method to postpone destruction of the instance by\n   creating a new reference to it.  It may then be called at a later\n   time when this new reference is deleted.  It is not guaranteed that\n   "__del__()" methods are called for objects that still exist when\n   the interpreter exits.\n\n   Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n     decrements the reference count for "x" by one, and the latter is\n     only called when "x"\'s reference count reaches zero.  Some common\n     situations that may prevent the reference count of an object from\n     going to zero include: circular references between objects (e.g.,\n     a doubly-linked list or a tree data structure with parent and\n     child pointers); a reference to the object on the stack frame of\n     a function that caught an exception (the traceback stored in\n     "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n     to the object on the stack frame that raised an unhandled\n     exception in interactive mode (the traceback stored in\n     "sys.last_traceback" keeps the stack frame alive).  The first\n     situation can only be remedied by explicitly breaking the cycles;\n     the second can be resolved by freeing the reference to the\n     traceback object when it is no longer useful, and the third can\n     be resolved by storing "None" in "sys.last_traceback". Circular\n     references which are garbage are detected and cleaned up when the\n     cyclic garbage collector is enabled (it\'s on by default). Refer\n     to the documentation for the "gc" module for more information\n     about this topic.\n\n   Warning: Due to the precarious circumstances under which\n     "__del__()" methods are invoked, exceptions that occur during\n     their execution are ignored, and a warning is printed to\n     "sys.stderr" instead. Also, when "__del__()" is invoked in\n     response to a module being deleted (e.g., when execution of the\n     program is done), other globals referenced by the "__del__()"\n     method may already have been deleted or in the process of being\n     torn down (e.g. the import machinery shutting down).  For this\n     reason, "__del__()" methods should do the absolute minimum needed\n     to maintain external invariants.  Starting with version 1.5,\n     Python guarantees that globals whose name begins with a single\n     underscore are deleted from their module before other globals are\n     deleted; if no other references to such globals exist, this may\n     help in assuring that imported modules are still available at the\n     time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n   Called by the "repr()" built-in function to compute the "official"\n   string representation of an object.  If at all possible, this\n   should look like a valid Python expression that could be used to\n   recreate an object with the same value (given an appropriate\n   environment).  If this is not possible, a string of the form\n   "<...some useful description...>" should be returned. The return\n   value must be a string object. If a class defines "__repr__()" but\n   not "__str__()", then "__repr__()" is also used when an "informal"\n   string representation of instances of that class is required.\n\n   This is typically used for debugging, so it is important that the\n   representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n   Called by "str(object)" and the built-in functions "format()" and\n   "print()" to compute the "informal" or nicely printable string\n   representation of an object.  The return value must be a *string*\n   object.\n\n   This method differs from "object.__repr__()" in that there is no\n   expectation that "__str__()" return a valid Python expression: a\n   more convenient or concise representation can be used.\n\n   The default implementation defined by the built-in type "object"\n   calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n   Called by "bytes()" to compute a byte-string representation of an\n   object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n   Called by the "format()" built-in function (and by extension, the\n   "str.format()" method of class "str") to produce a "formatted"\n   string representation of an object. The "format_spec" argument is a\n   string that contains a description of the formatting options\n   desired. The interpretation of the "format_spec" argument is up to\n   the type implementing "__format__()", however most classes will\n   either delegate formatting to one of the built-in types, or use a\n   similar formatting option syntax.\n\n   See *Format Specification Mini-Language* for a description of the\n   standard formatting syntax.\n\n   The return value must be a string object.\n\n   Changed in version 3.4: The __format__ method of "object" itself\n   raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n   These are the so-called "rich comparison" methods. The\n   correspondence between operator symbols and method names is as\n   follows: "x<y" calls "x.__lt__(y)", "x<=y" calls "x.__le__(y)",\n   "x==y" calls "x.__eq__(y)", "x!=y" calls "x.__ne__(y)", "x>y" calls\n   "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n   A rich comparison method may return the singleton "NotImplemented"\n   if it does not implement the operation for a given pair of\n   arguments. By convention, "False" and "True" are returned for a\n   successful comparison. However, these methods can return any value,\n   so if the comparison operator is used in a Boolean context (e.g.,\n   in the condition of an "if" statement), Python will call "bool()"\n   on the value to determine if the result is true or false.\n\n   By default, "__ne__()" delegates to "__eq__()" and inverts the\n   result unless it is "NotImplemented".  There are no other implied\n   relationships among the comparison operators, for example, the\n   truth of "(x<y or x==y)" does not imply "x<=y". To automatically\n   generate ordering operations from a single root operation, see\n   "functools.total_ordering()".\n\n   See the paragraph on "__hash__()" for some important notes on\n   creating *hashable* objects which support custom comparison\n   operations and are usable as dictionary keys.\n\n   There are no swapped-argument versions of these methods (to be used\n   when the left argument does not support the operation but the right\n   argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n   reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n   and "__eq__()" and "__ne__()" are their own reflection. If the\n   operands are of different types, and right operand\'s type is a\n   direct or indirect subclass of the left operand\'s type, the\n   reflected method of the right operand has priority, otherwise the\n   left operand\'s method has priority.  Virtual subclassing is not\n   considered.\n\nobject.__hash__(self)\n\n   Called by built-in function "hash()" and for operations on members\n   of hashed collections including "set", "frozenset", and "dict".\n   "__hash__()" should return an integer.  The only required property\n   is that objects which compare equal have the same hash value; it is\n   advised to somehow mix together (e.g. using exclusive or) the hash\n   values for the components of the object that also play a part in\n   comparison of objects.\n\n   Note: "hash()" truncates the value returned from an object\'s\n     custom "__hash__()" method to the size of a "Py_ssize_t".  This\n     is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit\n     builds. If an object\'s   "__hash__()" must interoperate on builds\n     of different bit sizes, be sure to check the width on all\n     supported builds.  An easy way to do this is with "python -c\n     "import sys; print(sys.hash_info.width)"".\n\n   If a class does not define an "__eq__()" method it should not\n   define a "__hash__()" operation either; if it defines "__eq__()"\n   but not "__hash__()", its instances will not be usable as items in\n   hashable collections.  If a class defines mutable objects and\n   implements an "__eq__()" method, it should not implement\n   "__hash__()", since the implementation of hashable collections\n   requires that a key\'s hash value is immutable (if the object\'s hash\n   value changes, it will be in the wrong hash bucket).\n\n   User-defined classes have "__eq__()" and "__hash__()" methods by\n   default; with them, all objects compare unequal (except with\n   themselves) and "x.__hash__()" returns an appropriate value such\n   that "x == y" implies both that "x is y" and "hash(x) == hash(y)".\n\n   A class that overrides "__eq__()" and does not define "__hash__()"\n   will have its "__hash__()" implicitly set to "None".  When the\n   "__hash__()" method of a class is "None", instances of the class\n   will raise an appropriate "TypeError" when a program attempts to\n   retrieve their hash value, and will also be correctly identified as\n   unhashable when checking "isinstance(obj, collections.Hashable)".\n\n   If a class that overrides "__eq__()" needs to retain the\n   implementation of "__hash__()" from a parent class, the interpreter\n   must be told this explicitly by setting "__hash__ =\n   <ParentClass>.__hash__".\n\n   If a class that does not override "__eq__()" wishes to suppress\n   hash support, it should include "__hash__ = None" in the class\n   definition. A class which defines its own "__hash__()" that\n   explicitly raises a "TypeError" would be incorrectly identified as\n   hashable by an "isinstance(obj, collections.Hashable)" call.\n\n   Note: By default, the "__hash__()" values of str, bytes and\n     datetime objects are "salted" with an unpredictable random value.\n     Although they remain constant within an individual Python\n     process, they are not predictable between repeated invocations of\n     Python.This is intended to provide protection against a denial-\n     of-service caused by carefully-chosen inputs that exploit the\n     worst case performance of a dict insertion, O(n^2) complexity.\n     See http://www.ocert.org/advisories/ocert-2011-003.html for\n     details.Changing hash values affects the iteration order of\n     dicts, sets and other mappings.  Python has never made guarantees\n     about this ordering (and it typically varies between 32-bit and\n     64-bit builds).See also "PYTHONHASHSEED".\n\n   Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n   Called to implement truth value testing and the built-in operation\n   "bool()"; should return "False" or "True".  When this method is not\n   defined, "__len__()" is called, if it is defined, and the object is\n   considered true if its result is nonzero.  If a class defines\n   neither "__len__()" nor "__bool__()", all its instances are\n   considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n   Called when an attribute lookup has not found the attribute in the\n   usual places (i.e. it is not an instance attribute nor is it found\n   in the class tree for "self").  "name" is the attribute name. This\n   method should return the (computed) attribute value or raise an\n   "AttributeError" exception.\n\n   Note that if the attribute is found through the normal mechanism,\n   "__getattr__()" is not called.  (This is an intentional asymmetry\n   between "__getattr__()" and "__setattr__()".) This is done both for\n   efficiency reasons and because otherwise "__getattr__()" would have\n   no way to access other attributes of the instance.  Note that at\n   least for instance variables, you can fake total control by not\n   inserting any values in the instance attribute dictionary (but\n   instead inserting them in another object).  See the\n   "__getattribute__()" method below for a way to actually get total\n   control over attribute access.\n\nobject.__getattribute__(self, name)\n\n   Called unconditionally to implement attribute accesses for\n   instances of the class. If the class also defines "__getattr__()",\n   the latter will not be called unless "__getattribute__()" either\n   calls it explicitly or raises an "AttributeError". This method\n   should return the (computed) attribute value or raise an\n   "AttributeError" exception. In order to avoid infinite recursion in\n   this method, its implementation should always call the base class\n   method with the same name to access any attributes it needs, for\n   example, "object.__getattribute__(self, name)".\n\n   Note: This method may still be bypassed when looking up special\n     methods as the result of implicit invocation via language syntax\n     or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n   Called when an attribute assignment is attempted.  This is called\n   instead of the normal mechanism (i.e. store the value in the\n   instance dictionary). *name* is the attribute name, *value* is the\n   value to be assigned to it.\n\n   If "__setattr__()" wants to assign to an instance attribute, it\n   should call the base class method with the same name, for example,\n   "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n   Like "__setattr__()" but for attribute deletion instead of\n   assignment.  This should only be implemented if "del obj.name" is\n   meaningful for the object.\n\nobject.__dir__(self)\n\n   Called when "dir()" is called on the object. A sequence must be\n   returned. "dir()" converts the returned sequence to a list and\n   sorts it.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents).  In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n   Called to get the attribute of the owner class (class attribute\n   access) or of an instance of that class (instance attribute\n   access). *owner* is always the owner class, while *instance* is the\n   instance that the attribute was accessed through, or "None" when\n   the attribute is accessed through the *owner*.  This method should\n   return the (computed) attribute value or raise an "AttributeError"\n   exception.\n\nobject.__set__(self, instance, value)\n\n   Called to set the attribute on an instance *instance* of the owner\n   class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n   Called to delete the attribute on an instance *instance* of the\n   owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol:  "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead.  Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n   The simplest and least common call is when user code directly\n   invokes a descriptor method:    "x.__get__(a)".\n\nInstance Binding\n   If binding to an object instance, "a.x" is transformed into the\n   call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n   If binding to a class, "A.x" is transformed into the call:\n   "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n   If "a" is an instance of "super", then the binding "super(B,\n   obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n   immediately preceding "B" and then invokes the descriptor with the\n   call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined.  A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()".  If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary.  If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor.  Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method.  Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary.  In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors.  Accordingly, instances can\nredefine and override methods.  This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage.  This wastes space for objects having very few instance\nvariables.  The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable.  Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n   This class variable can be assigned a string, iterable, or sequence\n   of strings with variable names used by instances.  *__slots__*\n   reserves space for the declared variables and prevents the\n   automatic creation of *__dict__* and *__weakref__* for each\n   instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n  attribute of that class will always be accessible, so a *__slots__*\n  definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n  variables not listed in the *__slots__* definition.  Attempts to\n  assign to an unlisted variable name raises "AttributeError". If\n  dynamic assignment of new variables is desired, then add\n  "\'__dict__\'" to the sequence of strings in the *__slots__*\n  declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n  defining *__slots__* do not support weak references to its\n  instances. If weak reference support is needed, then add\n  "\'__weakref__\'" to the sequence of strings in the *__slots__*\n  declaration.\n\n* *__slots__* are implemented at the class level by creating\n  descriptors (*Implementing Descriptors*) for each variable name.  As\n  a result, class attributes cannot be used to set default values for\n  instance variables defined by *__slots__*; otherwise, the class\n  attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n  where it is defined.  As a result, subclasses will have a *__dict__*\n  unless they also define *__slots__* (which must only contain names\n  of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n  instance variable defined by the base class slot is inaccessible\n  (except by retrieving its descriptor directly from the base class).\n  This renders the meaning of the program undefined.  In the future, a\n  check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n  "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n  may also be used; however, in the future, special meaning may be\n  assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n  *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using "type()". The class body is\nexecuted in a new namespace and the class name is bound locally to the\nresult of "type(name, bases, namespace)".\n\nThe class creation process can be customised by passing the\n"metaclass" keyword argument in the class definition line, or by\ninheriting from an existing class that included such an argument. In\nthe following example, both "MyClass" and "MySubclass" are instances\nof "Meta":\n\n   class Meta(type):\n       pass\n\n   class MyClass(metaclass=Meta):\n       pass\n\n   class MySubclass(MyClass):\n       pass\n\nAny other keyword arguments that are specified in the class definition\nare passed through to all metaclass operations described below.\n\nWhen a class definition is executed, the following steps occur:\n\n* the appropriate metaclass is determined\n\n* the class namespace is prepared\n\n* the class body is executed\n\n* the class object is created\n\n\nDetermining the appropriate metaclass\n-------------------------------------\n\nThe appropriate metaclass for a class definition is determined as\nfollows:\n\n* if no bases and no explicit metaclass are given, then "type()" is\n  used\n\n* if an explicit metaclass is given and it is *not* an instance of\n  "type()", then it is used directly as the metaclass\n\n* if an instance of "type()" is given as the explicit metaclass, or\n  bases are defined, then the most derived metaclass is used\n\nThe most derived metaclass is selected from the explicitly specified\nmetaclass (if any) and the metaclasses (i.e. "type(cls)") of all\nspecified base classes. The most derived metaclass is one which is a\nsubtype of *all* of these candidate metaclasses. If none of the\ncandidate metaclasses meets that criterion, then the class definition\nwill fail with "TypeError".\n\n\nPreparing the class namespace\n-----------------------------\n\nOnce the appropriate metaclass has been identified, then the class\nnamespace is prepared. If the metaclass has a "__prepare__" attribute,\nit is called as "namespace = metaclass.__prepare__(name, bases,\n**kwds)" (where the additional keyword arguments, if any, come from\nthe class definition).\n\nIf the metaclass has no "__prepare__" attribute, then the class\nnamespace is initialised as an empty "dict()" instance.\n\nSee also: **PEP 3115** - Metaclasses in Python 3000\n\n     Introduced the "__prepare__" namespace hook\n\n\nExecuting the class body\n------------------------\n\nThe class body is executed (approximately) as "exec(body, globals(),\nnamespace)". The key difference from a normal call to "exec()" is that\nlexical scoping allows the class body (including any methods) to\nreference names from the current and outer scopes when the class\ndefinition occurs inside a function.\n\nHowever, even when the class definition occurs inside the function,\nmethods defined inside the class still cannot see names defined at the\nclass scope. Class variables must be accessed through the first\nparameter of instance or class methods, and cannot be accessed at all\nfrom static methods.\n\n\nCreating the class object\n-------------------------\n\nOnce the class namespace has been populated by executing the class\nbody, the class object is created by calling "metaclass(name, bases,\nnamespace, **kwds)" (the additional keywords passed here are the same\nas those passed to "__prepare__").\n\nThis class object is the one that will be referenced by the zero-\nargument form of "super()". "__class__" is an implicit closure\nreference created by the compiler if any methods in a class body refer\nto either "__class__" or "super". This allows the zero argument form\nof "super()" to correctly identify the class being defined based on\nlexical scoping, while the class or instance that was used to make the\ncurrent call is identified based on the first argument passed to the\nmethod.\n\nAfter the class object is created, it is passed to the class\ndecorators included in the class definition (if any) and the resulting\nobject is bound in the local namespace as the defined class.\n\nWhen a new class is created by "type.__new__", the object provided as\nthe namespace parameter is copied to a standard Python dictionary and\nthe original object is discarded. The new copy becomes the "__dict__"\nattribute of the class object.\n\nSee also: **PEP 3135** - New super\n\n     Describes the implicit "__class__" closure reference\n\n\nMetaclass example\n-----------------\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored include logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n"collections.OrderedDict" to remember the order that class variables\nare defined:\n\n   class OrderedClass(type):\n\n       @classmethod\n       def __prepare__(metacls, name, bases, **kwds):\n           return collections.OrderedDict()\n\n       def __new__(cls, name, bases, namespace, **kwds):\n           result = type.__new__(cls, name, bases, dict(namespace))\n           result.members = tuple(namespace)\n           return result\n\n   class A(metaclass=OrderedClass):\n       def one(self): pass\n       def two(self): pass\n       def three(self): pass\n       def four(self): pass\n\n   >>> A.members\n   (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s "__prepare__()" method which returns an\nempty "collections.OrderedDict".  That mapping records the methods and\nattributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s "__new__()" method gets\ninvoked.  That method builds the new type and it saves the ordered\ndictionary keys in an attribute called "members".\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n"isinstance()" and "issubclass()" built-in functions.\n\nIn particular, the metaclass "abc.ABCMeta" implements these methods in\norder to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n   Return true if *instance* should be considered a (direct or\n   indirect) instance of *class*. If defined, called to implement\n   "isinstance(instance, class)".\n\nclass.__subclasscheck__(self, subclass)\n\n   Return true if *subclass* should be considered a (direct or\n   indirect) subclass of *class*.  If defined, called to implement\n   "issubclass(subclass, class)".\n\nNote that these methods are looked up on the type (metaclass) of a\nclass.  They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also: **PEP 3119** - Introducing Abstract Base Classes\n\n     Includes the specification for customizing "isinstance()" and\n     "issubclass()" behavior through "__instancecheck__()" and\n     "__subclasscheck__()", with motivation for this functionality in\n     the context of adding Abstract Base Classes (see the "abc"\n     module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n   Called when the instance is "called" as a function; if this method\n   is defined, "x(arg1, arg2, ...)" is a shorthand for\n   "x.__call__(arg1, arg2, ...)".\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well.  The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items.  It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects.  Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators.  It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values.  It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n   Called to implement the built-in function "len()".  Should return\n   the length of the object, an integer ">=" 0.  Also, an object that\n   doesn\'t define a "__bool__()" method and whose "__len__()" method\n   returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n   Called to implement "operator.length_hint()". Should return an\n   estimated length for the object (which may be greater or less than\n   the actual length). The length must be an integer ">=" 0. This\n   method is purely an optimization and is never required for\n   correctness.\n\n   New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n  A call like\n\n     a[1:2] = b\n\n  is translated to\n\n     a[slice(1, 2, None)] = b\n\n  and so forth.  Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n   Called to implement evaluation of "self[key]". For sequence types,\n   the accepted keys should be integers and slice objects.  Note that\n   the special interpretation of negative indexes (if the class wishes\n   to emulate a sequence type) is up to the "__getitem__()" method. If\n   *key* is of an inappropriate type, "TypeError" may be raised; if of\n   a value outside the set of indexes for the sequence (after any\n   special interpretation of negative values), "IndexError" should be\n   raised. For mapping types, if *key* is missing (not in the\n   container), "KeyError" should be raised.\n\n   Note: "for" loops expect that an "IndexError" will be raised for\n     illegal indexes to allow proper detection of the end of the\n     sequence.\n\nobject.__missing__(self, key)\n\n   Called by "dict"."__getitem__()" to implement "self[key]" for dict\n   subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n   Called to implement assignment to "self[key]".  Same note as for\n   "__getitem__()".  This should only be implemented for mappings if\n   the objects support changes to the values for keys, or if new keys\n   can be added, or for sequences if elements can be replaced.  The\n   same exceptions should be raised for improper *key* values as for\n   the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n   Called to implement deletion of "self[key]".  Same note as for\n   "__getitem__()".  This should only be implemented for mappings if\n   the objects support removal of keys, or for sequences if elements\n   can be removed from the sequence.  The same exceptions should be\n   raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n   This method is called when an iterator is required for a container.\n   This method should return a new iterator object that can iterate\n   over all the objects in the container.  For mappings, it should\n   iterate over the keys of the container.\n\n   Iterator objects also need to implement this method; they are\n   required to return themselves.  For more information on iterator\n   objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n   Called (if present) by the "reversed()" built-in to implement\n   reverse iteration.  It should return a new iterator object that\n   iterates over all the objects in the container in reverse order.\n\n   If the "__reversed__()" method is not provided, the "reversed()"\n   built-in will fall back to using the sequence protocol ("__len__()"\n   and "__getitem__()").  Objects that support the sequence protocol\n   should only provide "__reversed__()" if they can provide an\n   implementation that is more efficient than the one provided by\n   "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence.  However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n   Called to implement membership test operators.  Should return true\n   if *item* is in *self*, false otherwise.  For mapping objects, this\n   should consider the keys of the mapping rather than the values or\n   the key-item pairs.\n\n   For objects that don\'t define "__contains__()", the membership test\n   first tries iteration via "__iter__()", then the old sequence\n   iteration protocol via "__getitem__()", see *this section in the\n   language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__matmul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n   "pow()", "**", "<<", ">>", "&", "^", "|").  For instance, to\n   evaluate the expression "x + y", where *x* is an instance of a\n   class that has an "__add__()" method, "x.__add__(y)" is called.\n   The "__divmod__()" method should be the equivalent to using\n   "__floordiv__()" and "__mod__()"; it should not be related to\n   "__truediv__()".  Note that "__pow__()" should be defined to accept\n   an optional third argument if the ternary version of the built-in\n   "pow()" function is to be supported.\n\n   If one of those methods does not support the operation with the\n   supplied arguments, it should return "NotImplemented".\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rmatmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n   "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)\n   operands.  These functions are only called if the left operand does\n   not support the corresponding operation and the operands are of\n   different types. [2] For instance, to evaluate the expression "x -\n   y", where *y* is an instance of a class that has an "__rsub__()"\n   method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n   *NotImplemented*.\n\n   Note that ternary "pow()" will not try calling "__rpow__()" (the\n   coercion rules would become too complicated).\n\n   Note: If the right operand\'s type is a subclass of the left\n     operand\'s type and that subclass provides the reflected method\n     for the operation, this method will be called before the left\n     operand\'s non-reflected method.  This behavior allows subclasses\n     to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__imatmul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n   These methods are called to implement the augmented arithmetic\n   assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", "**=",\n   "<<=", ">>=", "&=", "^=", "|=").  These methods should attempt to\n   do the operation in-place (modifying *self*) and return the result\n   (which could be, but does not have to be, *self*).  If a specific\n   method is not defined, the augmented assignment falls back to the\n   normal methods.  For instance, if *x* is an instance of a class\n   with an "__iadd__()" method, "x += y" is equivalent to "x =\n   x.__iadd__(y)" . Otherwise, "x.__add__(y)" and "y.__radd__(x)" are\n   considered, as with the evaluation of "x + y". In certain\n   situations, augmented assignment can result in unexpected errors\n   (see *Why does a_tuple[i] += [\'item\'] raise an exception when the\n   addition works?*), but this behavior is in fact part of the data\n   model.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n   Called to implement the unary arithmetic operations ("-", "+",\n   "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n   Called to implement the built-in functions "complex()", "int()",\n   "float()" and "round()".  Should return a value of the appropriate\n   type.\n\nobject.__index__(self)\n\n   Called to implement "operator.index()", and whenever Python needs\n   to losslessly convert the numeric object to an integer object (such\n   as in slicing, or in the built-in "bin()", "hex()" and "oct()"\n   functions). Presence of this method indicates that the numeric\n   object is an integer type.  Must return an integer.\n\n   Note: In order to have a coherent integer type class, when\n     "__index__()" is defined "__int__()" should also be defined, and\n     both should return the same value.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code.  Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n   Enter the runtime context related to this object. The "with"\n   statement will bind this method\'s return value to the target(s)\n   specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n   Exit the runtime context related to this object. The parameters\n   describe the exception that caused the context to be exited. If the\n   context was exited without an exception, all three arguments will\n   be "None".\n\n   If an exception is supplied, and the method wishes to suppress the\n   exception (i.e., prevent it from being propagated), it should\n   return a true value. Otherwise, the exception will be processed\n   normally upon exit from this method.\n\n   Note that "__exit__()" methods should not reraise the passed-in\n   exception; this is the caller\'s responsibility.\n\nSee also: **PEP 343** - The "with" statement\n\n     The specification, background, and examples for the Python "with"\n     statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary.  That behaviour is the reason why\nthe following code raises an exception:\n\n   >>> class C:\n   ...     pass\n   ...\n   >>> c = C()\n   >>> c.__len__ = lambda: 5\n   >>> len(c)\n   Traceback (most recent call last):\n     File "<stdin>", line 1, in <module>\n   TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as "__hash__()" and "__repr__()" that are implemented by\nall objects, including type objects. If the implicit lookup of these\nmethods used the conventional lookup process, they would fail when\ninvoked on the type object itself:\n\n   >>> 1 .__hash__() == hash(1)\n   True\n   >>> int.__hash__() == hash(int)\n   Traceback (most recent call last):\n     File "<stdin>", line 1, in <module>\n   TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n   >>> type(1).__hash__(1) == hash(1)\n   True\n   >>> type(int).__hash__(int) == hash(int)\n   True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe "__getattribute__()" method even of the object\'s metaclass:\n\n   >>> class Meta(type):\n   ...     def __getattribute__(*args):\n   ...         print("Metaclass getattribute invoked")\n   ...         return type.__getattribute__(*args)\n   ...\n   >>> class C(object, metaclass=Meta):\n   ...     def __len__(self):\n   ...         return 10\n   ...     def __getattribute__(*args):\n   ...         print("Class getattribute invoked")\n   ...         return object.__getattribute__(*args)\n   ...\n   >>> c = C()\n   >>> c.__len__()                 # Explicit lookup via instance\n   Class getattribute invoked\n   10\n   >>> type(c).__len__(c)          # Explicit lookup via type\n   Metaclass getattribute invoked\n   10\n   >>> len(c)                      # Implicit lookup\n   10\n\nBypassing the "__getattribute__()" machinery in this fashion provides\nsignificant scope for speed optimisations within the interpreter, at\nthe cost of some flexibility in the handling of special methods (the\nspecial method *must* be set on the class object itself in order to be\nconsistently invoked by the interpreter).\n',
+ 'string-methods': u'\nString Methods\n**************\n\nStrings implement all of the *common* sequence operations, along with\nthe additional methods described below.\n\nStrings also support two styles of string formatting, one providing a\nlarge degree of flexibility and customization (see "str.format()",\n*Format String Syntax* and *Custom String Formatting*) and the other\nbased on C "printf" style formatting that handles a narrower range of\ntypes and is slightly harder to use correctly, but is often faster for\nthe cases it can handle (*printf-style String Formatting*).\n\nThe *Text Processing Services* section of the standard library covers\na number of other modules that provide various text related utilities\n(including regular expression support in the "re" module).\n\nstr.capitalize()\n\n   Return a copy of the string with its first character capitalized\n   and the rest lowercased.\n\nstr.casefold()\n\n   Return a casefolded copy of the string. Casefolded strings may be\n   used for caseless matching.\n\n   Casefolding is similar to lowercasing but more aggressive because\n   it is intended to remove all case distinctions in a string. For\n   example, the German lowercase letter "\'\xdf\'" is equivalent to ""ss"".\n   Since it is already lowercase, "lower()" would do nothing to "\'\xdf\'";\n   "casefold()" converts it to ""ss"".\n\n   The casefolding algorithm is described in section 3.13 of the\n   Unicode Standard.\n\n   New in version 3.3.\n\nstr.center(width[, fillchar])\n\n   Return centered in a string of length *width*. Padding is done\n   using the specified *fillchar* (default is an ASCII space). The\n   original string is returned if *width* is less than or equal to\n   "len(s)".\n\nstr.count(sub[, start[, end]])\n\n   Return the number of non-overlapping occurrences of substring *sub*\n   in the range [*start*, *end*].  Optional arguments *start* and\n   *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n   Return an encoded version of the string as a bytes object. Default\n   encoding is "\'utf-8\'". *errors* may be given to set a different\n   error handling scheme. The default for *errors* is "\'strict\'",\n   meaning that encoding errors raise a "UnicodeError". Other possible\n   values are "\'ignore\'", "\'replace\'", "\'xmlcharrefreplace\'",\n   "\'backslashreplace\'" and any other name registered via\n   "codecs.register_error()", see section *Error Handlers*. For a list\n   of possible encodings, see section *Standard Encodings*.\n\n   Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n   Return "True" if the string ends with the specified *suffix*,\n   otherwise return "False".  *suffix* can also be a tuple of suffixes\n   to look for.  With optional *start*, test beginning at that\n   position.  With optional *end*, stop comparing at that position.\n\nstr.expandtabs(tabsize=8)\n\n   Return a copy of the string where all tab characters are replaced\n   by one or more spaces, depending on the current column and the\n   given tab size.  Tab positions occur every *tabsize* characters\n   (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n   To expand the string, the current column is set to zero and the\n   string is examined character by character.  If the character is a\n   tab ("\\t"), one or more space characters are inserted in the result\n   until the current column is equal to the next tab position. (The\n   tab character itself is not copied.)  If the character is a newline\n   ("\\n") or return ("\\r"), it is copied and the current column is\n   reset to zero.  Any other character is copied unchanged and the\n   current column is incremented by one regardless of how the\n   character is represented when printed.\n\n   >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n   \'01      012     0123    01234\'\n   >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n   \'01  012 0123    01234\'\n\nstr.find(sub[, start[, end]])\n\n   Return the lowest index in the string where substring *sub* is\n   found within the slice "s[start:end]".  Optional arguments *start*\n   and *end* are interpreted as in slice notation.  Return "-1" if\n   *sub* is not found.\n\n   Note: The "find()" method should be used only if you need to know\n     the position of *sub*.  To check if *sub* is a substring or not,\n     use the "in" operator:\n\n        >>> \'Py\' in \'Python\'\n        True\n\nstr.format(*args, **kwargs)\n\n   Perform a string formatting operation.  The string on which this\n   method is called can contain literal text or replacement fields\n   delimited by braces "{}".  Each replacement field contains either\n   the numeric index of a positional argument, or the name of a\n   keyword argument.  Returns a copy of the string where each\n   replacement field is replaced with the string value of the\n   corresponding argument.\n\n   >>> "The sum of 1 + 2 is {0}".format(1+2)\n   \'The sum of 1 + 2 is 3\'\n\n   See *Format String Syntax* for a description of the various\n   formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n   Similar to "str.format(**mapping)", except that "mapping" is used\n   directly and not copied to a "dict".  This is useful if for example\n   "mapping" is a dict subclass:\n\n   >>> class Default(dict):\n   ...     def __missing__(self, key):\n   ...         return key\n   ...\n   >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n   \'Guido was born in country\'\n\n   New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n   Like "find()", but raise "ValueError" when the substring is not\n   found.\n\nstr.isalnum()\n\n   Return true if all characters in the string are alphanumeric and\n   there is at least one character, false otherwise.  A character "c"\n   is alphanumeric if one of the following returns "True":\n   "c.isalpha()", "c.isdecimal()", "c.isdigit()", or "c.isnumeric()".\n\nstr.isalpha()\n\n   Return true if all characters in the string are alphabetic and\n   there is at least one character, false otherwise.  Alphabetic\n   characters are those characters defined in the Unicode character\n   database as "Letter", i.e., those with general category property\n   being one of "Lm", "Lt", "Lu", "Ll", or "Lo".  Note that this is\n   different from the "Alphabetic" property defined in the Unicode\n   Standard.\n\nstr.isdecimal()\n\n   Return true if all characters in the string are decimal characters\n   and there is at least one character, false otherwise. Decimal\n   characters are those from general category "Nd". This category\n   includes digit characters, and all characters that can be used to\n   form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n   Return true if all characters in the string are digits and there is\n   at least one character, false otherwise.  Digits include decimal\n   characters and digits that need special handling, such as the\n   compatibility superscript digits.  Formally, a digit is a character\n   that has the property value Numeric_Type=Digit or\n   Numeric_Type=Decimal.\n\nstr.isidentifier()\n\n   Return true if the string is a valid identifier according to the\n   language definition, section *Identifiers and keywords*.\n\n   Use "keyword.iskeyword()" to test for reserved identifiers such as\n   "def" and "class".\n\nstr.islower()\n\n   Return true if all cased characters [4] in the string are lowercase\n   and there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n   Return true if all characters in the string are numeric characters,\n   and there is at least one character, false otherwise. Numeric\n   characters include digit characters, and all characters that have\n   the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n   ONE FIFTH.  Formally, numeric characters are those with the\n   property value Numeric_Type=Digit, Numeric_Type=Decimal or\n   Numeric_Type=Numeric.\n\nstr.isprintable()\n\n   Return true if all characters in the string are printable or the\n   string is empty, false otherwise.  Nonprintable characters are\n   those characters defined in the Unicode character database as\n   "Other" or "Separator", excepting the ASCII space (0x20) which is\n   considered printable.  (Note that printable characters in this\n   context are those which should not be escaped when "repr()" is\n   invoked on a string.  It has no bearing on the handling of strings\n   written to "sys.stdout" or "sys.stderr".)\n\nstr.isspace()\n\n   Return true if there are only whitespace characters in the string\n   and there is at least one character, false otherwise.  Whitespace\n   characters  are those characters defined in the Unicode character\n   database as "Other" or "Separator" and those with bidirectional\n   property being one of "WS", "B", or "S".\n\nstr.istitle()\n\n   Return true if the string is a titlecased string and there is at\n   least one character, for example uppercase characters may only\n   follow uncased characters and lowercase characters only cased ones.\n   Return false otherwise.\n\nstr.isupper()\n\n   Return true if all cased characters [4] in the string are uppercase\n   and there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n   Return a string which is the concatenation of the strings in the\n   *iterable* *iterable*.  A "TypeError" will be raised if there are\n   any non-string values in *iterable*, including "bytes" objects.\n   The separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n   Return the string left justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is an ASCII\n   space). The original string is returned if *width* is less than or\n   equal to "len(s)".\n\nstr.lower()\n\n   Return a copy of the string with all the cased characters [4]\n   converted to lowercase.\n\n   The lowercasing algorithm used is described in section 3.13 of the\n   Unicode Standard.\n\nstr.lstrip([chars])\n\n   Return a copy of the string with leading characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or "None", the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a prefix; rather,\n   all combinations of its values are stripped:\n\n      >>> \'   spacious   \'.lstrip()\n      \'spacious   \'\n      >>> \'www.example.com\'.lstrip(\'cmowz.\')\n      \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n   This static method returns a translation table usable for\n   "str.translate()".\n\n   If there is only one argument, it must be a dictionary mapping\n   Unicode ordinals (integers) or characters (strings of length 1) to\n   Unicode ordinals, strings (of arbitrary lengths) or None.\n   Character keys will then be converted to ordinals.\n\n   If there are two arguments, they must be strings of equal length,\n   and in the resulting dictionary, each character in x will be mapped\n   to the character at the same position in y.  If there is a third\n   argument, it must be a string, whose characters will be mapped to\n   None in the result.\n\nstr.partition(sep)\n\n   Split the string at the first occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing the string itself, followed by\n   two empty strings.\n\nstr.replace(old, new[, count])\n\n   Return a copy of the string with all occurrences of substring *old*\n   replaced by *new*.  If the optional argument *count* is given, only\n   the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n   Return the highest index in the string where substring *sub* is\n   found, such that *sub* is contained within "s[start:end]".\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return "-1" on failure.\n\nstr.rindex(sub[, start[, end]])\n\n   Like "rfind()" but raises "ValueError" when the substring *sub* is\n   not found.\n\nstr.rjust(width[, fillchar])\n\n   Return the string right justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is an ASCII\n   space). The original string is returned if *width* is less than or\n   equal to "len(s)".\n\nstr.rpartition(sep)\n\n   Split the string at the last occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing two empty strings, followed by\n   the string itself.\n\nstr.rsplit(sep=None, maxsplit=-1)\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n   are done, the *rightmost* ones.  If *sep* is not specified or\n   "None", any whitespace string is a separator.  Except for splitting\n   from the right, "rsplit()" behaves like "split()" which is\n   described in detail below.\n\nstr.rstrip([chars])\n\n   Return a copy of the string with trailing characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or "None", the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a suffix; rather,\n   all combinations of its values are stripped:\n\n      >>> \'   spacious   \'.rstrip()\n      \'   spacious\'\n      >>> \'mississippi\'.rstrip(\'ipz\')\n      \'mississ\'\n\nstr.split(sep=None, maxsplit=-1)\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string.  If *maxsplit* is given, at most *maxsplit*\n   splits are done (thus, the list will have at most "maxsplit+1"\n   elements).  If *maxsplit* is not specified or "-1", then there is\n   no limit on the number of splits (all possible splits are made).\n\n   If *sep* is given, consecutive delimiters are not grouped together\n   and are deemed to delimit empty strings (for example,\n   "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', \'2\']").  The *sep* argument\n   may consist of multiple characters (for example,\n   "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', \'3\']"). Splitting an\n   empty string with a specified separator returns "[\'\']".\n\n   For example:\n\n      >>> \'1,2,3\'.split(\',\')\n      [\'1\', \'2\', \'3\']\n      >>> \'1,2,3\'.split(\',\', maxsplit=1)\n      [\'1\', \'2,3\']\n      >>> \'1,2,,3,\'.split(\',\')\n      [\'1\', \'2\', \'\', \'3\', \'\']\n\n   If *sep* is not specified or is "None", a different splitting\n   algorithm is applied: runs of consecutive whitespace are regarded\n   as a single separator, and the result will contain no empty strings\n   at the start or end if the string has leading or trailing\n   whitespace.  Consequently, splitting an empty string or a string\n   consisting of just whitespace with a "None" separator returns "[]".\n\n   For example:\n\n      >>> \'1 2 3\'.split()\n      [\'1\', \'2\', \'3\']\n      >>> \'1 2 3\'.split(maxsplit=1)\n      [\'1\', \'2 3\']\n      >>> \'   1   2   3   \'.split()\n      [\'1\', \'2\', \'3\']\n\nstr.splitlines([keepends])\n\n   Return a list of the lines in the string, breaking at line\n   boundaries.  Line breaks are not included in the resulting list\n   unless *keepends* is given and true.\n\n   This method splits on the following line boundaries.  In\n   particular, the boundaries are a superset of *universal newlines*.\n\n   +-------------------------+-------------------------------+\n   | Representation          | Description                   |\n   +=========================+===============================+\n   | "\\n"                    | Line Feed                     |\n   +-------------------------+-------------------------------+\n   | "\\r"                    | Carriage Return               |\n   +-------------------------+-------------------------------+\n   | "\\r\\n"                  | Carriage Return + Line Feed   |\n   +-------------------------+-------------------------------+\n   | "\\v" or "\\x0b"          | Line Tabulation               |\n   +-------------------------+-------------------------------+\n   | "\\f" or "\\x0c"          | Form Feed                     |\n   +-------------------------+-------------------------------+\n   | "\\x1c"                  | File Separator                |\n   +-------------------------+-------------------------------+\n   | "\\x1d"                  | Group Separator               |\n   +-------------------------+-------------------------------+\n   | "\\x1e"                  | Record Separator              |\n   +-------------------------+-------------------------------+\n   | "\\x85"                  | Next Line (C1 Control Code)   |\n   +-------------------------+-------------------------------+\n   | "\\u2028"                | Line Separator                |\n   +-------------------------+-------------------------------+\n   | "\\u2029"                | Paragraph Separator           |\n   +-------------------------+-------------------------------+\n\n   Changed in version 3.2: "\\v" and "\\f" added to list of line\n   boundaries.\n\n   For example:\n\n      >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()\n      [\'ab c\', \'\', \'de fg\', \'kl\']\n      >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines(keepends=True)\n      [\'ab c\\n\', \'\\n\', \'de fg\\r\', \'kl\\r\\n\']\n\n   Unlike "split()" when a delimiter string *sep* is given, this\n   method returns an empty list for the empty string, and a terminal\n   line break does not result in an extra line:\n\n      >>> "".splitlines()\n      []\n      >>> "One line\\n".splitlines()\n      [\'One line\']\n\n   For comparison, "split(\'\\n\')" gives:\n\n      >>> \'\'.split(\'\\n\')\n      [\'\']\n      >>> \'Two lines\\n\'.split(\'\\n\')\n      [\'Two lines\', \'\']\n\nstr.startswith(prefix[, start[, end]])\n\n   Return "True" if string starts with the *prefix*, otherwise return\n   "False". *prefix* can also be a tuple of prefixes to look for.\n   With optional *start*, test string beginning at that position.\n   With optional *end*, stop comparing string at that position.\n\nstr.strip([chars])\n\n   Return a copy of the string with the leading and trailing\n   characters removed. The *chars* argument is a string specifying the\n   set of characters to be removed. If omitted or "None", the *chars*\n   argument defaults to removing whitespace. The *chars* argument is\n   not a prefix or suffix; rather, all combinations of its values are\n   stripped:\n\n      >>> \'   spacious   \'.strip()\n      \'spacious\'\n      >>> \'www.example.com\'.strip(\'cmowz.\')\n      \'example\'\n\n   The outermost leading and trailing *chars* argument values are\n   stripped from the string. Characters are removed from the leading\n   end until reaching a string character that is not contained in the\n   set of characters in *chars*. A similar action takes place on the\n   trailing end. For example:\n\n      >>> comment_string = \'#....... Section 3.2.1 Issue #32 .......\'\n      >>> comment_string.strip(\'.#! \')\n      \'Section 3.2.1 Issue #32\'\n\nstr.swapcase()\n\n   Return a copy of the string with uppercase characters converted to\n   lowercase and vice versa. Note that it is not necessarily true that\n   "s.swapcase().swapcase() == s".\n\nstr.title()\n\n   Return a titlecased version of the string where words start with an\n   uppercase character and the remaining characters are lowercase.\n\n   For example:\n\n      >>> \'Hello world\'.title()\n      \'Hello World\'\n\n   The algorithm uses a simple language-independent definition of a\n   word as groups of consecutive letters.  The definition works in\n   many contexts but it means that apostrophes in contractions and\n   possessives form word boundaries, which may not be the desired\n   result:\n\n      >>> "they\'re bill\'s friends from the UK".title()\n      "They\'Re Bill\'S Friends From The Uk"\n\n   A workaround for apostrophes can be constructed using regular\n   expressions:\n\n      >>> import re\n      >>> def titlecase(s):\n      ...     return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n      ...                   lambda mo: mo.group(0)[0].upper() +\n      ...                              mo.group(0)[1:].lower(),\n      ...                   s)\n      ...\n      >>> titlecase("they\'re bill\'s friends.")\n      "They\'re Bill\'s Friends."\n\nstr.translate(table)\n\n   Return a copy of the string in which each character has been mapped\n   through the given translation table.  The table must be an object\n   that implements indexing via "__getitem__()", typically a *mapping*\n   or *sequence*.  When indexed by a Unicode ordinal (an integer), the\n   table object can do any of the following: return a Unicode ordinal\n   or a string, to map the character to one or more other characters;\n   return "None", to delete the character from the return string; or\n   raise a "LookupError" exception, to map the character to itself.\n\n   You can use "str.maketrans()" to create a translation map from\n   character-to-character mappings in different formats.\n\n   See also the "codecs" module for a more flexible approach to custom\n   character mappings.\n\nstr.upper()\n\n   Return a copy of the string with all the cased characters [4]\n   converted to uppercase.  Note that "str.upper().isupper()" might be\n   "False" if "s" contains uncased characters or if the Unicode\n   category of the resulting character(s) is not "Lu" (Letter,\n   uppercase), but e.g. "Lt" (Letter, titlecase).\n\n   The uppercasing algorithm used is described in section 3.13 of the\n   Unicode Standard.\n\nstr.zfill(width)\n\n   Return a copy of the string left filled with ASCII "\'0\'" digits to\n   make a string of length *width*. A leading sign prefix\n   ("\'+\'"/"\'-\'") is handled by inserting the padding *after* the sign\n   character rather than before. The original string is returned if\n   *width* is less than or equal to "len(s)".\n\n   For example:\n\n      >>> "42".zfill(5)\n      \'00042\'\n      >>> "-42".zfill(5)\n      \'-0042\'\n',
+ 'strings': u'\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n   stringliteral   ::= [stringprefix](shortstring | longstring)\n   stringprefix    ::= "r" | "u" | "R" | "U"\n   shortstring     ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n   longstring      ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n   shortstringitem ::= shortstringchar | stringescapeseq\n   longstringitem  ::= longstringchar | stringescapeseq\n   shortstringchar ::= <any source character except "\\" or newline or the quote>\n   longstringchar  ::= <any source character except "\\">\n   stringescapeseq ::= "\\" <any source character>\n\n   bytesliteral   ::= bytesprefix(shortbytes | longbytes)\n   bytesprefix    ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"\n   shortbytes     ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n   longbytes      ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n   shortbytesitem ::= shortbyteschar | bytesescapeseq\n   longbytesitem  ::= longbyteschar | bytesescapeseq\n   shortbyteschar ::= <any ASCII character except "\\" or newline or the quote>\n   longbyteschar  ::= <any ASCII character except "\\">\n   bytesescapeseq ::= "\\" <any ASCII character>\n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the "stringprefix" or "bytesprefix"\nand the rest of the literal. The source character set is defined by\nthe encoding declaration; it is UTF-8 if no encoding declaration is\ngiven in the source file; see section *Encoding declarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes ("\'") or double quotes (""").  They can also be enclosed\nin matching groups of three single or double quotes (these are\ngenerally referred to as *triple-quoted strings*).  The backslash\n("\\") character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with "\'b\'" or "\'B\'"; they produce\nan instance of the "bytes" type instead of the "str" type.  They may\nonly contain ASCII characters; bytes with a numeric value of 128 or\ngreater must be expressed with escapes.\n\nAs of Python 3.3 it is possible again to prefix string literals with a\n"u" prefix to simplify maintenance of dual 2.x and 3.x codebases.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter "\'r\'" or "\'R\'"; such strings are called *raw strings* and treat\nbackslashes as literal characters.  As a result, in string literals,\n"\'\\U\'" and "\'\\u\'" escapes in raw strings are not treated specially.\nGiven that Python 2.x\'s raw unicode literals behave differently than\nPython 3.x\'s the "\'ur\'" syntax is not supported.\n\nNew in version 3.3: The "\'rb\'" prefix of raw bytes literals has been\nadded as a synonym of "\'br\'".\n\nNew in version 3.3: Support for the unicode legacy literal\n("u\'value\'") was reintroduced to simplify the maintenance of dual\nPython 2.x and 3.x codebases. See **PEP 414** for more information.\n\nIn triple-quoted literals, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the literal.  (A "quote" is the character used to open the\nliteral, i.e. either "\'" or """.)\n\nUnless an "\'r\'" or "\'R\'" prefix is present, escape sequences in string\nand bytes literals are interpreted according to rules similar to those\nused by Standard C.  The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence   | Meaning                           | Notes   |\n+===================+===================================+=========+\n| "\\newline"        | Backslash and newline ignored     |         |\n+-------------------+-----------------------------------+---------+\n| "\\\\"              | Backslash ("\\")                   |         |\n+-------------------+-----------------------------------+---------+\n| "\\\'"              | Single quote ("\'")                |         |\n+-------------------+-----------------------------------+---------+\n| "\\""              | Double quote (""")                |         |\n+-------------------+-----------------------------------+---------+\n| "\\a"              | ASCII Bell (BEL)                  |         |\n+-------------------+-----------------------------------+---------+\n| "\\b"              | ASCII Backspace (BS)              |         |\n+-------------------+-----------------------------------+---------+\n| "\\f"              | ASCII Formfeed (FF)               |         |\n+-------------------+-----------------------------------+---------+\n| "\\n"              | ASCII Linefeed (LF)               |         |\n+-------------------+-----------------------------------+---------+\n| "\\r"              | ASCII Carriage Return (CR)        |         |\n+-------------------+-----------------------------------+---------+\n| "\\t"              | ASCII Horizontal Tab (TAB)        |         |\n+-------------------+-----------------------------------+---------+\n| "\\v"              | ASCII Vertical Tab (VT)           |         |\n+-------------------+-----------------------------------+---------+\n| "\\ooo"            | Character with octal value *ooo*  | (1,3)   |\n+-------------------+-----------------------------------+---------+\n| "\\xhh"            | Character with hex value *hh*     | (2,3)   |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence   | Meaning                           | Notes   |\n+===================+===================================+=========+\n| "\\N{name}"        | Character named *name* in the     | (4)     |\n|                   | Unicode database                  |         |\n+-------------------+-----------------------------------+---------+\n| "\\uxxxx"          | Character with 16-bit hex value   | (5)     |\n|                   | *xxxx*                            |         |\n+-------------------+-----------------------------------+---------+\n| "\\Uxxxxxxxx"      | Character with 32-bit hex value   | (6)     |\n|                   | *xxxxxxxx*                        |         |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the\n   byte with the given value. In a string literal, these escapes\n   denote a Unicode character with the given value.\n\n4. Changed in version 3.3: Support for name aliases [1] has been\n   added.\n\n5. Exactly four hex digits are required.\n\n6. Any Unicode character can be encoded this way.  Exactly eight\n   hex digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the result*.  (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.)  It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw literal, quotes can be escaped with a backslash, but the\nbackslash remains in the result; for example, "r"\\""" is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; "r"\\"" is not a valid string literal (even a raw string cannot\nend in an odd number of backslashes).  Specifically, *a raw literal\ncannot end in a single backslash* (since the backslash would escape\nthe following quote character).  Note also that a single backslash\nfollowed by a newline is interpreted as those two characters as part\nof the literal, *not* as a line continuation.\n',
  'subscriptions': u'\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n   subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription\n(lists or dictionaries for example).  User-defined objects can support\nsubscription by defining a "__getitem__()" method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey.  (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer or a slice (as discussed in the following section).\n\nThe formal syntax makes no special provision for negative indices in\nsequences; however, built-in sequences all provide a "__getitem__()"\nmethod that interprets negative indices by adding the length of the\nsequence to the index (so that "x[-1]" selects the last item of "x").\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero). Since the support for\nnegative indices and slicing occurs in the object\'s "__getitem__()"\nmethod, subclasses overriding this method will need to explicitly add\nthat support.\n\nA string\'s items are characters.  A character is not a separate data\ntype but a string of exactly one character.\n',
  'truth': u'\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an "if" or\n"while" condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* "None"\n\n* "False"\n\n* zero of any numeric type, for example, "0", "0.0", "0j".\n\n* any empty sequence, for example, "\'\'", "()", "[]".\n\n* any empty mapping, for example, "{}".\n\n* instances of user-defined classes, if the class defines a\n  "__bool__()" or "__len__()" method, when that method returns the\n  integer zero or "bool" value "False". [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn "0" or "False" for false and "1" or "True" for true, unless\notherwise stated. (Important exception: the Boolean operations "or"\nand "and" always return one of their operands.)\n',
  'try': u'\nThe "try" statement\n*******************\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n   try_stmt  ::= try1_stmt | try2_stmt\n   try1_stmt ::= "try" ":" suite\n                 ("except" [expression ["as" identifier]] ":" suite)+\n                 ["else" ":" suite]\n                 ["finally" ":" suite]\n   try2_stmt ::= "try" ":" suite\n                 "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started.  This search inspects the except clauses\nin turn until one is found that matches the exception.  An expression-\nless except clause, if present, must be last; it matches any\nexception.  For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception.  An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed.  All except\nclauses must have an executable block.  When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause.  This is as if\n\n   except E as N:\n       foo\n\nwas translated to\n\n   except E as N:\n       try:\n           foo\n       finally:\n           del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause.  Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred.  "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler.  The "try"\nclause is executed, including any "except" and "else" clauses.  If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed.  If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause.  If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n   >>> def f():\n   ...     try:\n   ...         1/0\n   ...     finally:\n   ...         return 42\n   ...\n   >>> f()\n   42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed.  Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n   >>> def foo():\n   ...     try:\n   ...         return \'try\'\n   ...     finally:\n   ...         return \'finally\'\n   ...\n   >>> foo()\n   \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n',
@@ -71,9 +71,9 @@ topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert
  'typesmapping': u'\nMapping Types --- "dict"\n************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects.  There is currently only one standard\nmapping type, the *dictionary*.  (For other containers see the built-\nin "list", "set", and "tuple" classes, and the "collections" module.)\n\nA dictionary\'s keys are *almost* arbitrary values.  Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys.  Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as "1" and "1.0") then they can be used interchangeably to index\nthe same dictionary entry.  (Note however, that since computers store\nfloating-point numbers as approximations it is usually unwise to use\nthem as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of "key:\nvalue" pairs within braces, for example: "{\'jack\': 4098, \'sjoerd\':\n4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the "dict"\nconstructor.\n\nclass class dict(**kwarg)\nclass class dict(mapping, **kwarg)\nclass class dict(iterable, **kwarg)\n\n   Return a new dictionary initialized from an optional positional\n   argument and a possibly empty set of keyword arguments.\n\n   If no positional argument is given, an empty dictionary is created.\n   If a positional argument is given and it is a mapping object, a\n   dictionary is created with the same key-value pairs as the mapping\n   object.  Otherwise, the positional argument must be an *iterable*\n   object.  Each item in the iterable must itself be an iterable with\n   exactly two objects.  The first object of each item becomes a key\n   in the new dictionary, and the second object the corresponding\n   value.  If a key occurs more than once, the last value for that key\n   becomes the corresponding value in the new dictionary.\n\n   If keyword arguments are given, the keyword arguments and their\n   values are added to the dictionary created from the positional\n   argument.  If a key being added is already present, the value from\n   the keyword argument replaces the value from the positional\n   argument.\n\n   To illustrate, the following examples all return a dictionary equal\n   to "{"one": 1, "two": 2, "three": 3}":\n\n      >>> a = dict(one=1, two=2, three=3)\n      >>> b = {\'one\': 1, \'two\': 2, \'three\': 3}\n      >>> c = dict(zip([\'one\', \'two\', \'three\'], [1, 2, 3]))\n      >>> d = dict([(\'two\', 2), (\'one\', 1), (\'three\', 3)])\n      >>> e = dict({\'three\': 3, \'one\': 1, \'two\': 2})\n      >>> a == b == c == d == e\n      True\n\n   Providing keyword arguments as in the first example only works for\n   keys that are valid Python identifiers.  Otherwise, any valid keys\n   can be used.\n\n   These are the operations that dictionaries support (and therefore,\n   custom mapping types should support too):\n\n   len(d)\n\n      Return the number of items in the dictionary *d*.\n\n   d[key]\n\n      Return the item of *d* with key *key*.  Raises a "KeyError" if\n      *key* is not in the map.\n\n      If a subclass of dict defines a method "__missing__()" and *key*\n      is not present, the "d[key]" operation calls that method with\n      the key *key* as argument.  The "d[key]" operation then returns\n      or raises whatever is returned or raised by the\n      "__missing__(key)" call. No other operations or methods invoke\n      "__missing__()". If "__missing__()" is not defined, "KeyError"\n      is raised. "__missing__()" must be a method; it cannot be an\n      instance variable:\n\n         >>> class Counter(dict):\n         ...     def __missing__(self, key):\n         ...         return 0\n         >>> c = Counter()\n         >>> c[\'red\']\n         0\n         >>> c[\'red\'] += 1\n         >>> c[\'red\']\n         1\n\n      The example above shows part of the implementation of\n      "collections.Counter".  A different "__missing__" method is used\n      by "collections.defaultdict".\n\n   d[key] = value\n\n      Set "d[key]" to *value*.\n\n   del d[key]\n\n      Remove "d[key]" from *d*.  Raises a "KeyError" if *key* is not\n      in the map.\n\n   key in d\n\n      Return "True" if *d* has a key *key*, else "False".\n\n   key not in d\n\n      Equivalent to "not key in d".\n\n   iter(d)\n\n      Return an iterator over the keys of the dictionary.  This is a\n      shortcut for "iter(d.keys())".\n\n   clear()\n\n      Remove all items from the dictionary.\n\n   copy()\n\n      Return a shallow copy of the dictionary.\n\n   classmethod fromkeys(seq[, value])\n\n      Create a new dictionary with keys from *seq* and values set to\n      *value*.\n\n      "fromkeys()" is a class method that returns a new dictionary.\n      *value* defaults to "None".\n\n   get(key[, default])\n\n      Return the value for *key* if *key* is in the dictionary, else\n      *default*. If *default* is not given, it defaults to "None", so\n      that this method never raises a "KeyError".\n\n   items()\n\n      Return a new view of the dictionary\'s items ("(key, value)"\n      pairs). See the *documentation of view objects*.\n\n   keys()\n\n      Return a new view of the dictionary\'s keys.  See the\n      *documentation of view objects*.\n\n   pop(key[, default])\n\n      If *key* is in the dictionary, remove it and return its value,\n      else return *default*.  If *default* is not given and *key* is\n      not in the dictionary, a "KeyError" is raised.\n\n   popitem()\n\n      Remove and return an arbitrary "(key, value)" pair from the\n      dictionary.\n\n      "popitem()" is useful to destructively iterate over a\n      dictionary, as often used in set algorithms.  If the dictionary\n      is empty, calling "popitem()" raises a "KeyError".\n\n   setdefault(key[, default])\n\n      If *key* is in the dictionary, return its value.  If not, insert\n      *key* with a value of *default* and return *default*.  *default*\n      defaults to "None".\n\n   update([other])\n\n      Update the dictionary with the key/value pairs from *other*,\n      overwriting existing keys.  Return "None".\n\n      "update()" accepts either another dictionary object or an\n      iterable of key/value pairs (as tuples or other iterables of\n      length two).  If keyword arguments are specified, the dictionary\n      is then updated with those key/value pairs: "d.update(red=1,\n      blue=2)".\n\n   values()\n\n      Return a new view of the dictionary\'s values.  See the\n      *documentation of view objects*.\n\n   Dictionaries compare equal if and only if they have the same "(key,\n   value)" pairs. Order comparisons (\'<\', \'<=\', \'>=\', \'>\') raise\n   "TypeError".\n\nSee also: "types.MappingProxyType" can be used to create a read-only\n  view of a "dict".\n\n\nDictionary view objects\n=======================\n\nThe objects returned by "dict.keys()", "dict.values()" and\n"dict.items()" are *view objects*.  They provide a dynamic view on the\ndictionary\'s entries, which means that when the dictionary changes,\nthe view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n   Return the number of entries in the dictionary.\n\niter(dictview)\n\n   Return an iterator over the keys, values or items (represented as\n   tuples of "(key, value)") in the dictionary.\n\n   Keys and values are iterated over in an arbitrary order which is\n   non-random, varies across Python implementations, and depends on\n   the dictionary\'s history of insertions and deletions. If keys,\n   values and items views are iterated over with no intervening\n   modifications to the dictionary, the order of items will directly\n   correspond.  This allows the creation of "(value, key)" pairs using\n   "zip()": "pairs = zip(d.values(), d.keys())".  Another way to\n   create the same list is "pairs = [(v, k) for (k, v) in d.items()]".\n\n   Iterating views while adding or deleting entries in the dictionary\n   may raise a "RuntimeError" or fail to iterate over all entries.\n\nx in dictview\n\n   Return "True" if *x* is in the underlying dictionary\'s keys, values\n   or items (in the latter case, *x* should be a "(key, value)"\n   tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that "(key, value)" pairs are unique\nand hashable, then the items view is also set-like.  (Values views are\nnot treated as set-like since the entries are generally not unique.)\nFor set-like views, all of the operations defined for the abstract\nbase class "collections.abc.Set" are available (for example, "==",\n"<", or "^").\n\nAn example of dictionary view usage:\n\n   >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n   >>> keys = dishes.keys()\n   >>> values = dishes.values()\n\n   >>> # iteration\n   >>> n = 0\n   >>> for val in values:\n   ...     n += val\n   >>> print(n)\n   504\n\n   >>> # keys and values are iterated over in the same order\n   >>> list(keys)\n   [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n   >>> list(values)\n   [2, 1, 1, 500]\n\n   >>> # view objects are dynamic and reflect dict changes\n   >>> del dishes[\'eggs\']\n   >>> del dishes[\'sausage\']\n   >>> list(keys)\n   [\'spam\', \'bacon\']\n\n   >>> # set operations\n   >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n   {\'bacon\'}\n   >>> keys ^ {\'sausage\', \'juice\'}\n   {\'juice\', \'sausage\', \'bacon\', \'spam\'}\n',
  'typesmethods': u'\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as "append()" on lists)\nand class instance methods.  Built-in methods are described with the\ntypes that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the "self"\nargument to the argument list.  Bound methods have two special read-\nonly attributes: "m.__self__" is the object on which the method\noperates, and "m.__func__" is the function implementing the method.\nCalling "m(arg-1, arg-2, ..., arg-n)" is completely equivalent to\ncalling "m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)".\n\nLike function objects, bound method objects support getting arbitrary\nattributes.  However, since method attributes are actually stored on\nthe underlying function object ("meth.__func__"), setting method\nattributes on bound methods is disallowed.  Attempting to set an\nattribute on a method results in an "AttributeError" being raised.  In\norder to set a method attribute, you need to explicitly set it on the\nunderlying function object:\n\n   >>> class C:\n   ...     def method(self):\n   ...         pass\n   ...\n   >>> c = C()\n   >>> c.method.whoami = \'my name is method\'  # can\'t set on the method\n   Traceback (most recent call last):\n     File "<stdin>", line 1, in <module>\n   AttributeError: \'method\' object has no attribute \'whoami\'\n   >>> c.method.__func__.whoami = \'my name is method\'\n   >>> c.method.whoami\n   \'my name is method\'\n\nSee *The standard type hierarchy* for more information.\n',
  'typesmodules': u'\nModules\n*******\n\nThe only special operation on a module is attribute access: "m.name",\nwhere *m* is a module and *name* accesses a name defined in *m*\'s\nsymbol table. Module attributes can be assigned to.  (Note that the\n"import" statement is not, strictly speaking, an operation on a module\nobject; "import foo" does not require a module object named *foo* to\nexist, rather it requires an (external) *definition* for a module\nnamed *foo* somewhere.)\n\nA special attribute of every module is "__dict__". This is the\ndictionary containing the module\'s symbol table. Modifying this\ndictionary will actually change the module\'s symbol table, but direct\nassignment to the "__dict__" attribute is not possible (you can write\n"m.__dict__[\'a\'] = 1", which defines "m.a" to be "1", but you can\'t\nwrite "m.__dict__ = {}").  Modifying "__dict__" directly is not\nrecommended.\n\nModules built into the interpreter are written like this: "<module\n\'sys\' (built-in)>".  If loaded from a file, they are written as\n"<module \'os\' from \'/usr/local/lib/pythonX.Y/os.pyc\'>".\n',
- 'typesseq': u'\nSequence Types --- "list", "tuple", "range"\n*******************************************\n\nThere are three basic sequence types: lists, tuples, and range\nobjects. Additional sequence types tailored for processing of *binary\ndata* and *text strings* are described in dedicated sections.\n\n\nCommon Sequence Operations\n==========================\n\nThe operations in the following table are supported by most sequence\ntypes, both mutable and immutable. The "collections.abc.Sequence" ABC\nis provided to make it easier to correctly implement these operations\non custom sequence types.\n\nThis table lists the sequence operations sorted in ascending priority.\nIn the table, *s* and *t* are sequences of the same type, *n*, *i*,\n*j* and *k* are integers and *x* is an arbitrary object that meets any\ntype and value restrictions imposed by *s*.\n\nThe "in" and "not in" operations have the same priorities as the\ncomparison operations. The "+" (concatenation) and "*" (repetition)\noperations have the same priority as the corresponding numeric\noperations.\n\n+----------------------------+----------------------------------+------------+\n| Operation                  | Result                           | Notes      |\n+============================+==================================+============+\n| "x in s"                   | "True" if an item of *s* is      | (1)        |\n|                            | equal to *x*, else "False"       |            |\n+----------------------------+----------------------------------+------------+\n| "x not in s"               | "False" if an item of *s* is     | (1)        |\n|                            | equal to *x*, else "True"        |            |\n+----------------------------+----------------------------------+------------+\n| "s + t"                    | the concatenation of *s* and *t* | (6)(7)     |\n+----------------------------+----------------------------------+------------+\n| "s * n" or "n * s"         | equivalent to adding *s* to      | (2)(7)     |\n|                            | itself *n* times                 |            |\n+----------------------------+----------------------------------+------------+\n| "s[i]"                     | *i*th item of *s*, origin 0      | (3)        |\n+----------------------------+----------------------------------+------------+\n| "s[i:j]"                   | slice of *s* from *i* to *j*     | (3)(4)     |\n+----------------------------+----------------------------------+------------+\n| "s[i:j:k]"                 | slice of *s* from *i* to *j*     | (3)(5)     |\n|                            | with step *k*                    |            |\n+----------------------------+----------------------------------+------------+\n| "len(s)"                   | length of *s*                    |            |\n+----------------------------+----------------------------------+------------+\n| "min(s)"                   | smallest item of *s*             |            |\n+----------------------------+----------------------------------+------------+\n| "max(s)"                   | largest item of *s*              |            |\n+----------------------------+----------------------------------+------------+\n| "s.index(x[, i[, j]])"     | index of the first occurrence of | (8)        |\n|                            | *x* in *s* (at or after index    |            |\n|                            | *i* and before index *j*)        |            |\n+----------------------------+----------------------------------+------------+\n| "s.count(x)"               | total number of occurrences of   |            |\n|                            | *x* in *s*                       |            |\n+----------------------------+----------------------------------+------------+\n\nSequences of the same type also support comparisons.  In particular,\ntuples and lists are compared lexicographically by comparing\ncorresponding elements. This means that to compare equal, every\nelement must compare equal and the two sequences must be of the same\ntype and have the same length.  (For full details see *Comparisons* in\nthe language reference.)\n\nNotes:\n\n1. While the "in" and "not in" operations are used only for simple\n   containment testing in the general case, some specialised sequences\n   (such as "str", "bytes" and "bytearray") also use them for\n   subsequence testing:\n\n      >>> "gg" in "eggs"\n      True\n\n2. Values of *n* less than "0" are treated as "0" (which yields an\n   empty sequence of the same type as *s*).  Note that items in the\n   sequence *s* are not copied; they are referenced multiple times.\n   This often haunts new Python programmers; consider:\n\n      >>> lists = [[]] * 3\n      >>> lists\n      [[], [], []]\n      >>> lists[0].append(3)\n      >>> lists\n      [[3], [3], [3]]\n\n   What has happened is that "[[]]" is a one-element list containing\n   an empty list, so all three elements of "[[]] * 3" are references\n   to this single empty list.  Modifying any of the elements of\n   "lists" modifies this single list. You can create a list of\n   different lists this way:\n\n      >>> lists = [[] for i in range(3)]\n      >>> lists[0].append(3)\n      >>> lists[1].append(5)\n      >>> lists[2].append(7)\n      >>> lists\n      [[3], [5], [7]]\n\n   Further explanation is available in the FAQ entry *How do I create\n   a multidimensional list?*.\n\n3. If *i* or *j* is negative, the index is relative to the end of\n   the string: "len(s) + i" or "len(s) + j" is substituted.  But note\n   that "-0" is still "0".\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n   items with index *k* such that "i <= k < j".  If *i* or *j* is\n   greater than "len(s)", use "len(s)".  If *i* is omitted or "None",\n   use "0".  If *j* is omitted or "None", use "len(s)".  If *i* is\n   greater than or equal to *j*, the slice is empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n   sequence of items with index  "x = i + n*k" such that "0 <= n <\n   (j-i)/k".  In other words, the indices are "i", "i+k", "i+2*k",\n   "i+3*k" and so on, stopping when *j* is reached (but never\n   including *j*).  If *i* or *j* is greater than "len(s)", use\n   "len(s)".  If *i* or *j* are omitted or "None", they become "end"\n   values (which end depends on the sign of *k*).  Note, *k* cannot be\n   zero. If *k* is "None", it is treated like "1".\n\n6. Concatenating immutable sequences always results in a new\n   object. This means that building up a sequence by repeated\n   concatenation will have a quadratic runtime cost in the total\n   sequence length. To get a linear runtime cost, you must switch to\n   one of the alternatives below:\n\n   * if concatenating "str" objects, you can build a list and use\n     "str.join()" at the end or else write to an "io.StringIO"\n     instance and retrieve its value when complete\n\n   * if concatenating "bytes" objects, you can similarly use\n     "bytes.join()" or "io.BytesIO", or you can do in-place\n     concatenation with a "bytearray" object.  "bytearray" objects are\n     mutable and have an efficient overallocation mechanism\n\n   * if concatenating "tuple" objects, extend a "list" instead\n\n   * for other types, investigate the relevant class documentation\n\n7. Some sequence types (such as "range") only support item\n   sequences that follow specific patterns, and hence don\'t support\n   sequence concatenation or repetition.\n\n8. "index" raises "ValueError" when *x* is not found in *s*. When\n   supported, the additional arguments to the index method allow\n   efficient searching of subsections of the sequence. Passing the\n   extra arguments is roughly equivalent to using "s[i:j].index(x)",\n   only without copying any data and with the returned index being\n   relative to the start of the sequence rather than the start of the\n   slice.\n\n\nImmutable Sequence Types\n========================\n\nThe only operation that immutable sequence types generally implement\nthat is not also implemented by mutable sequence types is support for\nthe "hash()" built-in.\n\nThis support allows immutable sequences, such as "tuple" instances, to\nbe used as "dict" keys and stored in "set" and "frozenset" instances.\n\nAttempting to hash an immutable sequence that contains unhashable\nvalues will result in "TypeError".\n\n\nMutable Sequence Types\n======================\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation                      | Result                           | Notes                 |\n+================================+==================================+=======================+\n| "s[i] = x"                     | item *i* of *s* is replaced by   |                       |\n|                                | *x*                              |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t"                   | slice of *s* from *i* to *j* is  |                       |\n|                                | replaced by the contents of the  |                       |\n|                                | iterable *t*                     |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]"                   | same as "s[i:j] = []"            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t"                 | the elements of "s[i:j:k]" are   | (1)                   |\n|                                | replaced by those of *t*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]"                 | removes the elements of          |                       |\n|                                | "s[i:j:k]" from the list         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)"                  | appends *x* to the end of the    |                       |\n|                                | sequence (same as                |                       |\n|                                | "s[len(s):len(s)] = [x]")        |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()"                    | removes all items from "s" (same | (5)                   |\n|                                | as "del s[:]")                   |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()"                     | creates a shallow copy of "s"    | (5)                   |\n|                                | (same as "s[:]")                 |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" or "s += t"      | extends *s* with the contents of |                       |\n|                                | *t* (for the most part the same  |                       |\n|                                | as "s[len(s):len(s)] = t")       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s *= n"                       | updates *s* with its contents    | (6)                   |\n|                                | repeated *n* times               |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)"               | inserts *x* into *s* at the      |                       |\n|                                | index given by *i* (same as      |                       |\n|                                | "s[i:i] = [x]")                  |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])"                   | retrieves the item at *i* and    | (2)                   |\n|                                | also removes it from *s*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)"                  | remove the first item from *s*   | (3)                   |\n|                                | where "s[i] == x"                |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()"                  | reverses the items of *s* in     | (4)                   |\n|                                | place                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n   the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n   economy of space when reversing a large sequence.  To remind users\n   that it operates by side effect, it does not return the reversed\n   sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n   interfaces of mutable containers that don\'t support slicing\n   operations (such as "dict" and "set")\n\n   New in version 3.3: "clear()" and "copy()" methods.\n\n6. The value *n* is an integer, or an object implementing\n   "__index__()".  Zero and negative values of *n* clear the sequence.\n   Items in the sequence are not copied; they are referenced multiple\n   times, as explained for "s * n" under *Common Sequence Operations*.\n\n\nLists\n=====\n\nLists are mutable sequences, typically used to store collections of\nhomogeneous items (where the precise degree of similarity will vary by\napplication).\n\nclass class list([iterable])\n\n   Lists may be constructed in several ways:\n\n   * Using a pair of square brackets to denote the empty list: "[]"\n\n   * Using square brackets, separating items with commas: "[a]",\n     "[a, b, c]"\n\n   * Using a list comprehension: "[x for x in iterable]"\n\n   * Using the type constructor: "list()" or "list(iterable)"\n\n   The constructor builds a list whose items are the same and in the\n   same order as *iterable*\'s items.  *iterable* may be either a\n   sequence, a container that supports iteration, or an iterator\n   object.  If *iterable* is already a list, a copy is made and\n   returned, similar to "iterable[:]". For example, "list(\'abc\')"\n   returns "[\'a\', \'b\', \'c\']" and "list( (1, 2, 3) )" returns "[1, 2,\n   3]". If no argument is given, the constructor creates a new empty\n   list, "[]".\n\n   Many other operations also produce lists, including the "sorted()"\n   built-in.\n\n   Lists implement all of the *common* and *mutable* sequence\n   operations. Lists also provide the following additional method:\n\n   sort(*, key=None, reverse=None)\n\n      This method sorts the list in place, using only "<" comparisons\n      between items. Exceptions are not suppressed - if any comparison\n      operations fail, the entire sort operation will fail (and the\n      list will likely be left in a partially modified state).\n\n      "sort()" accepts two arguments that can only be passed by\n      keyword (*keyword-only arguments*):\n\n      *key* specifies a function of one argument that is used to\n      extract a comparison key from each list element (for example,\n      "key=str.lower"). The key corresponding to each item in the list\n      is calculated once and then used for the entire sorting process.\n      The default value of "None" means that list items are sorted\n      directly without calculating a separate key value.\n\n      The "functools.cmp_to_key()" utility is available to convert a\n      2.x style *cmp* function to a *key* function.\n\n      *reverse* is a boolean value.  If set to "True", then the list\n      elements are sorted as if each comparison were reversed.\n\n      This method modifies the sequence in place for economy of space\n      when sorting a large sequence.  To remind users that it operates\n      by side effect, it does not return the sorted sequence (use\n      "sorted()" to explicitly request a new sorted list instance).\n\n      The "sort()" method is guaranteed to be stable.  A sort is\n      stable if it guarantees not to change the relative order of\n      elements that compare equal --- this is helpful for sorting in\n      multiple passes (for example, sort by department, then by salary\n      grade).\n\n      **CPython implementation detail:** While a list is being sorted,\n      the effect of attempting to mutate, or even inspect, the list is\n      undefined.  The C implementation of Python makes the list appear\n      empty for the duration, and raises "ValueError" if it can detect\n      that the list has been mutated during a sort.\n\n\nTuples\n======\n\nTuples are immutable sequences, typically used to store collections of\nheterogeneous data (such as the 2-tuples produced by the "enumerate()"\nbuilt-in). Tuples are also used for cases where an immutable sequence\nof homogeneous data is needed (such as allowing storage in a "set" or\n"dict" instance).\n\nclass class tuple([iterable])\n\n   Tuples may be constructed in a number of ways:\n\n   * Using a pair of parentheses to denote the empty tuple: "()"\n\n   * Using a trailing comma for a singleton tuple: "a," or "(a,)"\n\n   * Separating items with commas: "a, b, c" or "(a, b, c)"\n\n   * Using the "tuple()" built-in: "tuple()" or "tuple(iterable)"\n\n   The constructor builds a tuple whose items are the same and in the\n   same order as *iterable*\'s items.  *iterable* may be either a\n   sequence, a container that supports iteration, or an iterator\n   object.  If *iterable* is already a tuple, it is returned\n   unchanged. For example, "tuple(\'abc\')" returns "(\'a\', \'b\', \'c\')"\n   and "tuple( [1, 2, 3] )" returns "(1, 2, 3)". If no argument is\n   given, the constructor creates a new empty tuple, "()".\n\n   Note that it is actually the comma which makes a tuple, not the\n   parentheses. The parentheses are optional, except in the empty\n   tuple case, or when they are needed to avoid syntactic ambiguity.\n   For example, "f(a, b, c)" is a function call with three arguments,\n   while "f((a, b, c))" is a function call with a 3-tuple as the sole\n   argument.\n\n   Tuples implement all of the *common* sequence operations.\n\nFor heterogeneous collections of data where access by name is clearer\nthan access by index, "collections.namedtuple()" may be a more\nappropriate choice than a simple tuple object.\n\n\nRanges\n======\n\nThe "range" type represents an immutable sequence of numbers and is\ncommonly used for looping a specific number of times in "for" loops.\n\nclass class range(stop)\nclass class range(start, stop[, step])\n\n   The arguments to the range constructor must be integers (either\n   built-in "int" or any object that implements the "__index__"\n   special method).  If the *step* argument is omitted, it defaults to\n   "1". If the *start* argument is omitted, it defaults to "0". If\n   *step* is zero, "ValueError" is raised.\n\n   For a positive *step*, the contents of a range "r" are determined\n   by the formula "r[i] = start + step*i" where "i >= 0" and "r[i] <\n   stop".\n\n   For a negative *step*, the contents of the range are still\n   determined by the formula "r[i] = start + step*i", but the\n   constraints are "i >= 0" and "r[i] > stop".\n\n   A range object will be empty if "r[0]" does not meet the value\n   constraint. Ranges do support negative indices, but these are\n   interpreted as indexing from the end of the sequence determined by\n   the positive indices.\n\n   Ranges containing absolute values larger than "sys.maxsize" are\n   permitted but some features (such as "len()") may raise\n   "OverflowError".\n\n   Range examples:\n\n      >>> list(range(10))\n      [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n      >>> list(range(1, 11))\n      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n      >>> list(range(0, 30, 5))\n      [0, 5, 10, 15, 20, 25]\n      >>> list(range(0, 10, 3))\n      [0, 3, 6, 9]\n      >>> list(range(0, -10, -1))\n      [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]\n      >>> list(range(0))\n      []\n      >>> list(range(1, 0))\n      []\n\n   Ranges implement all of the *common* sequence operations except\n   concatenation and repetition (due to the fact that range objects\n   can only represent sequences that follow a strict pattern and\n   repetition and concatenation will usually violate that pattern).\n\nThe advantage of the "range" type over a regular "list" or "tuple" is\nthat a "range" object will always take the same (small) amount of\nmemory, no matter the size of the range it represents (as it only\nstores the "start", "stop" and "step" values, calculating individual\nitems and subranges as needed).\n\nRange objects implement the "collections.abc.Sequence" ABC, and\nprovide features such as containment tests, element index lookup,\nslicing and support for negative indices (see *Sequence Types ---\nlist, tuple, range*):\n\n>>> r = range(0, 20, 2)\n>>> r\nrange(0, 20, 2)\n>>> 11 in r\nFalse\n>>> 10 in r\nTrue\n>>> r.index(10)\n5\n>>> r[5]\n10\n>>> r[:5]\nrange(0, 10, 2)\n>>> r[-1]\n18\n\nTesting range objects for equality with "==" and "!=" compares them as\nsequences.  That is, two range objects are considered equal if they\nrepresent the same sequence of values.  (Note that two range objects\nthat compare equal might have different "start", "stop" and "step"\nattributes, for example "range(0) == range(2, 1, 3)" or "range(0, 3,\n2) == range(0, 4, 2)".)\n\nChanged in version 3.2: Implement the Sequence ABC. Support slicing\nand negative indices. Test "int" objects for membership in constant\ntime instead of iterating through all items.\n\nChanged in version 3.3: Define \'==\' and \'!=\' to compare range objects\nbased on the sequence of values they define (instead of comparing\nbased on object identity).\n\nNew in version 3.3: The "start", "stop" and "step" attributes.\n',
+ 'typesseq': u'\nSequence Types --- "list", "tuple", "range"\n*******************************************\n\nThere are three basic sequence types: lists, tuples, and range\nobjects. Additional sequence types tailored for processing of *binary\ndata* and *text strings* are described in dedicated sections.\n\n\nCommon Sequence Operations\n==========================\n\nThe operations in the following table are supported by most sequence\ntypes, both mutable and immutable. The "collections.abc.Sequence" ABC\nis provided to make it easier to correctly implement these operations\non custom sequence types.\n\nThis table lists the sequence operations sorted in ascending priority.\nIn the table, *s* and *t* are sequences of the same type, *n*, *i*,\n*j* and *k* are integers and *x* is an arbitrary object that meets any\ntype and value restrictions imposed by *s*.\n\nThe "in" and "not in" operations have the same priorities as the\ncomparison operations. The "+" (concatenation) and "*" (repetition)\noperations have the same priority as the corresponding numeric\noperations.\n\n+----------------------------+----------------------------------+------------+\n| Operation                  | Result                           | Notes      |\n+============================+==================================+============+\n| "x in s"                   | "True" if an item of *s* is      | (1)        |\n|                            | equal to *x*, else "False"       |            |\n+----------------------------+----------------------------------+------------+\n| "x not in s"               | "False" if an item of *s* is     | (1)        |\n|                            | equal to *x*, else "True"        |            |\n+----------------------------+----------------------------------+------------+\n| "s + t"                    | the concatenation of *s* and *t* | (6)(7)     |\n+----------------------------+----------------------------------+------------+\n| "s * n" or "n * s"         | equivalent to adding *s* to      | (2)(7)     |\n|                            | itself *n* times                 |            |\n+----------------------------+----------------------------------+------------+\n| "s[i]"                     | *i*th item of *s*, origin 0      | (3)        |\n+----------------------------+----------------------------------+------------+\n| "s[i:j]"                   | slice of *s* from *i* to *j*     | (3)(4)     |\n+----------------------------+----------------------------------+------------+\n| "s[i:j:k]"                 | slice of *s* from *i* to *j*     | (3)(5)     |\n|                            | with step *k*                    |            |\n+----------------------------+----------------------------------+------------+\n| "len(s)"                   | length of *s*                    |            |\n+----------------------------+----------------------------------+------------+\n| "min(s)"                   | smallest item of *s*             |            |\n+----------------------------+----------------------------------+------------+\n| "max(s)"                   | largest item of *s*              |            |\n+----------------------------+----------------------------------+------------+\n| "s.index(x[, i[, j]])"     | index of the first occurrence of | (8)        |\n|                            | *x* in *s* (at or after index    |            |\n|                            | *i* and before index *j*)        |            |\n+----------------------------+----------------------------------+------------+\n| "s.count(x)"               | total number of occurrences of   |            |\n|                            | *x* in *s*                       |            |\n+----------------------------+----------------------------------+------------+\n\nSequences of the same type also support comparisons.  In particular,\ntuples and lists are compared lexicographically by comparing\ncorresponding elements. This means that to compare equal, every\nelement must compare equal and the two sequences must be of the same\ntype and have the same length.  (For full details see *Comparisons* in\nthe language reference.)\n\nNotes:\n\n1. While the "in" and "not in" operations are used only for simple\n   containment testing in the general case, some specialised sequences\n   (such as "str", "bytes" and "bytearray") also use them for\n   subsequence testing:\n\n      >>> "gg" in "eggs"\n      True\n\n2. Values of *n* less than "0" are treated as "0" (which yields an\n   empty sequence of the same type as *s*).  Note that items in the\n   sequence *s* are not copied; they are referenced multiple times.\n   This often haunts new Python programmers; consider:\n\n      >>> lists = [[]] * 3\n      >>> lists\n      [[], [], []]\n      >>> lists[0].append(3)\n      >>> lists\n      [[3], [3], [3]]\n\n   What has happened is that "[[]]" is a one-element list containing\n   an empty list, so all three elements of "[[]] * 3" are references\n   to this single empty list.  Modifying any of the elements of\n   "lists" modifies this single list. You can create a list of\n   different lists this way:\n\n      >>> lists = [[] for i in range(3)]\n      >>> lists[0].append(3)\n      >>> lists[1].append(5)\n      >>> lists[2].append(7)\n      >>> lists\n      [[3], [5], [7]]\n\n   Further explanation is available in the FAQ entry *How do I create\n   a multidimensional list?*.\n\n3. If *i* or *j* is negative, the index is relative to the end of\n   the string: "len(s) + i" or "len(s) + j" is substituted.  But note\n   that "-0" is still "0".\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n   items with index *k* such that "i <= k < j".  If *i* or *j* is\n   greater than "len(s)", use "len(s)".  If *i* is omitted or "None",\n   use "0".  If *j* is omitted or "None", use "len(s)".  If *i* is\n   greater than or equal to *j*, the slice is empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n   sequence of items with index  "x = i + n*k" such that "0 <= n <\n   (j-i)/k".  In other words, the indices are "i", "i+k", "i+2*k",\n   "i+3*k" and so on, stopping when *j* is reached (but never\n   including *j*).  If *i* or *j* is greater than "len(s)", use\n   "len(s)".  If *i* or *j* are omitted or "None", they become "end"\n   values (which end depends on the sign of *k*).  Note, *k* cannot be\n   zero. If *k* is "None", it is treated like "1".\n\n6. Concatenating immutable sequences always results in a new\n   object. This means that building up a sequence by repeated\n   concatenation will have a quadratic runtime cost in the total\n   sequence length. To get a linear runtime cost, you must switch to\n   one of the alternatives below:\n\n   * if concatenating "str" objects, you can build a list and use\n     "str.join()" at the end or else write to an "io.StringIO"\n     instance and retrieve its value when complete\n\n   * if concatenating "bytes" objects, you can similarly use\n     "bytes.join()" or "io.BytesIO", or you can do in-place\n     concatenation with a "bytearray" object.  "bytearray" objects are\n     mutable and have an efficient overallocation mechanism\n\n   * if concatenating "tuple" objects, extend a "list" instead\n\n   * for other types, investigate the relevant class documentation\n\n7. Some sequence types (such as "range") only support item\n   sequences that follow specific patterns, and hence don\'t support\n   sequence concatenation or repetition.\n\n8. "index" raises "ValueError" when *x* is not found in *s*. When\n   supported, the additional arguments to the index method allow\n   efficient searching of subsections of the sequence. Passing the\n   extra arguments is roughly equivalent to using "s[i:j].index(x)",\n   only without copying any data and with the returned index being\n   relative to the start of the sequence rather than the start of the\n   slice.\n\n\nImmutable Sequence Types\n========================\n\nThe only operation that immutable sequence types generally implement\nthat is not also implemented by mutable sequence types is support for\nthe "hash()" built-in.\n\nThis support allows immutable sequences, such as "tuple" instances, to\nbe used as "dict" keys and stored in "set" and "frozenset" instances.\n\nAttempting to hash an immutable sequence that contains unhashable\nvalues will result in "TypeError".\n\n\nMutable Sequence Types\n======================\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation                      | Result                           | Notes                 |\n+================================+==================================+=======================+\n| "s[i] = x"                     | item *i* of *s* is replaced by   |                       |\n|                                | *x*                              |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t"                   | slice of *s* from *i* to *j* is  |                       |\n|                                | replaced by the contents of the  |                       |\n|                                | iterable *t*                     |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]"                   | same as "s[i:j] = []"            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t"                 | the elements of "s[i:j:k]" are   | (1)                   |\n|                                | replaced by those of *t*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]"                 | removes the elements of          |                       |\n|                                | "s[i:j:k]" from the list         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)"                  | appends *x* to the end of the    |                       |\n|                                | sequence (same as                |                       |\n|                                | "s[len(s):len(s)] = [x]")        |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()"                    | removes all items from "s" (same | (5)                   |\n|                                | as "del s[:]")                   |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()"                     | creates a shallow copy of "s"    | (5)                   |\n|                                | (same as "s[:]")                 |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" or "s += t"      | extends *s* with the contents of |                       |\n|                                | *t* (for the most part the same  |                       |\n|                                | as "s[len(s):len(s)] = t")       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s *= n"                       | updates *s* with its contents    | (6)                   |\n|                                | repeated *n* times               |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)"               | inserts *x* into *s* at the      |                       |\n|                                | index given by *i* (same as      |                       |\n|                                | "s[i:i] = [x]")                  |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])"                   | retrieves the item at *i* and    | (2)                   |\n|                                | also removes it from *s*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)"                  | remove the first item from *s*   | (3)                   |\n|                                | where "s[i] == x"                |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()"                  | reverses the items of *s* in     | (4)                   |\n|                                | place                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n   the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n   economy of space when reversing a large sequence.  To remind users\n   that it operates by side effect, it does not return the reversed\n   sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n   interfaces of mutable containers that don\'t support slicing\n   operations (such as "dict" and "set")\n\n   New in version 3.3: "clear()" and "copy()" methods.\n\n6. The value *n* is an integer, or an object implementing\n   "__index__()".  Zero and negative values of *n* clear the sequence.\n   Items in the sequence are not copied; they are referenced multiple\n   times, as explained for "s * n" under *Common Sequence Operations*.\n\n\nLists\n=====\n\nLists are mutable sequences, typically used to store collections of\nhomogeneous items (where the precise degree of similarity will vary by\napplication).\n\nclass class list([iterable])\n\n   Lists may be constructed in several ways:\n\n   * Using a pair of square brackets to denote the empty list: "[]"\n\n   * Using square brackets, separating items with commas: "[a]",\n     "[a, b, c]"\n\n   * Using a list comprehension: "[x for x in iterable]"\n\n   * Using the type constructor: "list()" or "list(iterable)"\n\n   The constructor builds a list whose items are the same and in the\n   same order as *iterable*\'s items.  *iterable* may be either a\n   sequence, a container that supports iteration, or an iterator\n   object.  If *iterable* is already a list, a copy is made and\n   returned, similar to "iterable[:]". For example, "list(\'abc\')"\n   returns "[\'a\', \'b\', \'c\']" and "list( (1, 2, 3) )" returns "[1, 2,\n   3]". If no argument is given, the constructor creates a new empty\n   list, "[]".\n\n   Many other operations also produce lists, including the "sorted()"\n   built-in.\n\n   Lists implement all of the *common* and *mutable* sequence\n   operations. Lists also provide the following additional method:\n\n   sort(*, key=None, reverse=None)\n\n      This method sorts the list in place, using only "<" comparisons\n      between items. Exceptions are not suppressed - if any comparison\n      operations fail, the entire sort operation will fail (and the\n      list will likely be left in a partially modified state).\n\n      "sort()" accepts two arguments that can only be passed by\n      keyword (*keyword-only arguments*):\n\n      *key* specifies a function of one argument that is used to\n      extract a comparison key from each list element (for example,\n      "key=str.lower"). The key corresponding to each item in the list\n      is calculated once and then used for the entire sorting process.\n      The default value of "None" means that list items are sorted\n      directly without calculating a separate key value.\n\n      The "functools.cmp_to_key()" utility is available to convert a\n      2.x style *cmp* function to a *key* function.\n\n      *reverse* is a boolean value.  If set to "True", then the list\n      elements are sorted as if each comparison were reversed.\n\n      This method modifies the sequence in place for economy of space\n      when sorting a large sequence.  To remind users that it operates\n      by side effect, it does not return the sorted sequence (use\n      "sorted()" to explicitly request a new sorted list instance).\n\n      The "sort()" method is guaranteed to be stable.  A sort is\n      stable if it guarantees not to change the relative order of\n      elements that compare equal --- this is helpful for sorting in\n      multiple passes (for example, sort by department, then by salary\n      grade).\n\n      **CPython implementation detail:** While a list is being sorted,\n      the effect of attempting to mutate, or even inspect, the list is\n      undefined.  The C implementation of Python makes the list appear\n      empty for the duration, and raises "ValueError" if it can detect\n      that the list has been mutated during a sort.\n\n\nTuples\n======\n\nTuples are immutable sequences, typically used to store collections of\nheterogeneous data (such as the 2-tuples produced by the "enumerate()"\nbuilt-in). Tuples are also used for cases where an immutable sequence\nof homogeneous data is needed (such as allowing storage in a "set" or\n"dict" instance).\n\nclass class tuple([iterable])\n\n   Tuples may be constructed in a number of ways:\n\n   * Using a pair of parentheses to denote the empty tuple: "()"\n\n   * Using a trailing comma for a singleton tuple: "a," or "(a,)"\n\n   * Separating items with commas: "a, b, c" or "(a, b, c)"\n\n   * Using the "tuple()" built-in: "tuple()" or "tuple(iterable)"\n\n   The constructor builds a tuple whose items are the same and in the\n   same order as *iterable*\'s items.  *iterable* may be either a\n   sequence, a container that supports iteration, or an iterator\n   object.  If *iterable* is already a tuple, it is returned\n   unchanged. For example, "tuple(\'abc\')" returns "(\'a\', \'b\', \'c\')"\n   and "tuple( [1, 2, 3] )" returns "(1, 2, 3)". If no argument is\n   given, the constructor creates a new empty tuple, "()".\n\n   Note that it is actually the comma which makes a tuple, not the\n   parentheses. The parentheses are optional, except in the empty\n   tuple case, or when they are needed to avoid syntactic ambiguity.\n   For example, "f(a, b, c)" is a function call with three arguments,\n   while "f((a, b, c))" is a function call with a 3-tuple as the sole\n   argument.\n\n   Tuples implement all of the *common* sequence operations.\n\nFor heterogeneous collections of data where access by name is clearer\nthan access by index, "collections.namedtuple()" may be a more\nappropriate choice than a simple tuple object.\n\n\nRanges\n======\n\nThe "range" type represents an immutable sequence of numbers and is\ncommonly used for looping a specific number of times in "for" loops.\n\nclass class range(stop)\nclass class range(start, stop[, step])\n\n   The arguments to the range constructor must be integers (either\n   built-in "int" or any object that implements the "__index__"\n   special method).  If the *step* argument is omitted, it defaults to\n   "1". If the *start* argument is omitted, it defaults to "0". If\n   *step* is zero, "ValueError" is raised.\n\n   For a positive *step*, the contents of a range "r" are determined\n   by the formula "r[i] = start + step*i" where "i >= 0" and "r[i] <\n   stop".\n\n   For a negative *step*, the contents of the range are still\n   determined by the formula "r[i] = start + step*i", but the\n   constraints are "i >= 0" and "r[i] > stop".\n\n   A range object will be empty if "r[0]" does not meet the value\n   constraint. Ranges do support negative indices, but these are\n   interpreted as indexing from the end of the sequence determined by\n   the positive indices.\n\n   Ranges containing absolute values larger than "sys.maxsize" are\n   permitted but some features (such as "len()") may raise\n   "OverflowError".\n\n   Range examples:\n\n      >>> list(range(10))\n      [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n      >>> list(range(1, 11))\n      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n      >>> list(range(0, 30, 5))\n      [0, 5, 10, 15, 20, 25]\n      >>> list(range(0, 10, 3))\n      [0, 3, 6, 9]\n      >>> list(range(0, -10, -1))\n      [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]\n      >>> list(range(0))\n      []\n      >>> list(range(1, 0))\n      []\n\n   Ranges implement all of the *common* sequence operations except\n   concatenation and repetition (due to the fact that range objects\n   can only represent sequences that follow a strict pattern and\n   repetition and concatenation will usually violate that pattern).\n\n   start\n\n      The value of the *start* parameter (or "0" if the parameter was\n      not supplied)\n\n   stop\n\n      The value of the *stop* parameter\n\n   step\n\n      The value of the *step* parameter (or "1" if the parameter was\n      not supplied)\n\nThe advantage of the "range" type over a regular "list" or "tuple" is\nthat a "range" object will always take the same (small) amount of\nmemory, no matter the size of the range it represents (as it only\nstores the "start", "stop" and "step" values, calculating individual\nitems and subranges as needed).\n\nRange objects implement the "collections.abc.Sequence" ABC, and\nprovide features such as containment tests, element index lookup,\nslicing and support for negative indices (see *Sequence Types ---\nlist, tuple, range*):\n\n>>> r = range(0, 20, 2)\n>>> r\nrange(0, 20, 2)\n>>> 11 in r\nFalse\n>>> 10 in r\nTrue\n>>> r.index(10)\n5\n>>> r[5]\n10\n>>> r[:5]\nrange(0, 10, 2)\n>>> r[-1]\n18\n\nTesting range objects for equality with "==" and "!=" compares them as\nsequences.  That is, two range objects are considered equal if they\nrepresent the same sequence of values.  (Note that two range objects\nthat compare equal might have different "start", "stop" and "step"\nattributes, for example "range(0) == range(2, 1, 3)" or "range(0, 3,\n2) == range(0, 4, 2)".)\n\nChanged in version 3.2: Implement the Sequence ABC. Support slicing\nand negative indices. Test "int" objects for membership in constant\ntime instead of iterating through all items.\n\nChanged in version 3.3: Define \'==\' and \'!=\' to compare range objects\nbased on the sequence of values they define (instead of comparing\nbased on object identity).\n\nNew in version 3.3: The "start", "stop" and "step" attributes.\n',
  'typesseq-mutable': u'\nMutable Sequence Types\n**********************\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation                      | Result                           | Notes                 |\n+================================+==================================+=======================+\n| "s[i] = x"                     | item *i* of *s* is replaced by   |                       |\n|                                | *x*                              |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t"                   | slice of *s* from *i* to *j* is  |                       |\n|                                | replaced by the contents of the  |                       |\n|                                | iterable *t*                     |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]"                   | same as "s[i:j] = []"            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t"                 | the elements of "s[i:j:k]" are   | (1)                   |\n|                                | replaced by those of *t*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]"                 | removes the elements of          |                       |\n|                                | "s[i:j:k]" from the list         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)"                  | appends *x* to the end of the    |                       |\n|                                | sequence (same as                |                       |\n|                                | "s[len(s):len(s)] = [x]")        |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()"                    | removes all items from "s" (same | (5)                   |\n|                                | as "del s[:]")                   |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()"                     | creates a shallow copy of "s"    | (5)                   |\n|                                | (same as "s[:]")                 |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" or "s += t"      | extends *s* with the contents of |                       |\n|                                | *t* (for the most part the same  |                       |\n|                                | as "s[len(s):len(s)] = t")       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s *= n"                       | updates *s* with its contents    | (6)                   |\n|                                | repeated *n* times               |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)"               | inserts *x* into *s* at the      |                       |\n|                                | index given by *i* (same as      |                       |\n|                                | "s[i:i] = [x]")                  |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])"                   | retrieves the item at *i* and    | (2)                   |\n|                                | also removes it from *s*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)"                  | remove the first item from *s*   | (3)                   |\n|                                | where "s[i] == x"                |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()"                  | reverses the items of *s* in     | (4)                   |\n|                                | place                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n   the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n   economy of space when reversing a large sequence.  To remind users\n   that it operates by side effect, it does not return the reversed\n   sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n   interfaces of mutable containers that don\'t support slicing\n   operations (such as "dict" and "set")\n\n   New in version 3.3: "clear()" and "copy()" methods.\n\n6. The value *n* is an integer, or an object implementing\n   "__index__()".  Zero and negative values of *n* clear the sequence.\n   Items in the sequence are not copied; they are referenced multiple\n   times, as explained for "s * n" under *Common Sequence Operations*.\n',
  'unary': u'\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n   u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary "-" (minus) operator yields the negation of its numeric\nargument.\n\nThe unary "+" (plus) operator yields its numeric argument unchanged.\n\nThe unary "~" (invert) operator yields the bitwise inversion of its\ninteger argument.  The bitwise inversion of "x" is defined as\n"-(x+1)".  It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n"TypeError" exception is raised.\n',
  'while': u'\nThe "while" statement\n*********************\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n   while_stmt ::= "while" expression ":" suite\n                  ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite.  A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n',
- 'with': u'\nThe "with" statement\n********************\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n   with_stmt ::= "with" with_item ("," with_item)* ":" suite\n   with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n   is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n   value from "__enter__()" is assigned to it.\n\n   Note: The "with" statement guarantees that if the "__enter__()"\n     method returns without an error, then "__exit__()" will always be\n     called. Thus, if an error occurs during the assignment to the\n     target list, it will be treated the same as an error occurring\n     within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked.  If an\n   exception caused the suite to be exited, its type, value, and\n   traceback are passed as arguments to "__exit__()". Otherwise, three\n   "None" arguments are supplied.\n\n   If the suite was exited due to an exception, and the return value\n   from the "__exit__()" method was false, the exception is reraised.\n   If the return value was true, the exception is suppressed, and\n   execution continues with the statement following the "with"\n   statement.\n\n   If the suite was exited for any reason other than an exception, the\n   return value from "__exit__()" is ignored, and execution proceeds\n   at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n   with A() as a, B() as b:\n       suite\n\nis equivalent to\n\n   with A() as a:\n       with B() as b:\n           suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n     The specification, background, and examples for the Python "with"\n     statement.\n',
+ 'with': u'\nThe "with" statement\n********************\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n   with_stmt ::= "with" with_item ("," with_item)* ":" suite\n   with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n   is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n   value from "__enter__()" is assigned to it.\n\n   Note: The "with" statement guarantees that if the "__enter__()"\n     method returns without an error, then "__exit__()" will always be\n     called. Thus, if an error occurs during the assignment to the\n     target list, it will be treated the same as an error occurring\n     within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked.  If an\n   exception caused the suite to be exited, its type, value, and\n   traceback are passed as arguments to "__exit__()". Otherwise, three\n   "None" arguments are supplied.\n\n   If the suite was exited due to an exception, and the return value\n   from the "__exit__()" method was false, the exception is reraised.\n   If the return value was true, the exception is suppressed, and\n   execution continues with the statement following the "with"\n   statement.\n\n   If the suite was exited for any reason other than an exception, the\n   return value from "__exit__()" is ignored, and execution proceeds\n   at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n   with A() as a, B() as b:\n       suite\n\nis equivalent to\n\n   with A() as a:\n       with B() as b:\n           suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 343** - The "with" statement\n\n     The specification, background, and examples for the Python "with"\n     statement.\n',
  'yield': u'\nThe "yield" statement\n*********************\n\n   yield_stmt ::= yield_expression\n\nA "yield" statement is semantically equivalent to a *yield\nexpression*. The yield statement can be used to omit the parentheses\nthat would otherwise be required in the equivalent yield expression\nstatement. For example, the yield statements\n\n   yield <expr>\n   yield from <expr>\n\nare equivalent to the yield expression statements\n\n   (yield <expr>)\n   (yield from <expr>)\n\nYield expressions and statements are only used when defining a\n*generator* function, and are only used in the body of the generator\nfunction.  Using yield in a function definition is sufficient to cause\nthat definition to create a generator function instead of a normal\nfunction.\n\nFor full details of "yield" semantics, refer to the *Yield\nexpressions* section.\n'}
index 1f5be45..5950735 100644 (file)
@@ -231,7 +231,7 @@ class Random(_random.Random):
             while r >= n:
                 r = getrandbits(k)
             return r
-        # There's an overriden random() method but no new getrandbits() method,
+        # There's an overridden random() method but no new getrandbits() method,
         # so we can only use random() from here.
         if n >= maxsize:
             _warn("Underlying random() generator does not supply \n"
index ecbd2cc..40d991f 100644 (file)
@@ -30,6 +30,7 @@ def recursive_repr(fillvalue='...'):
         wrapper.__module__ = getattr(user_function, '__module__')
         wrapper.__doc__ = getattr(user_function, '__doc__')
         wrapper.__name__ = getattr(user_function, '__name__')
+        wrapper.__qualname__ = getattr(user_function, '__qualname__')
         wrapper.__annotations__ = getattr(user_function, '__annotations__', {})
         return wrapper
 
index be8aee0..401a626 100644 (file)
@@ -75,7 +75,12 @@ class Completer:
 
         if not text.strip():
             if state == 0:
-                return '\t'
+                if _readline_available:
+                    readline.insert_text('\t')
+                    readline.redisplay()
+                    return ''
+                else:
+                    return '\t'
             else:
                 return None
 
@@ -103,13 +108,16 @@ class Completer:
         """
         import keyword
         matches = []
+        seen = {"__builtins__"}
         n = len(text)
         for word in keyword.kwlist:
             if word[:n] == text:
+                seen.add(word)
                 matches.append(word)
-        for nspace in [builtins.__dict__, self.namespace]:
+        for nspace in [self.namespace, builtins.__dict__]:
             for word, val in nspace.items():
-                if word[:n] == text and word != "__builtins__":
+                if word[:n] == text and word not in seen:
+                    seen.add(word)
                     matches.append(self._callable_postfix(val, word))
         return matches
 
@@ -165,10 +173,11 @@ def get_class_members(klass):
 try:
     import readline
 except ImportError:
-    pass
+    _readline_available = False
 else:
     readline.set_completer(Completer().complete)
     # Release references early at shutdown (the readline module's
     # contents are quasi-immortal, and the completer function holds a
     # reference to globals).
     atexit.register(lambda: readline.set_completer(None))
+    _readline_available = True
index 1c5729d..af6205d 100644 (file)
@@ -99,7 +99,22 @@ def _run_module_code(code, init_globals=None,
     return mod_globals.copy()
 
 # Helper to get the loader, code and filename for a module
-def _get_module_details(mod_name):
+def _get_module_details(mod_name, error=ImportError):
+    if mod_name.startswith("."):
+        raise error("Relative module names not supported")
+    pkg_name, _, _ = mod_name.rpartition(".")
+    if pkg_name:
+        # Try importing the parent to avoid catching initialization errors
+        try:
+            __import__(pkg_name)
+        except ImportError as e:
+            # If the parent or higher ancestor package is missing, let the
+            # error be raised by find_spec() below and then be caught. But do
+            # not allow other errors to be caught.
+            if e.name is None or (e.name != pkg_name and
+                    not pkg_name.startswith(e.name + ".")):
+                raise
+
     try:
         spec = importlib.util.find_spec(mod_name)
     except (ImportError, AttributeError, TypeError, ValueError) as ex:
@@ -107,27 +122,35 @@ def _get_module_details(mod_name):
         # importlib, where the latter raises other errors for cases where
         # pkgutil previously raised ImportError
         msg = "Error while finding spec for {!r} ({}: {})"
-        raise ImportError(msg.format(mod_name, type(ex), ex)) from ex
+        raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex
     if spec is None:
-        raise ImportError("No module named %s" % mod_name)
+        raise error("No module named %s" % mod_name)
     if spec.submodule_search_locations is not None:
         if mod_name == "__main__" or mod_name.endswith(".__main__"):
-            raise ImportError("Cannot use package as __main__ module")
+            raise error("Cannot use package as __main__ module")
         try:
             pkg_main_name = mod_name + ".__main__"
-            return _get_module_details(pkg_main_name)
-        except ImportError as e:
-            raise ImportError(("%s; %r is a package and cannot " +
+            return _get_module_details(pkg_main_name, error)
+        except error as e:
+            if mod_name not in sys.modules:
+                raise  # No module loaded; being a package is irrelevant
+            raise error(("%s; %r is a package and cannot " +
                                "be directly executed") %(e, mod_name))
     loader = spec.loader
     if loader is None:
-        raise ImportError("%r is a namespace package and cannot be executed"
+        raise error("%r is a namespace package and cannot be executed"
                                                                  % mod_name)
-    code = loader.get_code(mod_name)
+    try:
+        code = loader.get_code(mod_name)
+    except ImportError as e:
+        raise error(format(e)) from e
     if code is None:
-        raise ImportError("No code object available for %s" % mod_name)
+        raise error("No code object available for %s" % mod_name)
     return mod_name, spec, code
 
+class _Error(Exception):
+    """Error that _run_module_as_main() should report without a traceback"""
+
 # XXX ncoghlan: Should this be documented and made public?
 # (Current thoughts: don't repeat the mistake that lead to its
 # creation when run_module() no longer met the needs of
@@ -148,20 +171,11 @@ def _run_module_as_main(mod_name, alter_argv=True):
     """
     try:
         if alter_argv or mod_name != "__main__": # i.e. -m switch
-            mod_name, mod_spec, code = _get_module_details(mod_name)
+            mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
         else:          # i.e. directory or zipfile execution
-            mod_name, mod_spec, code = _get_main_module_details()
-    except ImportError as exc:
-        # Try to provide a good error message
-        # for directories, zip files and the -m switch
-        if alter_argv:
-            # For -m switch, just display the exception
-            info = str(exc)
-        else:
-            # For directories/zipfiles, let the user
-            # know what the code was looking for
-            info = "can't find '__main__' module in %r" % sys.argv[0]
-        msg = "%s: %s" % (sys.executable, info)
+            mod_name, mod_spec, code = _get_main_module_details(_Error)
+    except _Error as exc:
+        msg = "%s: %s" % (sys.executable, exc)
         sys.exit(msg)
     main_globals = sys.modules["__main__"].__dict__
     if alter_argv:
@@ -184,7 +198,7 @@ def run_module(mod_name, init_globals=None,
         # Leave the sys module alone
         return _run_code(code, {}, init_globals, run_name, mod_spec)
 
-def _get_main_module_details():
+def _get_main_module_details(error=ImportError):
     # Helper that gives a nicer error message when attempting to
     # execute a zipfile or directory by invoking __main__.py
     # Also moves the standard __main__ out of the way so that the
@@ -196,7 +210,7 @@ def _get_main_module_details():
         return _get_module_details(main_name)
     except ImportError as exc:
         if main_name in str(exc):
-            raise ImportError("can't find %r module in %r" %
+            raise error("can't find %r module in %r" %
                               (main_name, sys.path[0])) from exc
         raise
     finally:
index 6d569c3..d8769e3 100644 (file)
@@ -43,9 +43,18 @@ def _fileobj_to_fd(fileobj):
 
 
 SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])
-"""Object used to associate a file object to its backing file descriptor,
-selected event mask and attached data."""
 
+SelectorKey.__doc__ = """SelectorKey(fileobj, fd, events, data)
+
+    Object used to associate a file object to its backing
+    file descriptor, selected event mask, and attached data.
+"""
+if sys.version_info >= (3, 5):
+    SelectorKey.fileobj.__doc__ = 'File object registered.'
+    SelectorKey.fd.__doc__ = 'Underlying file descriptor.'
+    SelectorKey.events.__doc__ = 'Events that must be waited for on this file object.'
+    SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object.
+    For example, this could be used to store a per-client session ID.''')
 
 class _SelectorMapping(Mapping):
     """Mapping of file objects to selector keys."""
index 3f4b6bf..37124a0 100644 (file)
@@ -1069,7 +1069,9 @@ def get_terminal_size(fallback=(80, 24)):
     if columns <= 0 or lines <= 0:
         try:
             size = os.get_terminal_size(sys.__stdout__.fileno())
-        except (NameError, OSError):
+        except (AttributeError, ValueError, OSError):
+            # stdout is None, closed, detached, or not a terminal, or
+            # os.get_terminal_size() is unsupported
             size = os.terminal_size(fallback)
         if columns <= 0:
             columns = size.columns
index 3a8d1c3..3f78ef5 100644 (file)
@@ -59,7 +59,7 @@ because bar.pth comes alphabetically before foo.pth; and spam is
 omitted because it is not mentioned in either path configuration file.
 
 The readline module is also automatically configured to enable
-completion for systems that support it.  This can be overriden in
+completion for systems that support it.  This can be overridden in
 sitecustomize, usercustomize or PYTHONSTARTUP.
 
 After these operations, an attempt is made to import a module
@@ -379,7 +379,7 @@ def enablerlcompleter():
 
     If the readline module can be imported, the hook will set the Tab key
     as completion key and register ~/.python_history as history file.
-    This can be overriden in the sitecustomize or usercustomize module,
+    This can be overridden in the sitecustomize or usercustomize module,
     or in a PYTHONSTARTUP file.
     """
     def register_readline():
index 4756973..dfbf5f9 100755 (executable)
@@ -773,6 +773,11 @@ class SMTP:
             self.ehlo_resp = None
             self.esmtp_features = {}
             self.does_esmtp = 0
+        else:
+            # RFC 3207:
+            # 501 Syntax error (no parameters allowed)
+            # 454 TLS not available due to temporary reason
+            raise SMTPResponseException(resp, reply)
         return (resp, reply)
 
     def sendmail(self, from_addr, to_addrs, msg, mail_options=[],
index ed1b10a..ac2e3dd 100644 (file)
@@ -209,10 +209,10 @@ class socket(_socket.socket):
                  encoding=None, errors=None, newline=None):
         """makefile(...) -> an I/O stream connected to the socket
 
-        The arguments are as for io.open() after the filename,
-        except the only mode characters supported are 'r', 'w' and 'b'.
-        The semantics are similar too.  (XXX refactor to share code?)
+        The arguments are as for io.open() after the filename, except the only
+        supported mode values are 'r' (default), 'w' and 'b'.
         """
+        # XXX refactor to share code?
         if not set(mode) <= {"r", "w", "b"}:
             raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
         writing = "w" in mode
@@ -685,7 +685,7 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
     global default timeout setting returned by :func:`getdefaulttimeout`
     is used.  If *source_address* is set it must be a tuple of (host, port)
     for the socket to bind as a source address before making the connection.
-    An host of '' or port 0 tells the OS to use the default.
+    A host of '' or port 0 tells the OS to use the default.
     """
 
     host, port = address
index 0ce8e81..8808813 100644 (file)
@@ -120,11 +120,6 @@ BaseServer:
 
 # Author of the BaseServer patch: Luke Kenneth Casson Leighton
 
-# XXX Warning!
-# There is a test suite for this module, but it cannot be run by the
-# standard regression test.
-# To run it manually, run Lib/test/test_socketserver.py.
-
 __version__ = "0.4"
 
 
@@ -319,6 +314,8 @@ class BaseServer:
             except:
                 self.handle_error(request, client_address)
                 self.shutdown_request(request)
+        else:
+            self.shutdown_request(request)
 
     def handle_timeout(self):
         """Called if no new request arrives within self.timeout.
@@ -671,7 +668,7 @@ class BaseRequestHandler:
     client address as self.client_address, and the server (in case it
     needs access to per-server information) as self.server.  Since a
     separate instance is created for each request, the handle() method
-    can define arbitrary other instance variariables.
+    can define other arbitrary instance variables.
 
     """
 
@@ -739,7 +736,7 @@ class StreamRequestHandler(BaseRequestHandler):
             try:
                 self.wfile.flush()
             except socket.error:
-                # An final socket error may have occurred here, such as
+                # A final socket error may have occurred here, such as
                 # the local error ECONNABORTED.
                 pass
         self.wfile.close()
@@ -748,9 +745,6 @@ class StreamRequestHandler(BaseRequestHandler):
 
 class DatagramRequestHandler(BaseRequestHandler):
 
-    # XXX Regrettably, I cannot get this working on Linux;
-    # s.recvfrom() doesn't return a meaningful client address.
-
     """Define self.rfile and self.wfile for datagram sockets."""
 
     def setup(self):
index eaaaa2c..11adb30 100644 (file)
@@ -73,7 +73,7 @@ class RegressionTests(unittest.TestCase):
     def CheckStatementFinalizationOnCloseDb(self):
         # pysqlite versions <= 2.3.3 only finalized statements in the statement
         # cache when closing the database. statements that were still
-        # referenced in cursors weren't closed an could provoke "
+        # referenced in cursors weren't closed and could provoke "
         # "OperationalError: Unable to close due to unfinalised statements".
         con = sqlite.connect(":memory:")
         cursors = []
index 69e2ec2..8a4bbab 100644 (file)
@@ -55,6 +55,9 @@ def func_isblob(v):
 def func_islonglong(v):
     return isinstance(v, int) and v >= 1<<31
 
+def func(*args):
+    return len(args)
+
 class AggrNoStep:
     def __init__(self):
         pass
@@ -111,6 +114,19 @@ class AggrCheckType:
     def finalize(self):
         return self.val
 
+class AggrCheckTypes:
+    def __init__(self):
+        self.val = 0
+
+    def step(self, whichType, *vals):
+        theType = {"str": str, "int": int, "float": float, "None": type(None),
+                   "blob": bytes}
+        for val in vals:
+            self.val += int(theType[whichType] is type(val))
+
+    def finalize(self):
+        return self.val
+
 class AggrSum:
     def __init__(self):
         self.val = 0.0
@@ -140,6 +156,7 @@ class FunctionTests(unittest.TestCase):
         self.con.create_function("isnone", 1, func_isnone)
         self.con.create_function("isblob", 1, func_isblob)
         self.con.create_function("islonglong", 1, func_islonglong)
+        self.con.create_function("spam", -1, func)
 
     def tearDown(self):
         self.con.close()
@@ -257,6 +274,13 @@ class FunctionTests(unittest.TestCase):
         val = cur.fetchone()[0]
         self.assertEqual(val, 1)
 
+    def CheckAnyArguments(self):
+        cur = self.con.cursor()
+        cur.execute("select spam(?, ?)", (1, 2))
+        val = cur.fetchone()[0]
+        self.assertEqual(val, 2)
+
+
 class AggregateTests(unittest.TestCase):
     def setUp(self):
         self.con = sqlite.connect(":memory:")
@@ -279,6 +303,7 @@ class AggregateTests(unittest.TestCase):
         self.con.create_aggregate("excStep", 1, AggrExceptionInStep)
         self.con.create_aggregate("excFinalize", 1, AggrExceptionInFinalize)
         self.con.create_aggregate("checkType", 2, AggrCheckType)
+        self.con.create_aggregate("checkTypes", -1, AggrCheckTypes)
         self.con.create_aggregate("mysum", 1, AggrSum)
 
     def tearDown(self):
@@ -349,6 +374,12 @@ class AggregateTests(unittest.TestCase):
         val = cur.fetchone()[0]
         self.assertEqual(val, 1)
 
+    def CheckAggrCheckParamsInt(self):
+        cur = self.con.cursor()
+        cur.execute("select checkTypes('int', ?, ?)", (42, 24))
+        val = cur.fetchone()[0]
+        self.assertEqual(val, 2)
+
     def CheckAggrCheckParamFloat(self):
         cur = self.con.cursor()
         cur.execute("select checkType('float', ?)", (3.14,))
index f6a8851..4ff50d1 100644 (file)
@@ -833,14 +833,14 @@ def parse(str, flags=0, pattern=None):
         assert source.next == ")"
         raise source.error("unbalanced parenthesis")
 
-    if flags & SRE_FLAG_DEBUG:
-        p.dump()
-
     if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
         # the VERBOSE flag was switched on inside the pattern.  to be
         # on the safe side, we'll parse the whole thing again...
         return parse(str, p.pattern.flags)
 
+    if flags & SRE_FLAG_DEBUG:
+        p.dump()
+
     return p
 
 def parse_template(source, pattern):
index ab7a49b..3f5c3c4 100644 (file)
@@ -145,6 +145,7 @@ from socket import socket, AF_INET, SOCK_STREAM, create_connection
 from socket import SOL_SOCKET, SO_TYPE
 import base64        # for DER-to-PEM translation
 import errno
+import warnings
 
 
 socket_error = OSError  # keep that public name in module namespace
@@ -405,12 +406,16 @@ class SSLContext(_SSLContext):
 
     def _load_windows_store_certs(self, storename, purpose):
         certs = bytearray()
-        for cert, encoding, trust in enum_certificates(storename):
-            # CA certs are never PKCS#7 encoded
-            if encoding == "x509_asn":
-                if trust is True or purpose.oid in trust:
-                    certs.extend(cert)
-        self.load_verify_locations(cadata=certs)
+        try:
+            for cert, encoding, trust in enum_certificates(storename):
+                # CA certs are never PKCS#7 encoded
+                if encoding == "x509_asn":
+                    if trust is True or purpose.oid in trust:
+                        certs.extend(cert)
+        except PermissionError:
+            warnings.warn("unable to enumerate Windows certificate store")
+        if certs:
+            self.load_verify_locations(cadata=certs)
         return certs
 
     def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
@@ -560,7 +565,7 @@ class SSLObject:
         server hostame is set."""
         return self._sslobj.server_hostname
 
-    def read(self, len=0, buffer=None):
+    def read(self, len=1024, buffer=None):
         """Read up to 'len' bytes from the SSL object and return them.
 
         If 'buffer' is provided, read into this buffer and return the number of
@@ -569,7 +574,7 @@ class SSLObject:
         if buffer is not None:
             v = self._sslobj.read(len, buffer)
         else:
-            v = self._sslobj.read(len or 1024)
+            v = self._sslobj.read(len)
         return v
 
     def write(self, data):
@@ -775,7 +780,7 @@ class SSLSocket(socket):
             # EAGAIN.
             self.getpeername()
 
-    def read(self, len=0, buffer=None):
+    def read(self, len=1024, buffer=None):
         """Read up to LEN bytes and return them.
         Return zero-length string on EOF."""
 
index 9203cf1..4f5c1c1 100644 (file)
@@ -104,6 +104,8 @@ import math
 
 from fractions import Fraction
 from decimal import Decimal
+from itertools import groupby
+
 
 
 # === Exceptions ===
@@ -115,86 +117,102 @@ class StatisticsError(ValueError):
 # === Private utilities ===
 
 def _sum(data, start=0):
-    """_sum(data [, start]) -> value
+    """_sum(data [, start]) -> (type, sum, count)
+
+    Return a high-precision sum of the given numeric data as a fraction,
+    together with the type to be converted to and the count of items.
 
-    Return a high-precision sum of the given numeric data. If optional
-    argument ``start`` is given, it is added to the total. If ``data`` is
-    empty, ``start`` (defaulting to 0) is returned.
+    If optional argument ``start`` is given, it is added to the total.
+    If ``data`` is empty, ``start`` (defaulting to 0) is returned.
 
 
     Examples
     --------
 
     >>> _sum([3, 2.25, 4.5, -0.5, 1.0], 0.75)
-    11.0
+    (<class 'float'>, Fraction(11, 1), 5)
 
     Some sources of round-off error will be avoided:
 
     >>> _sum([1e50, 1, -1e50] * 1000)  # Built-in sum returns zero.
-    1000.0
+    (<class 'float'>, Fraction(1000, 1), 3000)
 
     Fractions and Decimals are also supported:
 
     >>> from fractions import Fraction as F
     >>> _sum([F(2, 3), F(7, 5), F(1, 4), F(5, 6)])
-    Fraction(63, 20)
+    (<class 'fractions.Fraction'>, Fraction(63, 20), 4)
 
     >>> from decimal import Decimal as D
     >>> data = [D("0.1375"), D("0.2108"), D("0.3061"), D("0.0419")]
     >>> _sum(data)
-    Decimal('0.6963')
+    (<class 'decimal.Decimal'>, Fraction(6963, 10000), 4)
 
     Mixed types are currently treated as an error, except that int is
     allowed.
     """
-    # We fail as soon as we reach a value that is not an int or the type of
-    # the first value which is not an int. E.g. _sum([int, int, float, int])
-    # is okay, but sum([int, int, float, Fraction]) is not.
-    allowed_types = {int, type(start)}
+    count = 0
     n, d = _exact_ratio(start)
-    partials = {d: n}  # map {denominator: sum of numerators}
-    # Micro-optimizations.
-    exact_ratio = _exact_ratio
+    partials = {d: n}
     partials_get = partials.get
-    # Add numerators for each denominator.
-    for x in data:
-        _check_type(type(x), allowed_types)
-        n, d = exact_ratio(x)
-        partials[d] = partials_get(d, 0) + n
-    # Find the expected result type. If allowed_types has only one item, it
-    # will be int; if it has two, use the one which isn't int.
-    assert len(allowed_types) in (1, 2)
-    if len(allowed_types) == 1:
-        assert allowed_types.pop() is int
-        T = int
-    else:
-        T = (allowed_types - {int}).pop()
+    T = _coerce(int, type(start))
+    for typ, values in groupby(data, type):
+        T = _coerce(T, typ)  # or raise TypeError
+        for n,d in map(_exact_ratio, values):
+            count += 1
+            partials[d] = partials_get(d, 0) + n
     if None in partials:
-        assert issubclass(T, (float, Decimal))
-        assert not math.isfinite(partials[None])
-        return T(partials[None])
-    total = Fraction()
-    for d, n in sorted(partials.items()):
-        total += Fraction(n, d)
-    if issubclass(T, int):
-        assert total.denominator == 1
-        return T(total.numerator)
-    if issubclass(T, Decimal):
-        return T(total.numerator)/total.denominator
-    return T(total)
-
-
-def _check_type(T, allowed):
-    if T not in allowed:
-        if len(allowed) == 1:
-            allowed.add(T)
-        else:
-            types = ', '.join([t.__name__ for t in allowed] + [T.__name__])
-            raise TypeError("unsupported mixed types: %s" % types)
+        # The sum will be a NAN or INF. We can ignore all the finite
+        # partials, and just look at this special one.
+        total = partials[None]
+        assert not _isfinite(total)
+    else:
+        # Sum all the partial sums using builtin sum.
+        # FIXME is this faster if we sum them in order of the denominator?
+        total = sum(Fraction(n, d) for d, n in sorted(partials.items()))
+    return (T, total, count)
+
+
+def _isfinite(x):
+    try:
+        return x.is_finite()  # Likely a Decimal.
+    except AttributeError:
+        return math.isfinite(x)  # Coerces to float first.
+
+
+def _coerce(T, S):
+    """Coerce types T and S to a common type, or raise TypeError.
+
+    Coercion rules are currently an implementation detail. See the CoerceTest
+    test class in test_statistics for details.
+    """
+    # See http://bugs.python.org/issue24068.
+    assert T is not bool, "initial type T is bool"
+    # If the types are the same, no need to coerce anything. Put this
+    # first, so that the usual case (no coercion needed) happens as soon
+    # as possible.
+    if T is S:  return T
+    # Mixed int & other coerce to the other type.
+    if S is int or S is bool:  return T
+    if T is int:  return S
+    # If one is a (strict) subclass of the other, coerce to the subclass.
+    if issubclass(S, T):  return S
+    if issubclass(T, S):  return T
+    # Ints coerce to the other type.
+    if issubclass(T, int):  return S
+    if issubclass(S, int):  return T
+    # Mixed fraction & float coerces to float (or float subclass).
+    if issubclass(T, Fraction) and issubclass(S, float):
+        return S
+    if issubclass(T, float) and issubclass(S, Fraction):
+        return T
+    # Any other combination is disallowed.
+    msg = "don't know how to coerce %s and %s"
+    raise TypeError(msg % (T.__name__, S.__name__))
 
 
 def _exact_ratio(x):
-    """Convert Real number x exactly to (numerator, denominator) pair.
+    """Return Real number x to exact (numerator, denominator) pair.
 
     >>> _exact_ratio(0.25)
     (1, 4)
@@ -202,29 +220,31 @@ def _exact_ratio(x):
     x is expected to be an int, Fraction, Decimal or float.
     """
     try:
+        # Optimise the common case of floats. We expect that the most often
+        # used numeric type will be builtin floats, so try to make this as
+        # fast as possible.
+        if type(x) is float:
+            return x.as_integer_ratio()
         try:
-            # int, Fraction
+            # x may be an int, Fraction, or Integral ABC.
             return (x.numerator, x.denominator)
         except AttributeError:
-            # float
             try:
+                # x may be a float subclass.
                 return x.as_integer_ratio()
             except AttributeError:
-                # Decimal
                 try:
+                    # x may be a Decimal.
                     return _decimal_to_ratio(x)
                 except AttributeError:
-                    msg = "can't convert type '{}' to numerator/denominator"
-                    raise TypeError(msg.format(type(x).__name__)) from None
+                    # Just give up?
+                    pass
     except (OverflowError, ValueError):
-        # INF or NAN
-        if __debug__:
-            # Decimal signalling NANs cannot be converted to float :-(
-            if isinstance(x, Decimal):
-                assert not x.is_finite()
-            else:
-                assert not math.isfinite(x)
+        # float NAN or INF.
+        assert not math.isfinite(x)
         return (x, None)
+    msg = "can't convert type '{}' to numerator/denominator"
+    raise TypeError(msg.format(type(x).__name__))
 
 
 # FIXME This is faster than Fraction.from_decimal, but still too slow.
@@ -239,7 +259,7 @@ def _decimal_to_ratio(d):
     sign, digits, exp = d.as_tuple()
     if exp in ('F', 'n', 'N'):  # INF, NAN, sNAN
         assert not d.is_finite()
-        raise ValueError
+        return (d, None)
     num = 0
     for digit in digits:
         num = num*10 + digit
@@ -253,6 +273,24 @@ def _decimal_to_ratio(d):
     return (num, den)
 
 
+def _convert(value, T):
+    """Convert value to given numeric type T."""
+    if type(value) is T:
+        # This covers the cases where T is Fraction, or where value is
+        # a NAN or INF (Decimal or float).
+        return value
+    if issubclass(T, int) and value.denominator != 1:
+        T = float
+    try:
+        # FIXME: what do we do if this overflows?
+        return T(value)
+    except TypeError:
+        if issubclass(T, Decimal):
+            return T(value.numerator)/T(value.denominator)
+        else:
+            raise
+
+
 def _counts(data):
     # Generate a table of sorted (value, frequency) pairs.
     table = collections.Counter(iter(data)).most_common()
@@ -290,7 +328,9 @@ def mean(data):
     n = len(data)
     if n < 1:
         raise StatisticsError('mean requires at least one data point')
-    return _sum(data)/n
+    T, total, count = _sum(data)
+    assert count == n
+    return _convert(total/n, T)
 
 
 # FIXME: investigate ways to calculate medians without sorting? Quickselect?
@@ -460,12 +500,14 @@ def _ss(data, c=None):
     """
     if c is None:
         c = mean(data)
-    ss = _sum((x-c)**2 for x in data)
+    T, total, count = _sum((x-c)**2 for x in data)
     # The following sum should mathematically equal zero, but due to rounding
     # error may not.
-    ss -= _sum((x-c) for x in data)**2/len(data)
-    assert not ss < 0, 'negative sum of square deviations: %f' % ss
-    return ss
+    U, total2, count2 = _sum((x-c) for x in data)
+    assert T == U and count == count2
+    total -=  total2**2/len(data)
+    assert not total < 0, 'negative sum of square deviations: %f' % total
+    return (T, total)
 
 
 def variance(data, xbar=None):
@@ -511,8 +553,8 @@ def variance(data, xbar=None):
     n = len(data)
     if n < 2:
         raise StatisticsError('variance requires at least two data points')
-    ss = _ss(data, xbar)
-    return ss/(n-1)
+    T, ss = _ss(data, xbar)
+    return _convert(ss/(n-1), T)
 
 
 def pvariance(data, mu=None):
@@ -559,8 +601,8 @@ def pvariance(data, mu=None):
     n = len(data)
     if n < 1:
         raise StatisticsError('pvariance requires at least one data point')
-    ss = _ss(data, mu)
-    return ss/n
+    T, ss = _ss(data, mu)
+    return _convert(ss/n, T)
 
 
 def stdev(data, xbar=None):
index 62e8f2f..89287c4 100644 (file)
@@ -14,6 +14,10 @@ printable -- a string containing all ASCII characters considered printable
 
 """
 
+__all__ = ["ascii_letters", "ascii_lowercase", "ascii_uppercase", "capwords",
+           "digits", "hexdigits", "octdigits", "printable", "punctuation",
+           "whitespace", "Formatter", "Template"]
+
 import _string
 
 # Some strings for ctype-style character classification
@@ -46,7 +50,7 @@ def capwords(s, sep=None):
 
 ####################################################################
 import re as _re
-from collections import ChainMap
+from collections import ChainMap as _ChainMap
 
 class _TemplateMetaclass(type):
     pattern = r"""
@@ -104,7 +108,7 @@ class Template(metaclass=_TemplateMetaclass):
         if not args:
             mapping = kws
         elif kws:
-            mapping = ChainMap(kws, args[0])
+            mapping = _ChainMap(kws, args[0])
         else:
             mapping = args[0]
         # Helper function for .sub()
@@ -134,7 +138,7 @@ class Template(metaclass=_TemplateMetaclass):
         if not args:
             mapping = kws
         elif kws:
-            mapping = ChainMap(kws, args[0])
+            mapping = _ChainMap(kws, args[0])
         else:
             mapping = args[0]
         # Helper function for .sub()
index bbf50ce..d8d6ab2 100644 (file)
@@ -535,14 +535,11 @@ def _args_from_interpreter_flags():
         'verbose': 'v',
         'bytes_warning': 'b',
         'quiet': 'q',
-        'hash_randomization': 'R',
     }
     args = []
     for flag, opt in flag_opt_map.items():
         v = getattr(sys.flags, flag)
         if v > 0:
-            if flag == 'hash_randomization':
-                v = 1 # Handle specification of an exact seed
             args.append('-' + opt * v)
     for opt in sys.warnoptions:
         args.append('-W' + opt)
@@ -1014,8 +1011,7 @@ class Popen(object):
             try:
                 self.stdin.write(input)
             except BrokenPipeError:
-                # communicate() must ignore broken pipe error
-                pass
+                pass  # communicate() must ignore broken pipe errors.
             except OSError as e:
                 if e.errno == errno.EINVAL and self.poll() is not None:
                     # Issue #19612: On Windows, stdin.write() fails with EINVAL
@@ -1023,7 +1019,15 @@ class Popen(object):
                     pass
                 else:
                     raise
-        self.stdin.close()
+        try:
+            self.stdin.close()
+        except BrokenPipeError:
+            pass  # communicate() must ignore broken pipe errors.
+        except OSError as e:
+            if e.errno == errno.EINVAL and self.poll() is not None:
+                pass
+            else:
+                raise
 
     def communicate(self, input=None, timeout=None):
         """Interact with process: Send data to stdin.  Read data from
@@ -1404,7 +1408,10 @@ class Popen(object):
             elif stderr == PIPE:
                 errread, errwrite = os.pipe()
             elif stderr == STDOUT:
-                errwrite = c2pwrite
+                if c2pwrite != -1:
+                    errwrite = c2pwrite
+                else: # child's stdout is not set, use parent's stdout
+                    errwrite = sys.__stdout__.fileno()
             elif stderr == DEVNULL:
                 errwrite = self._get_devnull()
             elif isinstance(stderr, int):
@@ -1661,9 +1668,15 @@ class Popen(object):
             if self.stdin and not self._communication_started:
                 # Flush stdio buffer.  This might block, if the user has
                 # been writing to .stdin in an uncontrolled fashion.
-                self.stdin.flush()
+                try:
+                    self.stdin.flush()
+                except BrokenPipeError:
+                    pass  # communicate() must ignore BrokenPipeError.
                 if not input:
-                    self.stdin.close()
+                    try:
+                        self.stdin.close()
+                    except BrokenPipeError:
+                        pass  # communicate() must ignore BrokenPipeError.
 
             stdout = None
             stderr = None
index 137932e..9c34be0 100644 (file)
@@ -260,7 +260,12 @@ def _parse_makefile(filename, vars=None):
     while len(variables) > 0:
         for name in tuple(variables):
             value = notdone[name]
-            m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
+            m1 = _findvar1_rx.search(value)
+            m2 = _findvar2_rx.search(value)
+            if m1 and m2:
+                m = m1 if m1.start() < m2.start() else m2
+            else:
+                m = m1 if m1 else m2
             if m is not None:
                 n = m.group(1)
                 found = True
index ca45126..721f9d7 100755 (executable)
@@ -459,13 +459,7 @@ class _Stream:
                 self.fileobj.write(self.buf)
                 self.buf = b""
                 if self.comptype == "gz":
-                    # The native zlib crc is an unsigned 32-bit integer, but
-                    # the Python wrapper implicitly casts that to a signed C
-                    # long.  So, on a 32-bit box self.crc may "look negative",
-                    # while the same crc on a 64-bit box may "look positive".
-                    # To avoid irksome warnings from the `struct` module, force
-                    # it to look positive on all boxes.
-                    self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff))
+                    self.fileobj.write(struct.pack("<L", self.crc))
                     self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF))
         finally:
             if not self._extfileobj:
@@ -818,11 +812,11 @@ class TarInfo(object):
         """
         info["magic"] = POSIX_MAGIC
 
-        if len(info["linkname"]) > LENGTH_LINK:
+        if len(info["linkname"].encode(encoding, errors)) > LENGTH_LINK:
             raise ValueError("linkname is too long")
 
-        if len(info["name"]) > LENGTH_NAME:
-            info["prefix"], info["name"] = self._posix_split_name(info["name"])
+        if len(info["name"].encode(encoding, errors)) > LENGTH_NAME:
+            info["prefix"], info["name"] = self._posix_split_name(info["name"], encoding, errors)
 
         return self._create_header(info, USTAR_FORMAT, encoding, errors)
 
@@ -832,10 +826,10 @@ class TarInfo(object):
         info["magic"] = GNU_MAGIC
 
         buf = b""
-        if len(info["linkname"]) > LENGTH_LINK:
+        if len(info["linkname"].encode(encoding, errors)) > LENGTH_LINK:
             buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors)
 
-        if len(info["name"]) > LENGTH_NAME:
+        if len(info["name"].encode(encoding, errors)) > LENGTH_NAME:
             buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors)
 
         return buf + self._create_header(info, GNU_FORMAT, encoding, errors)
@@ -895,19 +889,20 @@ class TarInfo(object):
         """
         return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf-8")
 
-    def _posix_split_name(self, name):
+    def _posix_split_name(self, name, encoding, errors):
         """Split a name longer than 100 chars into a prefix
            and a name part.
         """
-        prefix = name[:LENGTH_PREFIX + 1]
-        while prefix and prefix[-1] != "/":
-            prefix = prefix[:-1]
-
-        name = name[len(prefix):]
-        prefix = prefix[:-1]
-
-        if not prefix or len(name) > LENGTH_NAME:
+        components = name.split("/")
+        for i in range(1, len(components)):
+            prefix = "/".join(components[:i])
+            name = "/".join(components[i:])
+            if len(prefix.encode(encoding, errors)) <= LENGTH_PREFIX and \
+                    len(name.encode(encoding, errors)) <= LENGTH_NAME:
+                break
+        else:
             raise ValueError("name is too long")
+
         return prefix, name
 
     @staticmethod
@@ -1531,9 +1526,9 @@ class TarFile(object):
 
            'x' or 'x:'  create a tarfile exclusively without compression, raise
                         an exception if the file is already created
-           'x:gz'       create an gzip compressed tarfile, raise an exception
+           'x:gz'       create a gzip compressed tarfile, raise an exception
                         if the file is already created
-           'x:bz2'      create an bzip2 compressed tarfile, raise an exception
+           'x:bz2'      create a bzip2 compressed tarfile, raise an exception
                         if the file is already created
            'x:xz'       create an lzma compressed tarfile, raise an exception
                         if the file is already created
@@ -1760,11 +1755,13 @@ class TarFile(object):
         return [tarinfo.name for tarinfo in self.getmembers()]
 
     def gettarinfo(self, name=None, arcname=None, fileobj=None):
-        """Create a TarInfo object for either the file `name' or the file
-           object `fileobj' (using os.fstat on its file descriptor). You can
-           modify some of the TarInfo's attributes before you add it using
-           addfile(). If given, `arcname' specifies an alternative name for the
-           file in the archive.
+        """Create a TarInfo object from the result of os.stat or equivalent
+           on an existing file. The file is either named by `name', or
+           specified as a file object `fileobj' with a file descriptor. If
+           given, `arcname' specifies an alternative name for the file in the
+           archive, otherwise, the name is taken from the 'name' attribute of
+           'fileobj', or the 'name' argument. The name should be a text
+           string.
         """
         self._check("awx")
 
@@ -1785,7 +1782,7 @@ class TarFile(object):
         # Now, fill the TarInfo object with
         # information specific for the file.
         tarinfo = self.tarinfo()
-        tarinfo.tarfile = self
+        tarinfo.tarfile = self  # Not needed
 
         # Use os.stat or os.lstat, depending on platform
         # and if symlinks shall be resolved.
@@ -1952,10 +1949,9 @@ class TarFile(object):
 
     def addfile(self, tarinfo, fileobj=None):
         """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
-           given, tarinfo.size bytes are read from it and added to the archive.
-           You can create TarInfo objects using gettarinfo().
-           On Windows platforms, `fileobj' should always be opened with mode
-           'rb' to avoid irritation about the file size.
+           given, it should be a binary file, and tarinfo.size bytes are read
+           from it and added to the archive. You can create TarInfo objects
+           directly, or by using gettarinfo().
         """
         self._check("awx")
 
@@ -2154,10 +2150,10 @@ class TarFile(object):
                 for offset, size in tarinfo.sparse:
                     target.seek(offset)
                     copyfileobj(source, target, size, ReadError)
+                target.seek(tarinfo.size)
+                target.truncate()
             else:
                 copyfileobj(source, target, tarinfo.size, ReadError)
-            target.seek(tarinfo.size)
-            target.truncate()
 
     def makeunknown(self, tarinfo, targetpath):
         """Make a file from a TarInfo object with an unknown type
index d381a25..ad687b9 100644 (file)
@@ -533,8 +533,8 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
     The file is created as mkstemp() would do it.
 
     Returns an object with a file-like interface; the name of the file
-    is accessible as file.name.  The file will be automatically deleted
-    when it is closed unless the 'delete' argument is set to False.
+    is accessible as its 'name' attribute.  The file will be automatically
+    deleted when it is closed unless the 'delete' argument is set to False.
     """
 
     prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
@@ -552,7 +552,8 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
                         newline=newline, encoding=encoding)
 
         return _TemporaryFileWrapper(file, name, delete)
-    except Exception:
+    except BaseException:
+        _os.unlink(name)
         _os.close(fd)
         raise
 
index e9120ab..11a6310 100644 (file)
@@ -455,13 +455,15 @@ class _TestSubclassingProcess(BaseTestCase):
 
     @classmethod
     def _test_stderr_flush(cls, testfn):
-        sys.stderr = open(testfn, 'w')
+        fd = os.open(testfn, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
+        sys.stderr = open(fd, 'w', closefd=False)
         1/0 # MARKER
 
 
     @classmethod
     def _test_sys_exit(cls, reason, testfn):
-        sys.stderr = open(testfn, 'w')
+        fd = os.open(testfn, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
+        sys.stderr = open(fd, 'w', closefd=False)
         sys.exit(reason)
 
     def test_sys_exit(self):
@@ -472,15 +474,21 @@ class _TestSubclassingProcess(BaseTestCase):
         testfn = test.support.TESTFN
         self.addCleanup(test.support.unlink, testfn)
 
-        for reason, code in (([1, 2, 3], 1), ('ignore this', 1)):
+        for reason in (
+            [1, 2, 3],
+            'ignore this',
+        ):
             p = self.Process(target=self._test_sys_exit, args=(reason, testfn))
             p.daemon = True
             p.start()
             p.join(5)
-            self.assertEqual(p.exitcode, code)
+            self.assertEqual(p.exitcode, 1)
 
             with open(testfn, 'r') as f:
-                self.assertEqual(f.read().rstrip(), str(reason))
+                content = f.read()
+            self.assertEqual(content.rstrip(), str(reason))
+
+            os.unlink(testfn)
 
         for reason in (True, False, 8):
             p = self.Process(target=sys.exit, args=(reason,))
@@ -1818,13 +1826,19 @@ class _TestPool(BaseTestCase):
                 expected_values.remove(value)
 
     def test_make_pool(self):
-        self.assertRaises(ValueError, multiprocessing.Pool, -1)
-        self.assertRaises(ValueError, multiprocessing.Pool, 0)
+        expected_error = (RemoteError if self.TYPE == 'manager'
+                          else ValueError)
 
-        p = multiprocessing.Pool(3)
-        self.assertEqual(3, len(p._pool))
-        p.close()
-        p.join()
+        self.assertRaises(expected_error, self.Pool, -1)
+        self.assertRaises(expected_error, self.Pool, 0)
+
+        if self.TYPE != 'manager':
+            p = self.Pool(3)
+            try:
+                self.assertEqual(3, len(p._pool))
+            finally:
+                p.close()
+                p.join()
 
     def test_terminate(self):
         result = self.pool.map_async(
@@ -1833,7 +1847,8 @@ class _TestPool(BaseTestCase):
         self.pool.terminate()
         join = TimingWrapper(self.pool.join)
         join()
-        self.assertLess(join.elapsed, 0.5)
+        # Sanity check the pool didn't wait for all tasks to finish
+        self.assertLess(join.elapsed, 2.0)
 
     def test_empty_iterable(self):
         # See Issue 12157
@@ -1851,7 +1866,7 @@ class _TestPool(BaseTestCase):
         if self.TYPE == 'processes':
             L = list(range(10))
             expected = [sqr(i) for i in L]
-            with multiprocessing.Pool(2) as p:
+            with self.Pool(2) as p:
                 r = p.map_async(sqr, L)
                 self.assertEqual(r.get(), expected)
             self.assertRaises(ValueError, p.map_async, sqr, L)
@@ -3834,7 +3849,7 @@ class ThreadsMixin(object):
     connection = multiprocessing.dummy.connection
     current_process = staticmethod(multiprocessing.dummy.current_process)
     active_children = staticmethod(multiprocessing.dummy.active_children)
-    Pool = staticmethod(multiprocessing.Pool)
+    Pool = staticmethod(multiprocessing.dummy.Pool)
     Pipe = staticmethod(multiprocessing.dummy.Pipe)
     Queue = staticmethod(multiprocessing.dummy.Queue)
     JoinableQueue = staticmethod(multiprocessing.dummy.JoinableQueue)
diff --git a/Lib/test/buffer_tests.py b/Lib/test/buffer_tests.py
deleted file mode 100644 (file)
index 0a62940..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-# Tests that work for both bytes and buffer objects.
-# See PEP 3137.
-
-import struct
-import sys
-
-class MixinBytesBufferCommonTests(object):
-    """Tests that work for both bytes and buffer objects.
-    See PEP 3137.
-    """
-
-    def marshal(self, x):
-        """Convert x into the appropriate type for these tests."""
-        raise RuntimeError('test class must provide a marshal method')
-
-    def test_islower(self):
-        self.assertFalse(self.marshal(b'').islower())
-        self.assertTrue(self.marshal(b'a').islower())
-        self.assertFalse(self.marshal(b'A').islower())
-        self.assertFalse(self.marshal(b'\n').islower())
-        self.assertTrue(self.marshal(b'abc').islower())
-        self.assertFalse(self.marshal(b'aBc').islower())
-        self.assertTrue(self.marshal(b'abc\n').islower())
-        self.assertRaises(TypeError, self.marshal(b'abc').islower, 42)
-
-    def test_isupper(self):
-        self.assertFalse(self.marshal(b'').isupper())
-        self.assertFalse(self.marshal(b'a').isupper())
-        self.assertTrue(self.marshal(b'A').isupper())
-        self.assertFalse(self.marshal(b'\n').isupper())
-        self.assertTrue(self.marshal(b'ABC').isupper())
-        self.assertFalse(self.marshal(b'AbC').isupper())
-        self.assertTrue(self.marshal(b'ABC\n').isupper())
-        self.assertRaises(TypeError, self.marshal(b'abc').isupper, 42)
-
-    def test_istitle(self):
-        self.assertFalse(self.marshal(b'').istitle())
-        self.assertFalse(self.marshal(b'a').istitle())
-        self.assertTrue(self.marshal(b'A').istitle())
-        self.assertFalse(self.marshal(b'\n').istitle())
-        self.assertTrue(self.marshal(b'A Titlecased Line').istitle())
-        self.assertTrue(self.marshal(b'A\nTitlecased Line').istitle())
-        self.assertTrue(self.marshal(b'A Titlecased, Line').istitle())
-        self.assertFalse(self.marshal(b'Not a capitalized String').istitle())
-        self.assertFalse(self.marshal(b'Not\ta Titlecase String').istitle())
-        self.assertFalse(self.marshal(b'Not--a Titlecase String').istitle())
-        self.assertFalse(self.marshal(b'NOT').istitle())
-        self.assertRaises(TypeError, self.marshal(b'abc').istitle, 42)
-
-    def test_isspace(self):
-        self.assertFalse(self.marshal(b'').isspace())
-        self.assertFalse(self.marshal(b'a').isspace())
-        self.assertTrue(self.marshal(b' ').isspace())
-        self.assertTrue(self.marshal(b'\t').isspace())
-        self.assertTrue(self.marshal(b'\r').isspace())
-        self.assertTrue(self.marshal(b'\n').isspace())
-        self.assertTrue(self.marshal(b' \t\r\n').isspace())
-        self.assertFalse(self.marshal(b' \t\r\na').isspace())
-        self.assertRaises(TypeError, self.marshal(b'abc').isspace, 42)
-
-    def test_isalpha(self):
-        self.assertFalse(self.marshal(b'').isalpha())
-        self.assertTrue(self.marshal(b'a').isalpha())
-        self.assertTrue(self.marshal(b'A').isalpha())
-        self.assertFalse(self.marshal(b'\n').isalpha())
-        self.assertTrue(self.marshal(b'abc').isalpha())
-        self.assertFalse(self.marshal(b'aBc123').isalpha())
-        self.assertFalse(self.marshal(b'abc\n').isalpha())
-        self.assertRaises(TypeError, self.marshal(b'abc').isalpha, 42)
-
-    def test_isalnum(self):
-        self.assertFalse(self.marshal(b'').isalnum())
-        self.assertTrue(self.marshal(b'a').isalnum())
-        self.assertTrue(self.marshal(b'A').isalnum())
-        self.assertFalse(self.marshal(b'\n').isalnum())
-        self.assertTrue(self.marshal(b'123abc456').isalnum())
-        self.assertTrue(self.marshal(b'a1b3c').isalnum())
-        self.assertFalse(self.marshal(b'aBc000 ').isalnum())
-        self.assertFalse(self.marshal(b'abc\n').isalnum())
-        self.assertRaises(TypeError, self.marshal(b'abc').isalnum, 42)
-
-    def test_isdigit(self):
-        self.assertFalse(self.marshal(b'').isdigit())
-        self.assertFalse(self.marshal(b'a').isdigit())
-        self.assertTrue(self.marshal(b'0').isdigit())
-        self.assertTrue(self.marshal(b'0123456789').isdigit())
-        self.assertFalse(self.marshal(b'0123456789a').isdigit())
-
-        self.assertRaises(TypeError, self.marshal(b'abc').isdigit, 42)
-
-    def test_lower(self):
-        self.assertEqual(b'hello', self.marshal(b'HeLLo').lower())
-        self.assertEqual(b'hello', self.marshal(b'hello').lower())
-        self.assertRaises(TypeError, self.marshal(b'hello').lower, 42)
-
-    def test_upper(self):
-        self.assertEqual(b'HELLO', self.marshal(b'HeLLo').upper())
-        self.assertEqual(b'HELLO', self.marshal(b'HELLO').upper())
-        self.assertRaises(TypeError, self.marshal(b'hello').upper, 42)
-
-    def test_capitalize(self):
-        self.assertEqual(b' hello ', self.marshal(b' hello ').capitalize())
-        self.assertEqual(b'Hello ', self.marshal(b'Hello ').capitalize())
-        self.assertEqual(b'Hello ', self.marshal(b'hello ').capitalize())
-        self.assertEqual(b'Aaaa', self.marshal(b'aaaa').capitalize())
-        self.assertEqual(b'Aaaa', self.marshal(b'AaAa').capitalize())
-
-        self.assertRaises(TypeError, self.marshal(b'hello').capitalize, 42)
-
-    def test_ljust(self):
-        self.assertEqual(b'abc       ', self.marshal(b'abc').ljust(10))
-        self.assertEqual(b'abc   ', self.marshal(b'abc').ljust(6))
-        self.assertEqual(b'abc', self.marshal(b'abc').ljust(3))
-        self.assertEqual(b'abc', self.marshal(b'abc').ljust(2))
-        self.assertEqual(b'abc*******', self.marshal(b'abc').ljust(10, b'*'))
-        self.assertRaises(TypeError, self.marshal(b'abc').ljust)
-
-    def test_rjust(self):
-        self.assertEqual(b'       abc', self.marshal(b'abc').rjust(10))
-        self.assertEqual(b'   abc', self.marshal(b'abc').rjust(6))
-        self.assertEqual(b'abc', self.marshal(b'abc').rjust(3))
-        self.assertEqual(b'abc', self.marshal(b'abc').rjust(2))
-        self.assertEqual(b'*******abc', self.marshal(b'abc').rjust(10, b'*'))
-        self.assertRaises(TypeError, self.marshal(b'abc').rjust)
-
-    def test_center(self):
-        self.assertEqual(b'   abc    ', self.marshal(b'abc').center(10))
-        self.assertEqual(b' abc  ', self.marshal(b'abc').center(6))
-        self.assertEqual(b'abc', self.marshal(b'abc').center(3))
-        self.assertEqual(b'abc', self.marshal(b'abc').center(2))
-        self.assertEqual(b'***abc****', self.marshal(b'abc').center(10, b'*'))
-        self.assertRaises(TypeError, self.marshal(b'abc').center)
-
-    def test_swapcase(self):
-        self.assertEqual(b'hEllO CoMPuTErS',
-            self.marshal(b'HeLLo cOmpUteRs').swapcase())
-
-        self.assertRaises(TypeError, self.marshal(b'hello').swapcase, 42)
-
-    def test_zfill(self):
-        self.assertEqual(b'123', self.marshal(b'123').zfill(2))
-        self.assertEqual(b'123', self.marshal(b'123').zfill(3))
-        self.assertEqual(b'0123', self.marshal(b'123').zfill(4))
-        self.assertEqual(b'+123', self.marshal(b'+123').zfill(3))
-        self.assertEqual(b'+123', self.marshal(b'+123').zfill(4))
-        self.assertEqual(b'+0123', self.marshal(b'+123').zfill(5))
-        self.assertEqual(b'-123', self.marshal(b'-123').zfill(3))
-        self.assertEqual(b'-123', self.marshal(b'-123').zfill(4))
-        self.assertEqual(b'-0123', self.marshal(b'-123').zfill(5))
-        self.assertEqual(b'000', self.marshal(b'').zfill(3))
-        self.assertEqual(b'34', self.marshal(b'34').zfill(1))
-        self.assertEqual(b'0034', self.marshal(b'34').zfill(4))
-
-        self.assertRaises(TypeError, self.marshal(b'123').zfill)
-
-    def test_expandtabs(self):
-        self.assertEqual(b'abc\rab      def\ng       hi',
-                         self.marshal(b'abc\rab\tdef\ng\thi').expandtabs())
-        self.assertEqual(b'abc\rab      def\ng       hi',
-                         self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(8))
-        self.assertEqual(b'abc\rab  def\ng   hi',
-                         self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(4))
-        self.assertEqual(b'abc\r\nab      def\ng       hi',
-                         self.marshal(b'abc\r\nab\tdef\ng\thi').expandtabs())
-        self.assertEqual(b'abc\r\nab      def\ng       hi',
-                         self.marshal(b'abc\r\nab\tdef\ng\thi').expandtabs(8))
-        self.assertEqual(b'abc\r\nab  def\ng   hi',
-                         self.marshal(b'abc\r\nab\tdef\ng\thi').expandtabs(4))
-        self.assertEqual(b'abc\r\nab\r\ndef\ng\r\nhi',
-                         self.marshal(b'abc\r\nab\r\ndef\ng\r\nhi').expandtabs(4))
-        # check keyword args
-        self.assertEqual(b'abc\rab      def\ng       hi',
-                         self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(tabsize=8))
-        self.assertEqual(b'abc\rab  def\ng   hi',
-                         self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(tabsize=4))
-
-        self.assertEqual(b'  a\n b', self.marshal(b' \ta\n\tb').expandtabs(1))
-
-        self.assertRaises(TypeError, self.marshal(b'hello').expandtabs, 42, 42)
-        # This test is only valid when sizeof(int) == sizeof(void*) == 4.
-        if sys.maxsize < (1 << 32) and struct.calcsize('P') == 4:
-            self.assertRaises(OverflowError,
-                              self.marshal(b'\ta\n\tb').expandtabs, sys.maxsize)
-
-    def test_title(self):
-        self.assertEqual(b' Hello ', self.marshal(b' hello ').title())
-        self.assertEqual(b'Hello ', self.marshal(b'hello ').title())
-        self.assertEqual(b'Hello ', self.marshal(b'Hello ').title())
-        self.assertEqual(b'Format This As Title String',
-                         self.marshal(b'fOrMaT thIs aS titLe String').title())
-        self.assertEqual(b'Format,This-As*Title;String',
-                         self.marshal(b'fOrMaT,thIs-aS*titLe;String').title())
-        self.assertEqual(b'Getint', self.marshal(b'getInt').title())
-        self.assertRaises(TypeError, self.marshal(b'hello').title, 42)
-
-    def test_splitlines(self):
-        self.assertEqual([b'abc', b'def', b'', b'ghi'],
-                         self.marshal(b'abc\ndef\n\rghi').splitlines())
-        self.assertEqual([b'abc', b'def', b'', b'ghi'],
-                         self.marshal(b'abc\ndef\n\r\nghi').splitlines())
-        self.assertEqual([b'abc', b'def', b'ghi'],
-                         self.marshal(b'abc\ndef\r\nghi').splitlines())
-        self.assertEqual([b'abc', b'def', b'ghi'],
-                         self.marshal(b'abc\ndef\r\nghi\n').splitlines())
-        self.assertEqual([b'abc', b'def', b'ghi', b''],
-                         self.marshal(b'abc\ndef\r\nghi\n\r').splitlines())
-        self.assertEqual([b'', b'abc', b'def', b'ghi', b''],
-                         self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines())
-        self.assertEqual([b'', b'abc', b'def', b'ghi', b''],
-                         self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines(False))
-        self.assertEqual([b'\n', b'abc\n', b'def\r\n', b'ghi\n', b'\r'],
-                         self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines(True))
-        self.assertEqual([b'', b'abc', b'def', b'ghi', b''],
-                         self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines(keepends=False))
-        self.assertEqual([b'\n', b'abc\n', b'def\r\n', b'ghi\n', b'\r'],
-                         self.marshal(b'\nabc\ndef\r\nghi\n\r').splitlines(keepends=True))
-
-        self.assertRaises(TypeError, self.marshal(b'abc').splitlines, 42, 42)
index 58b4209..347d603 100644 (file)
@@ -32,8 +32,8 @@ class BytecodeTestCase(unittest.TestCase):
         """Throws AssertionError if op is found"""
         for instr in dis.get_instructions(x):
             if instr.opname == opname:
-                disassembly = self.get_disassembly_as_string(co)
-                if opargval is _UNSPECIFIED:
+                disassembly = self.get_disassembly_as_string(x)
+                if argval is _UNSPECIFIED:
                     msg = '%s occurs in bytecode:\n%s' % (opname, disassembly)
                 elif instr.argval == argval:
                     msg = '(%s,%r) occurs in bytecode:\n%s'
diff --git a/Lib/test/capath/0e4015b9.0 b/Lib/test/capath/0e4015b9.0
new file mode 100644 (file)
index 0000000..b6d259b
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIIClTCCAf6gAwIBAgIJAKGU95wKR8pTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
+BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
+IFNvZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMMGnNlbGYtc2lnbmVkLnB5dGhv
+bnRlc3QubmV0MB4XDTE0MTEwMjE4MDkyOVoXDTI0MTAzMDE4MDkyOVowcDELMAkG
+A1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRo
+b24gU29mdHdhcmUgRm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0
+aG9udGVzdC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANDXQXW9tjyZ
+Xt0Iv2tLL1+jinr4wGg36ioLDLFkMf+2Y1GL0v0BnKYG4N1OKlAU15LXGeGer8vm
+Sv/yIvmdrELvhAbbo3w4a9TMYQA4XkIVLdvu3mvNOAet+8PMJxn26dbDhG809ALv
+EHY57lQsBS3G59RZyBPVqAqmImWNJnVzAgMBAAGjNzA1MCUGA1UdEQQeMByCGnNl
+bGYtc2lnbmVkLnB5dGhvbnRlc3QubmV0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
+AQEFBQADgYEAIuzAhgMouJpNdf3URCHIineyoSt6WK/9+eyUcjlKOrDoXNZaD72h
+TXMeKYoWvJyVcSLKL8ckPtDobgP2OTt0UkyAaj0n+ZHaqq1lH2yVfGUA1ILJv515
+C8BqbvVZuqm3i7ygmw3bqE/lYMgOrYtXXnqOrz6nvsE6Yc9V9rFflOM=
+-----END CERTIFICATE-----
diff --git a/Lib/test/capath/ce7b8643.0 b/Lib/test/capath/ce7b8643.0
new file mode 100644 (file)
index 0000000..b6d259b
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIIClTCCAf6gAwIBAgIJAKGU95wKR8pTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
+BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
+IFNvZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMMGnNlbGYtc2lnbmVkLnB5dGhv
+bnRlc3QubmV0MB4XDTE0MTEwMjE4MDkyOVoXDTI0MTAzMDE4MDkyOVowcDELMAkG
+A1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRo
+b24gU29mdHdhcmUgRm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0
+aG9udGVzdC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANDXQXW9tjyZ
+Xt0Iv2tLL1+jinr4wGg36ioLDLFkMf+2Y1GL0v0BnKYG4N1OKlAU15LXGeGer8vm
+Sv/yIvmdrELvhAbbo3w4a9TMYQA4XkIVLdvu3mvNOAet+8PMJxn26dbDhG809ALv
+EHY57lQsBS3G59RZyBPVqAqmImWNJnVzAgMBAAGjNzA1MCUGA1UdEQQeMByCGnNl
+bGYtc2lnbmVkLnB5dGhvbnRlc3QubmV0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
+AQEFBQADgYEAIuzAhgMouJpNdf3URCHIineyoSt6WK/9+eyUcjlKOrDoXNZaD72h
+TXMeKYoWvJyVcSLKL8ckPtDobgP2OTt0UkyAaj0n+ZHaqq1lH2yVfGUA1ILJv515
+C8BqbvVZuqm3i7ygmw3bqE/lYMgOrYtXXnqOrz6nvsE6Yc9V9rFflOM=
+-----END CERTIFICATE-----
index 19a420a..1646de8 100644 (file)
 # either /etc/hosts OR DNS or NIS depending on the settings of 
 # /etc/host.config, /etc/nsswitch.conf
 # and the /etc/resolv.conf file. "host" therefore is system 
-# configuration dependant. This parameter is most often of use to 
+# configuration dependent. This parameter is most often of use to 
 # prevent DNS lookups
 # in order to resolve NetBIOS names to IP Addresses. Use with care!
 # The example below excludes use of name resolution for machines that
index 6365c60..f5222c7 100644 (file)
@@ -117,6 +117,9 @@ class PicklableFixedOffset(FixedOffset):
     def __init__(self, offset=None, name=None, dstoffset=None):
         FixedOffset.__init__(self, offset, name, dstoffset)
 
+    def __getstate__(self):
+        return self.__dict__
+
 class _TZInfo(tzinfo):
     def utcoffset(self, datetime_module):
         return random.random()
@@ -1224,7 +1227,7 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
         #self.assertRaises(ValueError, t.strftime, "%#")
 
         #oh well, some systems just ignore those invalid ones.
-        #at least, excercise them to make sure that no crashes
+        #at least, exercise them to make sure that no crashes
         #are generated
         for f in ["%e", "%", "%#"]:
             try:
@@ -1239,7 +1242,7 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
         dt = self.theclass(2007, 9, 10)
         self.assertEqual(dt.__format__(''), str(dt))
 
-        with self.assertRaisesRegex(TypeError, '^must be str, not int$'):
+        with self.assertRaisesRegex(TypeError, 'must be str, not int'):
             dt.__format__(123)
 
         # check that a derived class's __str__() gets called
@@ -1574,7 +1577,7 @@ class TestDateTime(TestDate):
         dt = self.theclass(2007, 9, 10, 4, 5, 1, 123)
         self.assertEqual(dt.__format__(''), str(dt))
 
-        with self.assertRaisesRegex(TypeError, '^must be str, not int$'):
+        with self.assertRaisesRegex(TypeError, 'must be str, not int'):
             dt.__format__(123)
 
         # check that a derived class's __str__() gets called
@@ -2336,7 +2339,7 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
         t = self.theclass(1, 2, 3, 4)
         self.assertEqual(t.__format__(''), str(t))
 
-        with self.assertRaisesRegex(TypeError, '^must be str, not int$'):
+        with self.assertRaisesRegex(TypeError, 'must be str, not int'):
             t.__format__(123)
 
         # check that a derived class's __str__() gets called
@@ -2473,7 +2476,7 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
             self.theclass(bytes([1] * len(base)), 'EST')
 
 # A mixin for classes with a tzinfo= argument.  Subclasses must define
-# theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever)
+# theclass as a class attribute, and theclass(1, 1, 1, tzinfo=whatever)
 # must be legit (which is true for time and datetime).
 class TZInfoBase:
 
@@ -3423,6 +3426,14 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase):
         self.assertEqual(dt, local)
         self.assertEqual(local.strftime("%z %Z"), "-0400 EDT")
 
+    @support.run_with_tz('EST+05EDT,M3.2.0,M11.1.0')
+    def test_astimezone_default_near_fold(self):
+        # Issue #26616.
+        u = datetime(2015, 11, 1, 5, tzinfo=timezone.utc)
+        t = u.astimezone()
+        s = t.astimezone()
+        self.assertEqual(t.tzinfo, s.tzinfo)
+
     def test_aware_subtract(self):
         cls = self.theclass
 
index e3c36f9..9931a55 100644 (file)
@@ -334,10 +334,12 @@ class SocketEINTRTest(EINTRBaseTest):
         self._test_open("fp = open(path, 'r')\nfp.close()",
                         self.python_open)
 
+    @unittest.skipIf(sys.platform == 'darwin', "hangs under OS X; see issue #25234")
     def os_open(self, path):
         fd = os.open(path, os.O_WRONLY)
         os.close(fd)
 
+    @unittest.skipIf(sys.platform == "darwin", "hangs under OS X; see issue #25234")
     def test_os_open(self):
         self._test_open("fd = os.open(path, os.O_RDONLY)\nos.close(fd)",
                         self.os_open)
@@ -370,10 +372,10 @@ class SignalEINTRTest(EINTRBaseTest):
     @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
                          'need signal.sigwaitinfo()')
     def test_sigwaitinfo(self):
-        # Issue #25277: The sleep is a weak synchronization between the parent
-        # and the child process. If the sleep is too low, the test hangs on
-        # slow or highly loaded systems.
-        self.sleep_time = 2.0
+        # Issue #25277, #25868: give a few miliseconds to the parent process
+        # between os.write() and signal.sigwaitinfo() to works around a race
+        # condition
+        self.sleep_time = 0.100
 
         signum = signal.SIGUSR1
         pid = os.getpid()
@@ -381,18 +383,28 @@ class SignalEINTRTest(EINTRBaseTest):
         old_handler = signal.signal(signum, lambda *args: None)
         self.addCleanup(signal.signal, signum, old_handler)
 
+        rpipe, wpipe = os.pipe()
+
         code = '\n'.join((
             'import os, time',
             'pid = %s' % os.getpid(),
             'signum = %s' % int(signum),
             'sleep_time = %r' % self.sleep_time,
+            'rpipe = %r' % rpipe,
+            'os.read(rpipe, 1)',
+            'os.close(rpipe)',
             'time.sleep(sleep_time)',
             'os.kill(pid, signum)',
         ))
 
         t0 = time.monotonic()
-        proc = self.subprocess(code)
+        proc = self.subprocess(code, pass_fds=(rpipe,))
+        os.close(rpipe)
         with kill_on_error(proc):
+            # sync child-parent
+            os.write(wpipe, b'x')
+            os.close(wpipe)
+
             # parent
             signal.sigwaitinfo([signum])
             dt = time.monotonic() - t0
diff --git a/Lib/test/https_svn_python_org_root.pem b/Lib/test/https_svn_python_org_root.pem
deleted file mode 100644 (file)
index e7dfc82..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
-IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
-IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
-Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
-BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
-MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
-ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
-CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
-8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
-zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
-fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
-w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
-G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
-epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
-laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
-QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
-fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
-YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
-ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
-gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
-MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
-IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
-dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
-czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
-dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
-aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
-AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
-b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
-ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
-nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
-18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
-gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
-Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
-sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
-SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
-CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
-GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
-zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
-omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
------END CERTIFICATE-----
index 1adfc75..f20fdc0 100644 (file)
@@ -593,3 +593,14 @@ class CommonTest(seq_tests.CommonTest):
             def __iter__(self):
                 raise KeyboardInterrupt
         self.assertRaises(KeyboardInterrupt, list, F())
+
+    def test_exhausted_iterator(self):
+        a = self.type2test([1, 2, 3])
+        exhit = iter(a)
+        empit = iter(a)
+        for x in exhit:  # exhaust the iterator
+            next(empit)  # not exhausted
+        a.append(9)
+        self.assertEqual(list(exhit), [])
+        self.assertEqual(list(empit), [9])
+        self.assertEqual(a, self.type2test([1, 2, 3, 9]))
index afd6873..a64aa18 100644 (file)
@@ -395,12 +395,13 @@ class EventTests(BaseTestCase):
         self.assertEqual(results, [True] * N)
 
     def test_reset_internal_locks(self):
+        # ensure that condition is still using a Lock after reset
         evt = self.eventtype()
-        old_lock = evt._cond._lock
+        with evt._cond:
+            self.assertFalse(evt._cond.acquire(False))
         evt._reset_internal_locks()
-        new_lock = evt._cond._lock
-        self.assertIsNot(new_lock, old_lock)
-        self.assertIs(type(new_lock), type(old_lock))
+        with evt._cond:
+            self.assertFalse(evt._cond.acquire(False))
 
 
 class ConditionTests(BaseTestCase):
index 6d971aa..f252a0a 100644 (file)
@@ -11,6 +11,7 @@ import unittest
 import weakref
 from http.cookies import SimpleCookie
 
+from test import support
 from test.support import (
     TestFailed, TESTFN, run_with_locale, no_tracing,
     _2G, _4G, bigmemtest,
@@ -679,6 +680,17 @@ class AbstractUnpickleTests(unittest.TestCase):
                 self.assertEqual(getattr(obj, slot, None),
                                  getattr(objcopy, slot, None), msg=msg)
 
+    def check_unpickling_error(self, errors, data):
+        with self.subTest(data=data), \
+             self.assertRaises(errors):
+            try:
+                self.loads(data)
+            except BaseException as exc:
+                if support.verbose > 1:
+                    print('%-32r - %s: %s' %
+                          (data, exc.__class__.__name__, exc))
+                raise
+
     def test_load_from_data0(self):
         self.assert_is_copy(self._testdata, self.loads(DATA0))
 
@@ -759,12 +771,7 @@ class AbstractUnpickleTests(unittest.TestCase):
 
         # Try too with a bogus literal.
         data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
-        self.assertRaises(ValueError, self.loads, data)
-
-    def test_pop_empty_stack(self):
-        # Test issue7455
-        s = b'0'
-        self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s)
+        self.check_unpickling_error(ValueError, data)
 
     def test_unpickle_from_2x(self):
         # Unpickle non-trivial data from Python 2.x.
@@ -849,22 +856,22 @@ class AbstractUnpickleTests(unittest.TestCase):
     def test_negative_32b_binbytes(self):
         # On 32-bit builds, a BINBYTES of 2**31 or more is refused
         dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.'
-        with self.assertRaises((pickle.UnpicklingError, OverflowError)):
-            self.loads(dumped)
+        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
+                                    dumped)
 
     @requires_32b
     def test_negative_32b_binunicode(self):
         # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
         dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.'
-        with self.assertRaises((pickle.UnpicklingError, OverflowError)):
-            self.loads(dumped)
+        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
+                                    dumped)
 
     def test_short_binunicode(self):
         dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.'
         self.assertEqual(self.loads(dumped), '\u20ac\x00')
 
     def test_misc_get(self):
-        self.assertRaises(KeyError, self.loads, b'g0\np0')
+        self.check_unpickling_error(KeyError, b'g0\np0')
         self.assert_is_copy([(100,), (100,)],
                             self.loads(b'((Kdtp0\nh\x00l.))'))
 
@@ -879,14 +886,14 @@ class AbstractUnpickleTests(unittest.TestCase):
     @requires_32b
     def test_large_32b_binbytes8(self):
         dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
-        with self.assertRaises((pickle.UnpicklingError, OverflowError)):
-            self.loads(dumped)
+        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
+                                    dumped)
 
     @requires_32b
     def test_large_32b_binunicode8(self):
         dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
-        with self.assertRaises((pickle.UnpicklingError, OverflowError)):
-            self.loads(dumped)
+        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
+                                    dumped)
 
     def test_get(self):
         pickled = b'((lp100000\ng100000\nt.'
@@ -915,16 +922,16 @@ class AbstractUnpickleTests(unittest.TestCase):
     def test_negative_put(self):
         # Issue #12847
         dumped = b'Va\np-1\n.'
-        self.assertRaises(ValueError, self.loads, dumped)
+        self.check_unpickling_error(ValueError, dumped)
 
     @requires_32b
     def test_negative_32b_binput(self):
         # Issue #12847
         dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
-        self.assertRaises(ValueError, self.loads, dumped)
+        self.check_unpickling_error(ValueError, dumped)
 
     def test_badly_escaped_string(self):
-        self.assertRaises(ValueError, self.loads, b"S'\\'\n.")
+        self.check_unpickling_error(ValueError, b"S'\\'\n.")
 
     def test_badly_quoted_string(self):
         # Issue #17710
@@ -942,7 +949,7 @@ class AbstractUnpickleTests(unittest.TestCase):
                       b'S\n.',
                       b'S.']
         for p in badpickles:
-            self.assertRaises(pickle.UnpicklingError, self.loads, p)
+            self.check_unpickling_error(pickle.UnpicklingError, p)
 
     def test_correctly_quoted_string(self):
         goodpickles = [(b"S''\n.", ''),
@@ -987,6 +994,186 @@ class AbstractUnpickleTests(unittest.TestCase):
             self.assertIs(type(unpickled), collections.UserDict)
             self.assertEqual(unpickled, collections.UserDict({1: 2}))
 
+    def test_bad_stack(self):
+        badpickles = [
+            b'.',                       # STOP
+            b'0',                       # POP
+            b'1',                       # POP_MARK
+            b'2',                       # DUP
+            # b'(2',                    # PyUnpickler doesn't raise
+            b'R',                       # REDUCE
+            b')R',
+            b'a',                       # APPEND
+            b'Na',
+            b'b',                       # BUILD
+            b'Nb',
+            b'd',                       # DICT
+            b'e',                       # APPENDS
+            # b'(e',                    # PyUnpickler raises AttributeError
+            b'ibuiltins\nlist\n',       # INST
+            b'l',                       # LIST
+            b'o',                       # OBJ
+            b'(o',
+            b'p1\n',                    # PUT
+            b'q\x00',                   # BINPUT
+            b'r\x00\x00\x00\x00',       # LONG_BINPUT
+            b's',                       # SETITEM
+            b'Ns',
+            b'NNs',
+            b't',                       # TUPLE
+            b'u',                       # SETITEMS
+            # b'(u',                    # PyUnpickler doesn't raise
+            b'}(Nu',
+            b'\x81',                    # NEWOBJ
+            b')\x81',
+            b'\x85',                    # TUPLE1
+            b'\x86',                    # TUPLE2
+            b'N\x86',
+            b'\x87',                    # TUPLE3
+            b'N\x87',
+            b'NN\x87',
+            b'\x90',                    # ADDITEMS
+            # b'(\x90',                 # PyUnpickler raises AttributeError
+            b'\x91',                    # FROZENSET
+            b'\x92',                    # NEWOBJ_EX
+            b')}\x92',
+            b'\x93',                    # STACK_GLOBAL
+            b'Vlist\n\x93',
+            b'\x94',                    # MEMOIZE
+        ]
+        for p in badpickles:
+            self.check_unpickling_error(self.bad_stack_errors, p)
+
+    def test_bad_mark(self):
+        badpickles = [
+            # b'N(.',                     # STOP
+            b'N(2',                     # DUP
+            b'cbuiltins\nlist\n)(R',    # REDUCE
+            b'cbuiltins\nlist\n()R',
+            b']N(a',                    # APPEND
+                                        # BUILD
+            b'cbuiltins\nValueError\n)R}(b',
+            b'cbuiltins\nValueError\n)R(}b',
+            b'(Nd',                     # DICT
+            b'N(p1\n',                  # PUT
+            b'N(q\x00',                 # BINPUT
+            b'N(r\x00\x00\x00\x00',     # LONG_BINPUT
+            b'}NN(s',                   # SETITEM
+            b'}N(Ns',
+            b'}(NNs',
+            b'}((u',                    # SETITEMS
+            b'cbuiltins\nlist\n)(\x81', # NEWOBJ
+            b'cbuiltins\nlist\n()\x81',
+            b'N(\x85',                  # TUPLE1
+            b'NN(\x86',                 # TUPLE2
+            b'N(N\x86',
+            b'NNN(\x87',                # TUPLE3
+            b'NN(N\x87',
+            b'N(NN\x87',
+            b']((\x90',                 # ADDITEMS
+                                        # NEWOBJ_EX
+            b'cbuiltins\nlist\n)}(\x92',
+            b'cbuiltins\nlist\n)(}\x92',
+            b'cbuiltins\nlist\n()}\x92',
+                                        # STACK_GLOBAL
+            b'Vbuiltins\n(Vlist\n\x93',
+            b'Vbuiltins\nVlist\n(\x93',
+            b'N(\x94',                  # MEMOIZE
+        ]
+        for p in badpickles:
+            self.check_unpickling_error(self.bad_mark_errors, p)
+
+    def test_truncated_data(self):
+        self.check_unpickling_error(EOFError, b'')
+        self.check_unpickling_error(EOFError, b'N')
+        badpickles = [
+            b'B',                       # BINBYTES
+            b'B\x03\x00\x00',
+            b'B\x03\x00\x00\x00',
+            b'B\x03\x00\x00\x00ab',
+            b'C',                       # SHORT_BINBYTES
+            b'C\x03',
+            b'C\x03ab',
+            b'F',                       # FLOAT
+            b'F0.0',
+            b'F0.00',
+            b'G',                       # BINFLOAT
+            b'G\x00\x00\x00\x00\x00\x00\x00',
+            b'I',                       # INT
+            b'I0',
+            b'J',                       # BININT
+            b'J\x00\x00\x00',
+            b'K',                       # BININT1
+            b'L',                       # LONG
+            b'L0',
+            b'L10',
+            b'L0L',
+            b'L10L',
+            b'M',                       # BININT2
+            b'M\x00',
+            # b'P',                       # PERSID
+            # b'Pabc',
+            b'S',                       # STRING
+            b"S'abc'",
+            b'T',                       # BINSTRING
+            b'T\x03\x00\x00',
+            b'T\x03\x00\x00\x00',
+            b'T\x03\x00\x00\x00ab',
+            b'U',                       # SHORT_BINSTRING
+            b'U\x03',
+            b'U\x03ab',
+            b'V',                       # UNICODE
+            b'Vabc',
+            b'X',                       # BINUNICODE
+            b'X\x03\x00\x00',
+            b'X\x03\x00\x00\x00',
+            b'X\x03\x00\x00\x00ab',
+            b'(c',                      # GLOBAL
+            b'(cbuiltins',
+            b'(cbuiltins\n',
+            b'(cbuiltins\nlist',
+            b'Ng',                      # GET
+            b'Ng0',
+            b'(i',                      # INST
+            b'(ibuiltins',
+            b'(ibuiltins\n',
+            b'(ibuiltins\nlist',
+            b'Nh',                      # BINGET
+            b'Nj',                      # LONG_BINGET
+            b'Nj\x00\x00\x00',
+            b'Np',                      # PUT
+            b'Np0',
+            b'Nq',                      # BINPUT
+            b'Nr',                      # LONG_BINPUT
+            b'Nr\x00\x00\x00',
+            b'\x80',                    # PROTO
+            b'\x82',                    # EXT1
+            b'\x83',                    # EXT2
+            b'\x84\x01',
+            b'\x84',                    # EXT4
+            b'\x84\x01\x00\x00',
+            b'\x8a',                    # LONG1
+            b'\x8b',                    # LONG4
+            b'\x8b\x00\x00\x00',
+            b'\x8c',                    # SHORT_BINUNICODE
+            b'\x8c\x03',
+            b'\x8c\x03ab',
+            b'\x8d',                    # BINUNICODE8
+            b'\x8d\x03\x00\x00\x00\x00\x00\x00',
+            b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00',
+            b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab',
+            b'\x8e',                    # BINBYTES8
+            b'\x8e\x03\x00\x00\x00\x00\x00\x00',
+            b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00',
+            b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab',
+            b'\x95',                    # FRAME
+            b'\x95\x02\x00\x00\x00\x00\x00\x00',
+            b'\x95\x02\x00\x00\x00\x00\x00\x00\x00',
+            b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N',
+        ]
+        for p in badpickles:
+            self.check_unpickling_error(self.truncated_errors, p)
+
 
 class AbstractPickleTests(unittest.TestCase):
     # Subclass must define self.dumps, self.loads.
@@ -1757,15 +1944,15 @@ class AbstractPickleTests(unittest.TestCase):
                 # 5th item is not an iterator
                 return dict, (), None, None, []
 
-        # Protocol 0 is less strict and also accept iterables.
+        # Python implementation is less strict and also accepts iterables.
         for proto in protocols:
             try:
                 self.dumps(C(), proto)
-            except (pickle.PickleError):
+            except pickle.PicklingError:
                 pass
             try:
                 self.dumps(D(), proto)
-            except (pickle.PickleError):
+            except pickle.PicklingError:
                 pass
 
     def test_many_puts_and_gets(self):
@@ -2261,7 +2448,7 @@ class REX_six(object):
     def __init__(self, items=None):
         self.items = items if items is not None else []
     def __eq__(self, other):
-        return type(self) is type(other) and self.items == self.items
+        return type(self) is type(other) and self.items == other.items
     def append(self, item):
         self.items.append(item)
     def __reduce__(self):
@@ -2274,7 +2461,7 @@ class REX_seven(object):
     def __init__(self, table=None):
         self.table = table if table is not None else {}
     def __eq__(self, other):
-        return type(self) is type(other) and self.table == self.table
+        return type(self) is type(other) and self.table == other.table
     def __setitem__(self, key, value):
         self.table[key] = value
     def __reduce__(self):
index 431042e..fecfd09 100755 (executable)
@@ -1057,6 +1057,7 @@ class saved_test_environment:
                  'multiprocessing.process._dangling', 'threading._dangling',
                  'sysconfig._CONFIG_VARS', 'sysconfig._INSTALL_SCHEMES',
                  'files', 'locale', 'warnings.showwarning',
+                 'shutil_archive_formats', 'shutil_unpack_formats',
                 )
 
     def get_sys_argv(self):
index 9a80073..b6d259b 100644 (file)
@@ -1,5 +1,5 @@
 -----BEGIN CERTIFICATE-----
-MIIChzCCAfCgAwIBAgIJAKGU95wKR8pSMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
+MIIClTCCAf6gAwIBAgIJAKGU95wKR8pTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
 BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
 IFNvZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMMGnNlbGYtc2lnbmVkLnB5dGhv
 bnRlc3QubmV0MB4XDTE0MTEwMjE4MDkyOVoXDTI0MTAzMDE4MDkyOVowcDELMAkG
@@ -8,9 +8,9 @@ b24gU29mdHdhcmUgRm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0
 aG9udGVzdC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANDXQXW9tjyZ
 Xt0Iv2tLL1+jinr4wGg36ioLDLFkMf+2Y1GL0v0BnKYG4N1OKlAU15LXGeGer8vm
 Sv/yIvmdrELvhAbbo3w4a9TMYQA4XkIVLdvu3mvNOAet+8PMJxn26dbDhG809ALv
-EHY57lQsBS3G59RZyBPVqAqmImWNJnVzAgMBAAGjKTAnMCUGA1UdEQQeMByCGnNl
-bGYtc2lnbmVkLnB5dGhvbnRlc3QubmV0MA0GCSqGSIb3DQEBBQUAA4GBAIOXmdtM
-eG9qzP9TiXW/Gc/zI4cBfdCpC+Y4gOfC9bQUC7hefix4iO3+iZjgy3X/FaRxUUoV
-HKiXcXIaWqTSUWp45cSh0MbwZXudp6JIAptzdAhvvCrPKeC9i9GvxsPD4LtDAL97
-vSaxQBezA7hdxZd90/EeyMgVZgAnTCnvAWX9
+EHY57lQsBS3G59RZyBPVqAqmImWNJnVzAgMBAAGjNzA1MCUGA1UdEQQeMByCGnNl
+bGYtc2lnbmVkLnB5dGhvbnRlc3QubmV0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
+AQEFBQADgYEAIuzAhgMouJpNdf3URCHIineyoSt6WK/9+eyUcjlKOrDoXNZaD72h
+TXMeKYoWvJyVcSLKL8ckPtDobgP2OTt0UkyAaj0n+ZHaqq1lH2yVfGUA1ILJv515
+C8BqbvVZuqm3i7ygmw3bqE/lYMgOrYtXXnqOrz6nvsE6Yc9V9rFflOM=
 -----END CERTIFICATE-----
index 2416249..72f4845 100644 (file)
@@ -5,6 +5,7 @@ Tests common to tuple, list and UserList.UserList
 import unittest
 import sys
 import pickle
+from test import support
 
 # Various iterables
 # This is used for checking the constructor (here and in test_deque.py)
@@ -408,3 +409,7 @@ class CommonTest(unittest.TestCase):
             lst2 = pickle.loads(pickle.dumps(lst, proto))
             self.assertEqual(lst2, lst)
             self.assertNotEqual(id(lst2), id(lst))
+
+    def test_free_after_iterating(self):
+        support.check_free_after_iterating(self, iter, self.type2test)
+        support.check_free_after_iterating(self, reversed, self.type2test)
index e086994..cd3ee48 100644 (file)
@@ -1,5 +1,5 @@
 """
-Common tests shared by test_unicode, test_userstring and test_string.
+Common tests shared by test_unicode, test_userstring and test_bytes.
 """
 
 import unittest, string, sys, struct
@@ -51,6 +51,9 @@ class BaseTest:
         else:
             return obj
 
+    def test_fixtype(self):
+        self.assertIs(type(self.fixtype("123")), self.type2test)
+
     # check that obj.method(*args) returns result
     def checkequal(self, result, obj, methodname, *args, **kwargs):
         result = self.fixtype(result)
@@ -365,6 +368,8 @@ class BaseTest:
                         sys.maxsize-2)
         self.checkequal(['a|b|c|d'], 'a|b|c|d', 'split', '|', 0)
         self.checkequal(['a', '', 'b||c||d'], 'a||b||c||d', 'split', '|', 2)
+        self.checkequal(['abcd'], 'abcd', 'split', '|')
+        self.checkequal([''], '', 'split', '|')
         self.checkequal(['endcase ', ''], 'endcase |', 'split', '|')
         self.checkequal(['', ' startcase'], '| startcase', 'split', '|')
         self.checkequal(['', 'bothcase', ''], '|bothcase|', 'split', '|')
@@ -432,6 +437,8 @@ class BaseTest:
                         sys.maxsize-100)
         self.checkequal(['a|b|c|d'], 'a|b|c|d', 'rsplit', '|', 0)
         self.checkequal(['a||b||c', '', 'd'], 'a||b||c||d', 'rsplit', '|', 2)
+        self.checkequal(['abcd'], 'abcd', 'rsplit', '|')
+        self.checkequal([''], '', 'rsplit', '|')
         self.checkequal(['', ' begincase'], '| begincase', 'rsplit', '|')
         self.checkequal(['endcase ', ''], 'endcase |', 'rsplit', '|')
         self.checkequal(['', 'bothcase', ''], '|bothcase|', 'rsplit', '|')
@@ -638,14 +645,6 @@ class BaseTest:
         EQ("bobobXbobob", "bobobobXbobobob", "replace", "bobob", "bob")
         EQ("BOBOBOB", "BOBOBOB", "replace", "bob", "bobby")
 
-        # XXX Commented out. Is there any reason to support buffer objects
-        # as arguments for str.replace()?  GvR
-##         ba = bytearray('a')
-##         bb = bytearray('b')
-##         EQ("bbc", "abc", "replace", ba, bb)
-##         EQ("aac", "abc", "replace", bb, ba)
-
-        #
         self.checkequal('one@two!three!', 'one!two!three!', 'replace', '!', '@', 1)
         self.checkequal('onetwothree', 'one!two!three!', 'replace', '!', '')
         self.checkequal('one@two@three!', 'one!two!three!', 'replace', '!', '@', 2)
@@ -682,22 +681,6 @@ class BaseTest:
         self.checkraises(OverflowError, A2_16, "replace", "A", A2_16)
         self.checkraises(OverflowError, A2_16, "replace", "AA", A2_16+A2_16)
 
-
-
-class CommonTest(BaseTest):
-    # This testcase contains test that can be used in all
-    # stringlike classes. Currently this is str, unicode
-    # UserString and the string module.
-
-    def test_hash(self):
-        # SF bug 1054139:  += optimization was not invalidating cached hash value
-        a = self.type2test('DNSSEC')
-        b = self.type2test('')
-        for c in a:
-            b += c
-            hash(b)
-        self.assertEqual(hash(a), hash(b))
-
     def test_capitalize(self):
         self.checkequal(' hello ', ' hello ', 'capitalize')
         self.checkequal('Hello ', 'Hello ','capitalize')
@@ -705,23 +688,6 @@ class CommonTest(BaseTest):
         self.checkequal('Aaaa', 'aaaa', 'capitalize')
         self.checkequal('Aaaa', 'AaAa', 'capitalize')
 
-        # check that titlecased chars are lowered correctly
-        # \u1ffc is the titlecased char
-        self.checkequal('\u03a9\u0399\u1ff3\u1ff3\u1ff3',
-                        '\u1ff3\u1ff3\u1ffc\u1ffc', 'capitalize')
-        # check with cased non-letter chars
-        self.checkequal('\u24c5\u24e8\u24e3\u24d7\u24de\u24dd',
-                        '\u24c5\u24ce\u24c9\u24bd\u24c4\u24c3', 'capitalize')
-        self.checkequal('\u24c5\u24e8\u24e3\u24d7\u24de\u24dd',
-                        '\u24df\u24e8\u24e3\u24d7\u24de\u24dd', 'capitalize')
-        self.checkequal('\u2160\u2171\u2172',
-                        '\u2160\u2161\u2162', 'capitalize')
-        self.checkequal('\u2160\u2171\u2172',
-                        '\u2170\u2171\u2172', 'capitalize')
-        # check with Ll chars with no upper - nothing changes here
-        self.checkequal('\u019b\u1d00\u1d86\u0221\u1fb7',
-                        '\u019b\u1d00\u1d86\u0221\u1fb7', 'capitalize')
-
         self.checkraises(TypeError, 'hello', 'capitalize', 42)
 
     def test_additional_split(self):
@@ -744,16 +710,21 @@ class CommonTest(BaseTest):
         self.checkequal(['a'], '  a    ', 'split')
         self.checkequal(['a', 'b'], '  a    b   ', 'split')
         self.checkequal(['a', 'b   '], '  a    b   ', 'split', None, 1)
+        self.checkequal(['a    b   c   '], '  a    b   c   ', 'split', None, 0)
         self.checkequal(['a', 'b   c   '], '  a    b   c   ', 'split', None, 1)
         self.checkequal(['a', 'b', 'c   '], '  a    b   c   ', 'split', None, 2)
+        self.checkequal(['a', 'b', 'c'], '  a    b   c   ', 'split', None, 3)
         self.checkequal(['a', 'b'], '\n\ta \t\r b \v ', 'split')
         aaa = ' a '*20
         self.checkequal(['a']*20, aaa, 'split')
         self.checkequal(['a'] + [aaa[4:]], aaa, 'split', None, 1)
         self.checkequal(['a']*19 + ['a '], aaa, 'split', None, 19)
 
-        # mixed use of str and unicode
-        self.checkequal(['a', 'b', 'c d'], 'a b c d', 'split', ' ', 2)
+        for b in ('arf\tbarf', 'arf\nbarf', 'arf\rbarf',
+                  'arf\fbarf', 'arf\vbarf'):
+            self.checkequal(['arf', 'barf'], b, 'split')
+            self.checkequal(['arf', 'barf'], b, 'split', None)
+            self.checkequal(['arf', 'barf'], b, 'split', None, 2)
 
     def test_additional_rsplit(self):
         self.checkequal(['this', 'is', 'the', 'rsplit', 'function'],
@@ -775,36 +746,53 @@ class CommonTest(BaseTest):
         self.checkequal(['a'], '  a    ', 'rsplit')
         self.checkequal(['a', 'b'], '  a    b   ', 'rsplit')
         self.checkequal(['  a', 'b'], '  a    b   ', 'rsplit', None, 1)
+        self.checkequal(['  a    b   c'], '  a    b   c   ', 'rsplit',
+                        None, 0)
         self.checkequal(['  a    b','c'], '  a    b   c   ', 'rsplit',
                         None, 1)
         self.checkequal(['  a', 'b', 'c'], '  a    b   c   ', 'rsplit',
                         None, 2)
+        self.checkequal(['a', 'b', 'c'], '  a    b   c   ', 'rsplit',
+                        None, 3)
         self.checkequal(['a', 'b'], '\n\ta \t\r b \v ', 'rsplit', None, 88)
         aaa = ' a '*20
         self.checkequal(['a']*20, aaa, 'rsplit')
         self.checkequal([aaa[:-4]] + ['a'], aaa, 'rsplit', None, 1)
         self.checkequal([' a  a'] + ['a']*18, aaa, 'rsplit', None, 18)
 
-        # mixed use of str and unicode
-        self.checkequal(['a b', 'c', 'd'], 'a b c d', 'rsplit', ' ', 2)
+        for b in ('arf\tbarf', 'arf\nbarf', 'arf\rbarf',
+                  'arf\fbarf', 'arf\vbarf'):
+            self.checkequal(['arf', 'barf'], b, 'rsplit')
+            self.checkequal(['arf', 'barf'], b, 'rsplit', None)
+            self.checkequal(['arf', 'barf'], b, 'rsplit', None, 2)
 
-    def test_strip(self):
+    def test_strip_whitespace(self):
         self.checkequal('hello', '   hello   ', 'strip')
         self.checkequal('hello   ', '   hello   ', 'lstrip')
         self.checkequal('   hello', '   hello   ', 'rstrip')
         self.checkequal('hello', 'hello', 'strip')
 
+        b = ' \t\n\r\f\vabc \t\n\r\f\v'
+        self.checkequal('abc', b, 'strip')
+        self.checkequal('abc \t\n\r\f\v', b, 'lstrip')
+        self.checkequal(' \t\n\r\f\vabc', b, 'rstrip')
+
         # strip/lstrip/rstrip with None arg
         self.checkequal('hello', '   hello   ', 'strip', None)
         self.checkequal('hello   ', '   hello   ', 'lstrip', None)
         self.checkequal('   hello', '   hello   ', 'rstrip', None)
         self.checkequal('hello', 'hello', 'strip', None)
 
+    def test_strip(self):
         # strip/lstrip/rstrip with str arg
         self.checkequal('hello', 'xyzzyhelloxyzzy', 'strip', 'xyz')
         self.checkequal('helloxyzzy', 'xyzzyhelloxyzzy', 'lstrip', 'xyz')
         self.checkequal('xyzzyhello', 'xyzzyhelloxyzzy', 'rstrip', 'xyz')
         self.checkequal('hello', 'hello', 'strip', 'xyz')
+        self.checkequal('', 'mississippi', 'strip', 'mississippi')
+
+        # only trim the start and end; does not strip internal characters
+        self.checkequal('mississipp', 'mississippi', 'strip', 'i')
 
         self.checkraises(TypeError, 'hello', 'strip', 42, 42)
         self.checkraises(TypeError, 'hello', 'lstrip', 42, 42)
@@ -855,11 +843,6 @@ class CommonTest(BaseTest):
 
         self.checkraises(TypeError, '123', 'zfill')
 
-class MixinStrUnicodeUserStringTest:
-    # additional tests that only work for
-    # stringlike objects, i.e. str, unicode, UserString
-    # (but not the string module)
-
     def test_islower(self):
         self.checkequal(False, '', 'islower')
         self.checkequal(True, 'a', 'islower')
@@ -962,6 +945,43 @@ class MixinStrUnicodeUserStringTest:
 
         self.checkraises(TypeError, 'abc', 'splitlines', 42, 42)
 
+
+class CommonTest(BaseTest):
+    # This testcase contains tests that can be used in all
+    # stringlike classes. Currently this is str and UserString.
+
+    def test_hash(self):
+        # SF bug 1054139:  += optimization was not invalidating cached hash value
+        a = self.type2test('DNSSEC')
+        b = self.type2test('')
+        for c in a:
+            b += c
+            hash(b)
+        self.assertEqual(hash(a), hash(b))
+
+    def test_capitalize_nonascii(self):
+        # check that titlecased chars are lowered correctly
+        # \u1ffc is the titlecased char
+        self.checkequal('\u03a9\u0399\u1ff3\u1ff3\u1ff3',
+                        '\u1ff3\u1ff3\u1ffc\u1ffc', 'capitalize')
+        # check with cased non-letter chars
+        self.checkequal('\u24c5\u24e8\u24e3\u24d7\u24de\u24dd',
+                        '\u24c5\u24ce\u24c9\u24bd\u24c4\u24c3', 'capitalize')
+        self.checkequal('\u24c5\u24e8\u24e3\u24d7\u24de\u24dd',
+                        '\u24df\u24e8\u24e3\u24d7\u24de\u24dd', 'capitalize')
+        self.checkequal('\u2160\u2171\u2172',
+                        '\u2160\u2161\u2162', 'capitalize')
+        self.checkequal('\u2160\u2171\u2172',
+                        '\u2170\u2171\u2172', 'capitalize')
+        # check with Ll chars with no upper - nothing changes here
+        self.checkequal('\u019b\u1d00\u1d86\u0221\u1fb7',
+                        '\u019b\u1d00\u1d86\u0221\u1fb7', 'capitalize')
+
+
+class MixinStrUnicodeUserStringTest:
+    # additional tests that only work for
+    # stringlike objects, i.e. str, UserString
+
     def test_startswith(self):
         self.checkequal(True, 'hello', 'startswith', 'he')
         self.checkequal(True, 'hello', 'startswith', 'hello')
@@ -1343,7 +1363,7 @@ class MixinStrUnicodeUserStringTest:
 
 
 class MixinStrUnicodeTest:
-    # Additional tests that only work with str and unicode.
+    # Additional tests that only work with str.
 
     def test_bug1001011(self):
         # Make sure join returns a NEW object for single item sequences
@@ -1361,28 +1381,3 @@ class MixinStrUnicodeTest:
         s1 = t("abcd")
         s2 = t().join([s1])
         self.assertIs(s1, s2)
-
-        # Should also test mixed-type join.
-        if t is str:
-            s1 = subclass("abcd")
-            s2 = "".join([s1])
-            self.assertIsNot(s1, s2)
-            self.assertIs(type(s2), t)
-
-            s1 = t("abcd")
-            s2 = "".join([s1])
-            self.assertIs(s1, s2)
-
-##         elif t is str8:
-##             s1 = subclass("abcd")
-##             s2 = "".join([s1])
-##             self.assertIsNot(s1, s2)
-##             self.assertIs(type(s2), str) # promotes!
-
-##             s1 = t("abcd")
-##             s2 = "".join([s1])
-##             self.assertIsNot(s1, s2)
-##             self.assertIs(type(s2), str) # promotes!
-
-        else:
-            self.fail("unexpected type for MixinStrUnicodeTest %r" % t)
index dfb4c25..e124fab 100644 (file)
@@ -100,7 +100,8 @@ __all__ = [
     # threads
     "threading_setup", "threading_cleanup", "reap_threads", "start_threads",
     # miscellaneous
-    "check_warnings", "EnvironmentVarGuard", "run_with_locale", "swap_item",
+    "check_warnings", "check_no_resource_warning", "EnvironmentVarGuard",
+    "run_with_locale", "swap_item",
     "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict",
     "run_with_tz",
     ]
@@ -1147,6 +1148,27 @@ def check_warnings(*filters, **kwargs):
     return _filterwarnings(filters, quiet)
 
 
+@contextlib.contextmanager
+def check_no_resource_warning(testcase):
+    """Context manager to check that no ResourceWarning is emitted.
+
+    Usage:
+
+        with check_no_resource_warning(self):
+            f = open(...)
+            ...
+            del f
+
+    You must remove the object which may emit ResourceWarning before
+    the end of the context manager.
+    """
+    with warnings.catch_warnings(record=True) as warns:
+        warnings.filterwarnings('always', category=ResourceWarning)
+        yield
+        gc_collect()
+    testcase.assertEqual(warns, [])
+
+
 class CleanImport(object):
     """Context manager to force import to return a new module reference.
 
@@ -2344,3 +2366,22 @@ def run_in_subinterp(code):
                                      "memory allocations")
     import _testcapi
     return _testcapi.run_in_subinterp(code)
+
+
+def check_free_after_iterating(test, iter, cls, args=()):
+    class A(cls):
+        def __del__(self):
+            nonlocal done
+            done = True
+            try:
+                next(it)
+            except StopIteration:
+                pass
+
+    done = False
+    it = iter(A(*args))
+    # Issue 26494: Shouldn't crash
+    test.assertRaises(StopIteration, next, it)
+    # The sequence should be deallocated just after the end of iterating
+    gc_collect()
+    test.assertTrue(done)
index 584b0e8..9c2e9eb 100644 (file)
@@ -127,7 +127,7 @@ def assert_python_ok(*args, **env_vars):
     variables `env_vars` succeeds (rc == 0) and return a (return code, stdout,
     stderr) tuple.
 
-    If the __cleanenv keyword is set, env_vars is used a fresh environment.
+    If the __cleanenv keyword is set, env_vars is used as a fresh environment.
 
     Python is started in isolated mode (command line option -I),
     except if the __isolated keyword is set to False.
index d95d3a4..58f2f04 100644 (file)
@@ -67,7 +67,9 @@ def setUpModule():
 known_numerics = {
     'en_US': ('.', ','),
     'de_DE' : (',', '.'),
-    'fr_FR.UTF-8' : (',', ' '),
+    # The French thousands separator may be a breaking or non-breaking space
+    # depending on the platform, so do not test it
+    'fr_FR' : (',', ''),
     'ps_AF': ('\u066b', '\u066c'),
 }
 
index f48e85c..f9ee398 100644 (file)
@@ -534,7 +534,7 @@ class TestOptionalsNargsDefault(ParserTestCase):
 
 
 class TestOptionalsNargs1(ParserTestCase):
-    """Tests specifying the 1 arg for an Optional"""
+    """Tests specifying 1 arg for an Optional"""
 
     argument_signatures = [Sig('-x', nargs=1)]
     failures = ['a', '-x']
@@ -545,7 +545,7 @@ class TestOptionalsNargs1(ParserTestCase):
 
 
 class TestOptionalsNargs3(ParserTestCase):
-    """Tests specifying the 3 args for an Optional"""
+    """Tests specifying 3 args for an Optional"""
 
     argument_signatures = [Sig('-x', nargs=3)]
     failures = ['a', '-x', '-x a', '-x a b', 'a -x', 'a -x b']
@@ -579,7 +579,7 @@ class TestOptionalsNargsOptional(ParserTestCase):
 
 
 class TestOptionalsNargsZeroOrMore(ParserTestCase):
-    """Tests specifying an args for an Optional that accepts zero or more"""
+    """Tests specifying args for an Optional that accepts zero or more"""
 
     argument_signatures = [
         Sig('-x', nargs='*'),
@@ -598,7 +598,7 @@ class TestOptionalsNargsZeroOrMore(ParserTestCase):
 
 
 class TestOptionalsNargsOneOrMore(ParserTestCase):
-    """Tests specifying an args for an Optional that accepts one or more"""
+    """Tests specifying args for an Optional that accepts one or more"""
 
     argument_signatures = [
         Sig('-x', nargs='+'),
@@ -1251,7 +1251,7 @@ class TestPrefixCharacterOnlyArguments(ParserTestCase):
 
 
 class TestNargsZeroOrMore(ParserTestCase):
-    """Tests specifying an args for an Optional that accepts zero or more"""
+    """Tests specifying args for an Optional that accepts zero or more"""
 
     argument_signatures = [Sig('-x', nargs='*'), Sig('y', nargs='*')]
     failures = []
index 10d9946..482526e 100644 (file)
@@ -284,19 +284,42 @@ class BaseTest:
             self.assertEqual(type(a), type(b))
 
     def test_iterator_pickle(self):
-        data = array.array(self.typecode, self.example)
+        orig = array.array(self.typecode, self.example)
+        data = list(orig)
+        data2 = data[::-1]
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
-            orgit = iter(data)
-            d = pickle.dumps(orgit, proto)
-            it = pickle.loads(d)
-            self.assertEqual(type(orgit), type(it))
-            self.assertEqual(list(it), list(data))
-
-            if len(data):
-                it = pickle.loads(d)
-                next(it)
-                d = pickle.dumps(it, proto)
-                self.assertEqual(list(it), list(data)[1:])
+            # initial iterator
+            itorig = iter(orig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a.fromlist(data2)
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data + data2)
+
+            # running iterator
+            next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a.fromlist(data2)
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data[1:] + data2)
+
+            # empty iterator
+            for i in range(1, len(data)):
+                next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a.fromlist(data2)
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data2)
+
+            # exhausted iterator
+            self.assertRaises(StopIteration, next, itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a.fromlist(data2)
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data2)
 
     def test_insert(self):
         a = array.array(self.typecode, self.example)
index 072fe2f..0807dfb 100644 (file)
@@ -32,6 +32,145 @@ MOCK_ANY = mock.ANY
 PY34 = sys.version_info >= (3, 4)
 
 
+def mock_socket_module():
+    m_socket = mock.MagicMock(spec=socket)
+    for name in (
+        'AF_INET', 'AF_INET6', 'AF_UNSPEC', 'IPPROTO_TCP', 'IPPROTO_UDP',
+        'SOCK_STREAM', 'SOCK_DGRAM', 'SOL_SOCKET', 'SO_REUSEADDR', 'inet_pton'
+    ):
+        if hasattr(socket, name):
+            setattr(m_socket, name, getattr(socket, name))
+        else:
+            delattr(m_socket, name)
+
+    m_socket.socket = mock.MagicMock()
+    m_socket.socket.return_value = test_utils.mock_nonblocking_socket()
+    m_socket.getaddrinfo._is_coroutine = False
+
+    return m_socket
+
+
+def patch_socket(f):
+    return mock.patch('asyncio.base_events.socket',
+                      new_callable=mock_socket_module)(f)
+
+
+class BaseEventTests(test_utils.TestCase):
+
+    def test_ipaddr_info(self):
+        UNSPEC = socket.AF_UNSPEC
+        INET = socket.AF_INET
+        INET6 = socket.AF_INET6
+        STREAM = socket.SOCK_STREAM
+        DGRAM = socket.SOCK_DGRAM
+        TCP = socket.IPPROTO_TCP
+        UDP = socket.IPPROTO_UDP
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 1)),
+            base_events._ipaddr_info('1.2.3.4', 1, INET, STREAM, TCP))
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 1)),
+            base_events._ipaddr_info(b'1.2.3.4', 1, INET, STREAM, TCP))
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 1)),
+            base_events._ipaddr_info('1.2.3.4', 1, UNSPEC, STREAM, TCP))
+
+        self.assertEqual(
+            (INET, DGRAM, UDP, '', ('1.2.3.4', 1)),
+            base_events._ipaddr_info('1.2.3.4', 1, UNSPEC, DGRAM, UDP))
+
+        # Socket type STREAM implies TCP protocol.
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 1)),
+            base_events._ipaddr_info('1.2.3.4', 1, UNSPEC, STREAM, 0))
+
+        # Socket type DGRAM implies UDP protocol.
+        self.assertEqual(
+            (INET, DGRAM, UDP, '', ('1.2.3.4', 1)),
+            base_events._ipaddr_info('1.2.3.4', 1, UNSPEC, DGRAM, 0))
+
+        # No socket type.
+        self.assertIsNone(
+            base_events._ipaddr_info('1.2.3.4', 1, UNSPEC, 0, 0))
+
+        # IPv4 address with family IPv6.
+        self.assertIsNone(
+            base_events._ipaddr_info('1.2.3.4', 1, INET6, STREAM, TCP))
+
+        self.assertEqual(
+            (INET6, STREAM, TCP, '', ('::3', 1)),
+            base_events._ipaddr_info('::3', 1, INET6, STREAM, TCP))
+
+        self.assertEqual(
+            (INET6, STREAM, TCP, '', ('::3', 1)),
+            base_events._ipaddr_info('::3', 1, UNSPEC, STREAM, TCP))
+
+        # IPv6 address with family IPv4.
+        self.assertIsNone(
+            base_events._ipaddr_info('::3', 1, INET, STREAM, TCP))
+
+        # IPv6 address with zone index.
+        self.assertIsNone(
+            base_events._ipaddr_info('::3%lo0', 1, INET6, STREAM, TCP))
+
+    def test_port_parameter_types(self):
+        # Test obscure kinds of arguments for "port".
+        INET = socket.AF_INET
+        STREAM = socket.SOCK_STREAM
+        TCP = socket.IPPROTO_TCP
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 0)),
+            base_events._ipaddr_info('1.2.3.4', None, INET, STREAM, TCP))
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 0)),
+            base_events._ipaddr_info('1.2.3.4', b'', INET, STREAM, TCP))
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 0)),
+            base_events._ipaddr_info('1.2.3.4', '', INET, STREAM, TCP))
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 1)),
+            base_events._ipaddr_info('1.2.3.4', '1', INET, STREAM, TCP))
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 1)),
+            base_events._ipaddr_info('1.2.3.4', b'1', INET, STREAM, TCP))
+
+    def test_getaddrinfo_servname(self):
+        INET = socket.AF_INET
+        STREAM = socket.SOCK_STREAM
+        TCP = socket.IPPROTO_TCP
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 80)),
+            base_events._ipaddr_info('1.2.3.4', 'http', INET, STREAM, TCP))
+
+        self.assertEqual(
+            (INET, STREAM, TCP, '', ('1.2.3.4', 80)),
+            base_events._ipaddr_info('1.2.3.4', b'http', INET, STREAM, TCP))
+
+        # Raises "service/proto not found".
+        with self.assertRaises(OSError):
+            base_events._ipaddr_info('1.2.3.4', 'nonsense', INET, STREAM, TCP)
+
+        with self.assertRaises(OSError):
+            base_events._ipaddr_info('1.2.3.4', 'nonsense', INET, STREAM, TCP)
+
+    @patch_socket
+    def test_ipaddr_info_no_inet_pton(self, m_socket):
+        del m_socket.inet_pton
+        self.assertIsNone(base_events._ipaddr_info('1.2.3.4', 1,
+                                                   socket.AF_INET,
+                                                   socket.SOCK_STREAM,
+                                                   socket.IPPROTO_TCP))
+
+
 class BaseEventLoopTests(test_utils.TestCase):
 
     def setUp(self):
@@ -510,6 +649,7 @@ class BaseEventLoopTests(test_utils.TestCase):
             fut.add_done_callback(lambda *args: self.loop.stop())
             self.loop.run_forever()
             fut = None # Trigger Future.__del__ or futures._TracebackLogger
+            support.gc_collect()
             if PY34:
                 # Future.__del__ in Python 3.4 logs error with
                 # an actual exception context
@@ -539,8 +679,10 @@ class BaseEventLoopTests(test_utils.TestCase):
         self.loop.set_debug(True)
         self.loop._process_events = mock.Mock()
 
+        self.assertIsNone(self.loop.get_exception_handler())
         mock_handler = mock.Mock()
         self.loop.set_exception_handler(mock_handler)
+        self.assertIs(self.loop.get_exception_handler(), mock_handler)
         handle = run_loop()
         mock_handler.assert_called_with(self.loop, {
             'exception': MOCK_ANY,
@@ -875,7 +1017,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         self.loop = asyncio.new_event_loop()
         self.set_event_loop(self.loop)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_connection_multiple_errors(self, m_socket):
 
         class MyProto(asyncio.Protocol):
@@ -908,7 +1050,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
 
         self.assertEqual(str(cm.exception), 'Multiple exceptions: err1, err2')
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_connection_timeout(self, m_socket):
         # Ensure that the socket is closed on timeout
         sock = mock.Mock()
@@ -986,7 +1128,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         with self.assertRaises(OSError):
             self.loop.run_until_complete(coro)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_connection_multiple_errors_local_addr(self, m_socket):
 
         def bind(addr):
@@ -1018,6 +1160,55 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         self.assertTrue(str(cm.exception).startswith('Multiple exceptions: '))
         self.assertTrue(m_socket.socket.return_value.close.called)
 
+    def _test_create_connection_ip_addr(self, m_socket, allow_inet_pton):
+        # Test the fallback code, even if this system has inet_pton.
+        if not allow_inet_pton:
+            del m_socket.inet_pton
+
+        m_socket.getaddrinfo = socket.getaddrinfo
+        sock = m_socket.socket.return_value
+
+        self.loop.add_reader = mock.Mock()
+        self.loop.add_reader._is_coroutine = False
+        self.loop.add_writer = mock.Mock()
+        self.loop.add_writer._is_coroutine = False
+
+        coro = self.loop.create_connection(asyncio.Protocol, '1.2.3.4', 80)
+        t, p = self.loop.run_until_complete(coro)
+        try:
+            sock.connect.assert_called_with(('1.2.3.4', 80))
+            _, kwargs = m_socket.socket.call_args
+            self.assertEqual(kwargs['family'], m_socket.AF_INET)
+            self.assertEqual(kwargs['type'], m_socket.SOCK_STREAM)
+        finally:
+            t.close()
+            test_utils.run_briefly(self.loop)  # allow transport to close
+
+        sock.family = socket.AF_INET6
+        coro = self.loop.create_connection(asyncio.Protocol, '::2', 80)
+        t, p = self.loop.run_until_complete(coro)
+        try:
+            # Without inet_pton we use getaddrinfo, which transforms ('::2', 80)
+            # to ('::0.0.0.2', 80, 0, 0). The last 0s are flow info, scope id.
+            [address] = sock.connect.call_args[0]
+            host, port = address[:2]
+            self.assertRegex(host, r'::(0\.)*2')
+            self.assertEqual(port, 80)
+            _, kwargs = m_socket.socket.call_args
+            self.assertEqual(kwargs['family'], m_socket.AF_INET6)
+            self.assertEqual(kwargs['type'], m_socket.SOCK_STREAM)
+        finally:
+            t.close()
+            test_utils.run_briefly(self.loop)  # allow transport to close
+
+    @patch_socket
+    def test_create_connection_ip_addr(self, m_socket):
+        self._test_create_connection_ip_addr(m_socket, True)
+
+    @patch_socket
+    def test_create_connection_no_inet_pton(self, m_socket):
+        self._test_create_connection_ip_addr(m_socket, False)
+
     def test_create_connection_no_local_addr(self):
         @asyncio.coroutine
         def getaddrinfo(host, *args, **kw):
@@ -1037,6 +1228,21 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         self.assertRaises(
             OSError, self.loop.run_until_complete, coro)
 
+    @patch_socket
+    def test_create_connection_bluetooth(self, m_socket):
+        # See http://bugs.python.org/issue27136, fallback to getaddrinfo when
+        # we can't recognize an address is resolved, e.g. a Bluetooth address.
+        addr = ('00:01:02:03:04:05', 1)
+
+        def getaddrinfo(host, port, *args, **kw):
+            assert (host, port) == addr
+            return [(999, 1, 999, '', (addr, 1))]
+
+        m_socket.getaddrinfo = getaddrinfo
+        sock = m_socket.socket()
+        coro = self.loop.sock_connect(sock, addr)
+        self.loop.run_until_complete(coro)
+
     def test_create_connection_ssl_server_hostname_default(self):
         self.loop.getaddrinfo = mock.Mock()
 
@@ -1150,14 +1356,12 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         getaddrinfo = self.loop.getaddrinfo = mock.Mock()
         getaddrinfo.return_value = []
 
-        f = self.loop.create_server(MyProto, '0.0.0.0', 0)
+        f = self.loop.create_server(MyProto, 'python.org', 0)
         self.assertRaises(OSError, self.loop.run_until_complete, f)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_server_nosoreuseport(self, m_socket):
         m_socket.getaddrinfo = socket.getaddrinfo
-        m_socket.SOCK_STREAM = socket.SOCK_STREAM
-        m_socket.SOL_SOCKET = socket.SOL_SOCKET
         del m_socket.SO_REUSEPORT
         m_socket.socket.return_value = mock.Mock()
 
@@ -1166,7 +1370,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
 
         self.assertRaises(ValueError, self.loop.run_until_complete, f)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_server_cant_bind(self, m_socket):
 
         class Err(OSError):
@@ -1182,7 +1386,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         self.assertRaises(OSError, self.loop.run_until_complete, fut)
         self.assertTrue(m_sock.close.called)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_datagram_endpoint_no_addrinfo(self, m_socket):
         m_socket.getaddrinfo.return_value = []
         m_socket.getaddrinfo._is_coroutine = False
@@ -1211,7 +1415,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         self.assertRaises(
             OSError, self.loop.run_until_complete, coro)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_datagram_endpoint_socket_err(self, m_socket):
         m_socket.getaddrinfo = socket.getaddrinfo
         m_socket.socket.side_effect = OSError
@@ -1234,7 +1438,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         self.assertRaises(
             ValueError, self.loop.run_until_complete, coro)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_datagram_endpoint_setblk_err(self, m_socket):
         m_socket.socket.return_value.setblocking.side_effect = OSError
 
@@ -1250,12 +1454,11 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
             asyncio.DatagramProtocol)
         self.assertRaises(ValueError, self.loop.run_until_complete, coro)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_datagram_endpoint_cant_bind(self, m_socket):
         class Err(OSError):
             pass
 
-        m_socket.AF_INET6 = socket.AF_INET6
         m_socket.getaddrinfo = socket.getaddrinfo
         m_sock = m_socket.socket.return_value = mock.Mock()
         m_sock.bind.side_effect = Err
@@ -1369,11 +1572,8 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
         self.loop.run_until_complete(protocol.done)
         self.assertEqual('CLOSED', protocol.state)
 
-    @mock.patch('asyncio.base_events.socket')
+    @patch_socket
     def test_create_datagram_endpoint_nosoreuseport(self, m_socket):
-        m_socket.getaddrinfo = socket.getaddrinfo
-        m_socket.SOCK_DGRAM = socket.SOCK_DGRAM
-        m_socket.SOL_SOCKET = socket.SOL_SOCKET
         del m_socket.SO_REUSEPORT
         m_socket.socket.return_value = mock.Mock()
 
@@ -1385,6 +1585,33 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
 
         self.assertRaises(ValueError, self.loop.run_until_complete, coro)
 
+    @patch_socket
+    def test_create_datagram_endpoint_ip_addr(self, m_socket):
+        def getaddrinfo(*args, **kw):
+            self.fail('should not have called getaddrinfo')
+
+        m_socket.getaddrinfo = getaddrinfo
+        m_socket.socket.return_value.bind = bind = mock.Mock()
+        self.loop.add_reader = mock.Mock()
+        self.loop.add_reader._is_coroutine = False
+
+        reuseport_supported = hasattr(socket, 'SO_REUSEPORT')
+        coro = self.loop.create_datagram_endpoint(
+            lambda: MyDatagramProto(loop=self.loop),
+            local_addr=('1.2.3.4', 0),
+            reuse_address=False,
+            reuse_port=reuseport_supported)
+
+        t, p = self.loop.run_until_complete(coro)
+        try:
+            bind.assert_called_with(('1.2.3.4', 0))
+            m_socket.socket.assert_called_with(family=m_socket.AF_INET,
+                                               proto=m_socket.IPPROTO_UDP,
+                                               type=m_socket.SOCK_DGRAM)
+        finally:
+            t.close()
+            test_utils.run_briefly(self.loop)  # allow transport to close
+
     def test_accept_connection_retry(self):
         sock = mock.Mock()
         sock.accept.side_effect = BlockingIOError()
index 141fde7..d077775 100644 (file)
@@ -749,34 +749,37 @@ class EventLoopTestsMixin:
         @asyncio.coroutine
         def getaddrinfo(host, port, *args, **kw):
             if family == socket.AF_INET:
-                return [[family, socket.SOCK_STREAM, 6, '', (host, port)]]
+                return [(family, socket.SOCK_STREAM, 6, '', (host, port))]
             else:
-                return [[family, socket.SOCK_STREAM, 6, '', (host, port, 0, 0)]]
+                return [(family, socket.SOCK_STREAM, 6, '', (host, port, 0, 0))]
 
         def getaddrinfo_task(*args, **kwds):
             return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
 
+        unique_hosts = set(hosts)
+
         if family == socket.AF_INET:
-            mock_sock.socket().getsockbyname.side_effect = [(host, 80)
-                                                            for host in hosts]
+            mock_sock.socket().getsockbyname.side_effect = [
+                (host, 80) for host in unique_hosts]
         else:
-            mock_sock.socket().getsockbyname.side_effect = [(host, 80, 0, 0)
-                                                            for host in hosts]
+            mock_sock.socket().getsockbyname.side_effect = [
+                (host, 80, 0, 0) for host in unique_hosts]
         self.loop.getaddrinfo = getaddrinfo_task
         self.loop._start_serving = mock.Mock()
         self.loop._stop_serving = mock.Mock()
         f = self.loop.create_server(lambda: MyProto(self.loop), hosts, 80)
         server = self.loop.run_until_complete(f)
         self.addCleanup(server.close)
-        server_hosts = [sock.getsockbyname()[0] for sock in server.sockets]
-        self.assertEqual(server_hosts, hosts)
+        server_hosts = {sock.getsockbyname()[0] for sock in server.sockets}
+        self.assertEqual(server_hosts, unique_hosts)
 
     def test_create_server_multiple_hosts_ipv4(self):
         self.create_server_multiple_hosts(socket.AF_INET,
-                                          ['1.2.3.4', '5.6.7.8'])
+                                          ['1.2.3.4', '5.6.7.8', '1.2.3.4'])
 
     def test_create_server_multiple_hosts_ipv6(self):
-        self.create_server_multiple_hosts(socket.AF_INET6, ['::1', '::2'])
+        self.create_server_multiple_hosts(socket.AF_INET6,
+                                          ['::1', '::2', '::1'])
 
     def test_create_server(self):
         proto = MyProto(self.loop)
@@ -999,7 +1002,7 @@ class EventLoopTestsMixin:
         with mock.patch.object(self.loop, 'call_exception_handler'):
             with test_utils.disable_logger():
                 with self.assertRaisesRegex(ssl.SSLError,
-                                            'certificate verify failed '):
+                                            '(?i)certificate.verify.failed'):
                     self.loop.run_until_complete(f_c)
 
             # execute the loop to log the connection error
@@ -1033,7 +1036,7 @@ class EventLoopTestsMixin:
         with mock.patch.object(self.loop, 'call_exception_handler'):
             with test_utils.disable_logger():
                 with self.assertRaisesRegex(ssl.SSLError,
-                                            'certificate verify failed '):
+                                            '(?i)certificate.verify.failed'):
                     self.loop.run_until_complete(f_c)
 
             # execute the loop to log the connection error
@@ -1365,6 +1368,41 @@ class EventLoopTestsMixin:
 
     @unittest.skipUnless(sys.platform != 'win32',
                          "Don't support pipes for Windows")
+    def test_unclosed_pipe_transport(self):
+        # This test reproduces the issue #314 on GitHub
+        loop = self.create_event_loop()
+        read_proto = MyReadPipeProto(loop=loop)
+        write_proto = MyWritePipeProto(loop=loop)
+
+        rpipe, wpipe = os.pipe()
+        rpipeobj = io.open(rpipe, 'rb', 1024)
+        wpipeobj = io.open(wpipe, 'w', 1024)
+
+        @asyncio.coroutine
+        def connect():
+            read_transport, _ = yield from loop.connect_read_pipe(
+                lambda: read_proto, rpipeobj)
+            write_transport, _ = yield from loop.connect_write_pipe(
+                lambda: write_proto, wpipeobj)
+            return read_transport, write_transport
+
+        # Run and close the loop without closing the transports
+        read_transport, write_transport = loop.run_until_complete(connect())
+        loop.close()
+
+        # These 'repr' calls used to raise an AttributeError
+        # See Issue #314 on GitHub
+        self.assertIn('open', repr(read_transport))
+        self.assertIn('open', repr(write_transport))
+
+        # Clean up (avoid ResourceWarning)
+        rpipeobj.close()
+        wpipeobj.close()
+        read_transport._pipe = None
+        write_transport._pipe = None
+
+    @unittest.skipUnless(sys.platform != 'win32',
+                         "Don't support pipes for Windows")
     # select, poll and kqueue don't support character devices (PTY) on Mac OS X
     # older than 10.6 (Snow Leopard)
     @support.requires_mac_ver(10, 6)
@@ -1572,29 +1610,6 @@ class EventLoopTestsMixin:
             {'clock_resolution': self.loop._clock_resolution,
              'selector': self.loop._selector.__class__.__name__})
 
-    def test_sock_connect_address(self):
-        # In debug mode, sock_connect() must ensure that the address is already
-        # resolved (call _check_resolved_address())
-        self.loop.set_debug(True)
-
-        addresses = [(socket.AF_INET, ('www.python.org', 80))]
-        if support.IPV6_ENABLED:
-            addresses.extend((
-                (socket.AF_INET6, ('www.python.org', 80)),
-                (socket.AF_INET6, ('www.python.org', 80, 0, 0)),
-            ))
-
-        for family, address in addresses:
-            for sock_type in (socket.SOCK_STREAM, socket.SOCK_DGRAM):
-                sock = socket.socket(family, sock_type)
-                with sock:
-                    sock.setblocking(False)
-                    connect = self.loop.sock_connect(sock, address)
-                    with self.assertRaises(ValueError) as cm:
-                        self.loop.run_until_complete(connect)
-                    self.assertIn('address must be resolved',
-                                  str(cm.exception))
-
     def test_remove_fds_after_closing(self):
         loop = self.create_event_loop()
         callback = lambda: None
index 55fdff3..c38c1f2 100644 (file)
@@ -76,6 +76,10 @@ class FutureTests(test_utils.TestCase):
         f = asyncio.Future(loop=self.loop)
         self.assertRaises(asyncio.InvalidStateError, f.exception)
 
+        # StopIteration cannot be raised into a Future - CPython issue26221
+        self.assertRaisesRegex(TypeError, "StopIteration .* cannot be raised",
+                               f.set_exception, StopIteration)
+
         f.set_exception(exc)
         self.assertFalse(f.cancelled())
         self.assertTrue(f.done())
@@ -238,6 +242,7 @@ class FutureTests(test_utils.TestCase):
         fut.set_exception(RuntimeError('boom'))
         del fut
         test_utils.run_briefly(self.loop)
+        support.gc_collect()
         self.assertTrue(m_log.error.called)
 
     @mock.patch('asyncio.base_events.logger')
@@ -273,14 +278,15 @@ class FutureTests(test_utils.TestCase):
         f2 = asyncio.wrap_future(f1)
         self.assertIs(f1, f2)
 
-    @mock.patch('asyncio.futures.events')
-    def test_wrap_future_use_global_loop(self, m_events):
-        def run(arg):
-            return (arg, threading.get_ident())
-        ex = concurrent.futures.ThreadPoolExecutor(1)
-        f1 = ex.submit(run, 'oi')
-        f2 = asyncio.wrap_future(f1)
-        self.assertIs(m_events.get_event_loop.return_value, f2._loop)
+    def test_wrap_future_use_global_loop(self):
+        with mock.patch('asyncio.futures.events') as events:
+            events.get_event_loop = lambda: self.loop
+            def run(arg):
+                return (arg, threading.get_ident())
+            ex = concurrent.futures.ThreadPoolExecutor(1)
+            f1 = ex.submit(run, 'oi')
+            f2 = asyncio.wrap_future(f1)
+            self.assertIs(self.loop, f2._loop)
 
     def test_wrap_future_cancel(self):
         f1 = concurrent.futures.Future()
index cdf5d9d..d3bdc51 100644 (file)
@@ -457,6 +457,31 @@ class ConditionTests(test_utils.TestCase):
         self.assertFalse(cond._waiters)
         self.assertTrue(cond.locked())
 
+    def test_wait_cancel_contested(self):
+        cond = asyncio.Condition(loop=self.loop)
+
+        self.loop.run_until_complete(cond.acquire())
+        self.assertTrue(cond.locked())
+
+        wait_task = asyncio.Task(cond.wait(), loop=self.loop)
+        test_utils.run_briefly(self.loop)
+        self.assertFalse(cond.locked())
+
+        # Notify, but contest the lock before cancelling
+        self.loop.run_until_complete(cond.acquire())
+        self.assertTrue(cond.locked())
+        cond.notify()
+        self.loop.call_soon(wait_task.cancel)
+        self.loop.call_soon(cond.release)
+
+        try:
+            self.loop.run_until_complete(wait_task)
+        except asyncio.CancelledError:
+            # Should not happen, since no cancellation points
+            pass
+
+        self.assertTrue(cond.locked())
+
     def test_wait_unacquired(self):
         cond = asyncio.Condition(loop=self.loop)
         self.assertRaises(
index 404a748..29aba81 100644 (file)
@@ -4,7 +4,10 @@ import collections.abc
 import types
 import unittest
 
-from test import support
+try:
+    from test import support
+except ImportError:
+    from asyncio import test_support as support
 from unittest import mock
 
 import asyncio
index 5a0f088..5a92b1e 100644 (file)
@@ -436,7 +436,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
 class BaseProactorEventLoopTests(test_utils.TestCase):
 
     def setUp(self):
-        self.sock = mock.Mock(socket.socket)
+        self.sock = test_utils.mock_nonblocking_socket()
         self.proactor = mock.Mock()
 
         self.ssock, self.csock = mock.Mock(), mock.Mock()
@@ -491,8 +491,8 @@ class BaseProactorEventLoopTests(test_utils.TestCase):
         self.proactor.send.assert_called_with(self.sock, b'data')
 
     def test_sock_connect(self):
-        self.loop.sock_connect(self.sock, 123)
-        self.proactor.connect.assert_called_with(self.sock, 123)
+        self.loop.sock_connect(self.sock, ('1.2.3.4', 123))
+        self.proactor.connect.assert_called_with(self.sock, ('1.2.3.4', 123))
 
     def test_sock_accept(self):
         self.loop.sock_accept(self.sock)
index 135b5ab..5dc6ff8 100644 (file)
@@ -343,9 +343,11 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
 
         f = self.loop.sock_connect(sock, ('127.0.0.1', 8080))
         self.assertIsInstance(f, asyncio.Future)
-        self.assertEqual(
-            (f, sock, ('127.0.0.1', 8080)),
-            self.loop._sock_connect.call_args[0])
+        self.loop._run_once()
+        future_in, sock_in, address_in = self.loop._sock_connect.call_args[0]
+        self.assertEqual(future_in, f)
+        self.assertEqual(sock_in, sock)
+        self.assertEqual(address_in, ('127.0.0.1', 8080))
 
     def test_sock_connect_timeout(self):
         # asyncio issue #205: sock_connect() must unregister the socket on
@@ -359,6 +361,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
 
         # first call to sock_connect() registers the socket
         fut = self.loop.sock_connect(sock, ('127.0.0.1', 80))
+        self.loop._run_once()
         self.assertTrue(sock.connect.called)
         self.assertTrue(self.loop.add_writer.called)
         self.assertEqual(len(fut._callbacks), 1)
@@ -376,7 +379,10 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock = mock.Mock()
         sock.fileno.return_value = 10
 
-        self.loop._sock_connect(f, sock, ('127.0.0.1', 8080))
+        resolved = self.loop.create_future()
+        resolved.set_result([(socket.AF_INET, socket.SOCK_STREAM,
+                              socket.IPPROTO_TCP, '', ('127.0.0.1', 8080))])
+        self.loop._sock_connect(f, sock, resolved)
         self.assertTrue(f.done())
         self.assertIsNone(f.result())
         self.assertTrue(sock.connect.called)
@@ -402,9 +408,13 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.connect.side_effect = BlockingIOError
         sock.getsockopt.return_value = 0
         address = ('127.0.0.1', 8080)
+        resolved = self.loop.create_future()
+        resolved.set_result([(socket.AF_INET, socket.SOCK_STREAM,
+                              socket.IPPROTO_TCP, '', address)])
 
         f = asyncio.Future(loop=self.loop)
-        self.loop._sock_connect(f, sock, address)
+        self.loop._sock_connect(f, sock, resolved)
+        self.loop._run_once()
         self.assertTrue(self.loop.add_writer.called)
         self.assertEqual(10, self.loop.add_writer.call_args[0][0])
 
@@ -1077,17 +1087,6 @@ class SelectorSocketTransportTests(test_utils.TestCase):
                                    err,
                                    'Fatal write error on socket transport')
 
-    @mock.patch('asyncio.base_events.logger')
-    def test_write_ready_exception_and_close(self, m_log):
-        self.sock.send.side_effect = OSError()
-        remove_writer = self.loop.remove_writer = mock.Mock()
-
-        transport = self.socket_transport()
-        transport.close()
-        transport._buffer.extend(b'data')
-        transport._write_ready()
-        remove_writer.assert_called_with(self.sock_fd)
-
     def test_write_eof(self):
         tr = self.socket_transport()
         self.assertTrue(tr.can_write_eof())
@@ -1111,6 +1110,14 @@ class SelectorSocketTransportTests(test_utils.TestCase):
         self.sock.shutdown.assert_called_with(socket.SHUT_WR)
         tr.close()
 
+    @mock.patch('asyncio.base_events.logger')
+    def test_transport_close_remove_writer(self, m_log):
+        remove_writer = self.loop.remove_writer = mock.Mock()
+
+        transport = self.socket_transport()
+        transport.close()
+        remove_writer.assert_called_with(self.sock_fd)
+
 
 @unittest.skipIf(ssl is None, 'No ssl module')
 class SelectorSslTransportTests(test_utils.TestCase):
@@ -1165,7 +1172,7 @@ class SelectorSslTransportTests(test_utils.TestCase):
         self.sslsock.do_handshake.side_effect = exc
         with test_utils.disable_logger():
             waiter = asyncio.Future(loop=self.loop)
-            transport = self.ssl_transport(waiter=waiter)
+            self.ssl_transport(waiter=waiter)
         self.assertTrue(waiter.done())
         self.assertIs(exc, waiter.exception())
         self.assertTrue(self.sslsock.close.called)
@@ -1182,7 +1189,7 @@ class SelectorSslTransportTests(test_utils.TestCase):
         self.assertIs(exc, waiter.exception())
 
     def test_cancel_handshake(self):
-        # Python issue #23197: cancelling an handshake must not raise an
+        # Python issue #23197: cancelling a handshake must not raise an
         # exception or log an error, even if the handshake failed
         waiter = asyncio.Future(loop=self.loop)
         transport = self.ssl_transport(waiter=waiter)
@@ -1364,20 +1371,19 @@ class SelectorSslTransportTests(test_utils.TestCase):
     def test_write_ready_send_closing(self):
         self.sslsock.send.return_value = 4
         transport = self._make_one()
-        transport.close()
         transport._buffer = list_to_buffer([b'data'])
+        transport.close()
         transport._write_ready()
-        self.assertFalse(self.loop.writers)
         self.protocol.connection_lost.assert_called_with(None)
 
     def test_write_ready_send_closing_empty_buffer(self):
         self.sslsock.send.return_value = 4
+        call_soon = self.loop.call_soon = mock.Mock()
         transport = self._make_one()
-        transport.close()
         transport._buffer = list_to_buffer()
+        transport.close()
         transport._write_ready()
-        self.assertFalse(self.loop.writers)
-        self.protocol.connection_lost.assert_called_with(None)
+        call_soon.assert_called_with(transport._call_connection_lost, None)
 
     def test_write_ready_send_retry(self):
         transport = self._make_one()
index a72967e..e4121a0 100644 (file)
@@ -40,7 +40,7 @@ class SslProtoHandshakeTests(test_utils.TestCase):
             ssl_proto.connection_made(transport)
 
     def test_cancel_handshake(self):
-        # Python issue #23197: cancelling an handshake must not raise an
+        # Python issue #23197: cancelling a handshake must not raise an
         # exception or log an error, even if the handshake failed
         waiter = asyncio.Future(loop=self.loop)
         ssl_proto = self.ssl_protocol(waiter)
index 6f657ad..1783d5f 100644 (file)
@@ -203,6 +203,20 @@ class StreamReaderTests(test_utils.TestCase):
         self.assertRaises(
             ValueError, self.loop.run_until_complete, stream.read(2))
 
+    def test_invalid_limit(self):
+        with self.assertRaisesRegex(ValueError, 'imit'):
+            asyncio.StreamReader(limit=0, loop=self.loop)
+
+        with self.assertRaisesRegex(ValueError, 'imit'):
+            asyncio.StreamReader(limit=-1, loop=self.loop)
+
+    def test_read_limit(self):
+        stream = asyncio.StreamReader(limit=3, loop=self.loop)
+        stream.feed_data(b'chunk')
+        data = self.loop.run_until_complete(stream.read(5))
+        self.assertEqual(b'chunk', data)
+        self.assertEqual(b'', stream._buffer)
+
     def test_readline(self):
         # Read one line. 'readline' will need to wait for the data
         # to come from 'cb'
@@ -292,6 +306,23 @@ class StreamReaderTests(test_utils.TestCase):
             ValueError, self.loop.run_until_complete, stream.readline())
         self.assertEqual(b'chunk3\n', stream._buffer)
 
+        # check strictness of the limit
+        stream = asyncio.StreamReader(limit=7, loop=self.loop)
+        stream.feed_data(b'1234567\n')
+        line = self.loop.run_until_complete(stream.readline())
+        self.assertEqual(b'1234567\n', line)
+        self.assertEqual(b'', stream._buffer)
+
+        stream.feed_data(b'12345678\n')
+        with self.assertRaises(ValueError) as cm:
+            self.loop.run_until_complete(stream.readline())
+        self.assertEqual(b'', stream._buffer)
+
+        stream.feed_data(b'12345678')
+        with self.assertRaises(ValueError) as cm:
+            self.loop.run_until_complete(stream.readline())
+        self.assertEqual(b'', stream._buffer)
+
     def test_readline_nolimit_nowait(self):
         # All needed data for the first 'readline' call will be
         # in the buffer.
@@ -342,6 +373,92 @@ class StreamReaderTests(test_utils.TestCase):
             ValueError, self.loop.run_until_complete, stream.readline())
         self.assertEqual(b'', stream._buffer)
 
+    def test_readuntil_separator(self):
+        stream = asyncio.StreamReader(loop=self.loop)
+        with self.assertRaisesRegex(ValueError, 'Separator should be'):
+            self.loop.run_until_complete(stream.readuntil(separator=b''))
+
+    def test_readuntil_multi_chunks(self):
+        stream = asyncio.StreamReader(loop=self.loop)
+
+        stream.feed_data(b'lineAAA')
+        data = self.loop.run_until_complete(stream.readuntil(separator=b'AAA'))
+        self.assertEqual(b'lineAAA', data)
+        self.assertEqual(b'', stream._buffer)
+
+        stream.feed_data(b'lineAAA')
+        data = self.loop.run_until_complete(stream.readuntil(b'AAA'))
+        self.assertEqual(b'lineAAA', data)
+        self.assertEqual(b'', stream._buffer)
+
+        stream.feed_data(b'lineAAAxxx')
+        data = self.loop.run_until_complete(stream.readuntil(b'AAA'))
+        self.assertEqual(b'lineAAA', data)
+        self.assertEqual(b'xxx', stream._buffer)
+
+    def test_readuntil_multi_chunks_1(self):
+        stream = asyncio.StreamReader(loop=self.loop)
+
+        stream.feed_data(b'QWEaa')
+        stream.feed_data(b'XYaa')
+        stream.feed_data(b'a')
+        data = self.loop.run_until_complete(stream.readuntil(b'aaa'))
+        self.assertEqual(b'QWEaaXYaaa', data)
+        self.assertEqual(b'', stream._buffer)
+
+        stream.feed_data(b'QWEaa')
+        stream.feed_data(b'XYa')
+        stream.feed_data(b'aa')
+        data = self.loop.run_until_complete(stream.readuntil(b'aaa'))
+        self.assertEqual(b'QWEaaXYaaa', data)
+        self.assertEqual(b'', stream._buffer)
+
+        stream.feed_data(b'aaa')
+        data = self.loop.run_until_complete(stream.readuntil(b'aaa'))
+        self.assertEqual(b'aaa', data)
+        self.assertEqual(b'', stream._buffer)
+
+        stream.feed_data(b'Xaaa')
+        data = self.loop.run_until_complete(stream.readuntil(b'aaa'))
+        self.assertEqual(b'Xaaa', data)
+        self.assertEqual(b'', stream._buffer)
+
+        stream.feed_data(b'XXX')
+        stream.feed_data(b'a')
+        stream.feed_data(b'a')
+        stream.feed_data(b'a')
+        data = self.loop.run_until_complete(stream.readuntil(b'aaa'))
+        self.assertEqual(b'XXXaaa', data)
+        self.assertEqual(b'', stream._buffer)
+
+    def test_readuntil_eof(self):
+        stream = asyncio.StreamReader(loop=self.loop)
+        stream.feed_data(b'some dataAA')
+        stream.feed_eof()
+
+        with self.assertRaises(asyncio.IncompleteReadError) as cm:
+            self.loop.run_until_complete(stream.readuntil(b'AAA'))
+        self.assertEqual(cm.exception.partial, b'some dataAA')
+        self.assertIsNone(cm.exception.expected)
+        self.assertEqual(b'', stream._buffer)
+
+    def test_readuntil_limit_found_sep(self):
+        stream = asyncio.StreamReader(loop=self.loop, limit=3)
+        stream.feed_data(b'some dataAA')
+
+        with self.assertRaisesRegex(asyncio.LimitOverrunError,
+                                    'not found') as cm:
+            self.loop.run_until_complete(stream.readuntil(b'AAA'))
+
+        self.assertEqual(b'some dataAA', stream._buffer)
+
+        stream.feed_data(b'A')
+        with self.assertRaisesRegex(asyncio.LimitOverrunError,
+                                    'is found') as cm:
+            self.loop.run_until_complete(stream.readuntil(b'AAA'))
+
+        self.assertEqual(b'some dataAAA', stream._buffer)
+
     def test_readexactly_zero_or_less(self):
         # Read exact number of bytes (zero or less).
         stream = asyncio.StreamReader(loop=self.loop)
@@ -351,8 +468,8 @@ class StreamReaderTests(test_utils.TestCase):
         self.assertEqual(b'', data)
         self.assertEqual(self.DATA, stream._buffer)
 
-        data = self.loop.run_until_complete(stream.readexactly(-1))
-        self.assertEqual(b'', data)
+        with self.assertRaisesRegex(ValueError, 'less than zero'):
+            self.loop.run_until_complete(stream.readexactly(-1))
         self.assertEqual(self.DATA, stream._buffer)
 
     def test_readexactly(self):
@@ -372,6 +489,13 @@ class StreamReaderTests(test_utils.TestCase):
         self.assertEqual(self.DATA + self.DATA, data)
         self.assertEqual(self.DATA, stream._buffer)
 
+    def test_readexactly_limit(self):
+        stream = asyncio.StreamReader(limit=3, loop=self.loop)
+        stream.feed_data(b'chunk')
+        data = self.loop.run_until_complete(stream.readexactly(5))
+        self.assertEqual(b'chunk', data)
+        self.assertEqual(b'', stream._buffer)
+
     def test_readexactly_eof(self):
         # Read exact number of bytes (eof).
         stream = asyncio.StreamReader(loop=self.loop)
@@ -647,16 +771,19 @@ os.close(fd)
         def server():
             # Runs in a separate thread.
             sock = socket.socket()
-            sock.bind(('localhost', 0))
-            sock.listen(1)
-            addr = sock.getsockname()
-            q.put(addr)
-            clt, _ = sock.accept()
-            clt.close()
+            with sock:
+                sock.bind(('localhost', 0))
+                sock.listen(1)
+                addr = sock.getsockname()
+                q.put(addr)
+                clt, _ = sock.accept()
+                clt.close()
 
         @asyncio.coroutine
         def client(host, port):
-            reader, writer = yield from asyncio.open_connection(host, port, loop=self.loop)
+            reader, writer = yield from asyncio.open_connection(
+                host, port, loop=self.loop)
+
             while True:
                 writer.write(b"foo\n")
                 yield from writer.drain()
index e90f17d..58f7253 100644 (file)
@@ -287,6 +287,25 @@ class SubprocessMixin:
         self.assertEqual(output.rstrip(), b'3')
         self.assertEqual(exitcode, 0)
 
+    def test_empty_input(self):
+        @asyncio.coroutine
+        def empty_input():
+            code = 'import sys; data = sys.stdin.read(); print(len(data))'
+            proc = yield from asyncio.create_subprocess_exec(
+                                          sys.executable, '-c', code,
+                                          stdin=asyncio.subprocess.PIPE,
+                                          stdout=asyncio.subprocess.PIPE,
+                                          stderr=asyncio.subprocess.PIPE,
+                                          close_fds=False,
+                                          loop=self.loop)
+            stdout, stderr = yield from proc.communicate(b'')
+            exitcode = yield from proc.wait()
+            return (stdout, exitcode)
+
+        output, exitcode = self.loop.run_until_complete(empty_input())
+        self.assertEqual(output.rstrip(), b'0')
+        self.assertEqual(exitcode, 0)
+
     def test_cancel_process_wait(self):
         # Issue #23140: cancel Process.wait()
 
@@ -388,7 +407,7 @@ class SubprocessMixin:
             transport, protocol = yield from create
             proc = transport.get_extra_info('subprocess')
 
-            # kill the process (but asyncio is not notified immediatly)
+            # kill the process (but asyncio is not notified immediately)
             proc.kill()
             proc.wait()
 
index 04d19ac..e7fb774 100644 (file)
@@ -6,6 +6,7 @@ import io
 import os
 import re
 import sys
+import time
 import types
 import unittest
 import weakref
@@ -76,6 +77,21 @@ class TaskTests(test_utils.TestCase):
     def setUp(self):
         self.loop = self.new_test_loop()
 
+    def test_other_loop_future(self):
+        other_loop = asyncio.new_event_loop()
+        fut = asyncio.Future(loop=other_loop)
+
+        @asyncio.coroutine
+        def run(fut):
+            yield from fut
+
+        try:
+            with self.assertRaisesRegex(RuntimeError,
+                                        r'Task .* got Future .* attached'):
+                self.loop.run_until_complete(run(fut))
+        finally:
+            other_loop.close()
+
     def test_task_class(self):
         @asyncio.coroutine
         def notmuch():
@@ -1778,6 +1794,30 @@ class TaskTests(test_utils.TestCase):
 
         self.assertRegex(message, re.compile(regex, re.DOTALL))
 
+    def test_return_coroutine_from_coroutine(self):
+        """Return of @asyncio.coroutine()-wrapped function generator object
+        from @asyncio.coroutine()-wrapped function should have same effect as
+        returning generator object or Future."""
+        def check():
+            @asyncio.coroutine
+            def outer_coro():
+                @asyncio.coroutine
+                def inner_coro():
+                    return 1
+
+                return inner_coro()
+
+            result = self.loop.run_until_complete(outer_coro())
+            self.assertEqual(result, 1)
+
+        # Test with debug flag cleared.
+        with set_coroutine_debug(False):
+            check()
+
+        # Test with debug flag set.
+        with set_coroutine_debug(True):
+            check()
+
     def test_task_source_traceback(self):
         self.loop.set_debug(True)
 
@@ -2197,6 +2237,10 @@ class SleepTests(test_utils.TestCase):
         self.loop = asyncio.new_event_loop()
         asyncio.set_event_loop(None)
 
+    def tearDown(self):
+        self.loop.close()
+        self.loop = None
+
     def test_sleep_zero(self):
         result = 0
 
index a0f548d..4f86aaa 100644 (file)
@@ -243,14 +243,26 @@ class BaseXYTestCase(unittest.TestCase):
                  (b'@@', b''),
                  (b'!', b''),
                  (b'YWJj\nYWI=', b'abcab'))
+        funcs = (
+            base64.b64decode,
+            base64.standard_b64decode,
+            base64.urlsafe_b64decode,
+        )
         for bstr, res in tests:
-            self.assertEqual(base64.b64decode(bstr), res)
-            self.assertEqual(base64.b64decode(bstr.decode('ascii')), res)
+            for func in funcs:
+                with self.subTest(bstr=bstr, func=func):
+                    self.assertEqual(func(bstr), res)
+                    self.assertEqual(func(bstr.decode('ascii')), res)
             with self.assertRaises(binascii.Error):
                 base64.b64decode(bstr, validate=True)
             with self.assertRaises(binascii.Error):
                 base64.b64decode(bstr.decode('ascii'), validate=True)
 
+        # Normal alphabet characters not discarded when alternative given
+        res = b'\xFB\xEF\xBE\xFF\xFF\xFF'
+        self.assertEqual(base64.b64decode(b'++[[//]]', b'[]'), res)
+        self.assertEqual(base64.urlsafe_b64decode(b'++--//__'), res)
+
     def test_b32encode(self):
         eq = self.assertEqual
         eq(base64.b32encode(b''), b'')
@@ -360,6 +372,10 @@ class BaseXYTestCase(unittest.TestCase):
            b'\x01\x02\xab\xcd\xef')
         eq(base64.b16decode(array('B', b"0102abcdef"), True),
            b'\x01\x02\xab\xcd\xef')
+        # Non-alphabet characters
+        self.assertRaises(binascii.Error, base64.b16decode, '0102AG')
+        # Incorrect "padding"
+        self.assertRaises(binascii.Error, base64.b16decode, '010')
 
     def test_a85encode(self):
         eq = self.assertEqual
@@ -478,6 +494,7 @@ class BaseXYTestCase(unittest.TestCase):
             eq(base64.a85decode(data, adobe=False), res, data)
             eq(base64.a85decode(data.decode("ascii"), adobe=False), res, data)
             eq(base64.a85decode(b'<~' + data + b'~>', adobe=True), res, data)
+            eq(base64.a85decode(data + b'~>', adobe=True), res, data)
             eq(base64.a85decode('<~%s~>' % data.decode("ascii"), adobe=True),
                res, data)
 
@@ -568,8 +585,6 @@ class BaseXYTestCase(unittest.TestCase):
                                       b"malformed", adobe=True)
         self.assertRaises(ValueError, base64.a85decode,
                                       b"<~still malformed", adobe=True)
-        self.assertRaises(ValueError, base64.a85decode,
-                                      b"also malformed~>", adobe=True)
 
         # With adobe=False (the default), Adobe framing markers are disallowed
         self.assertRaises(ValueError, base64.a85decode,
index 0e54595..40ac9bf 100644 (file)
@@ -737,7 +737,7 @@ class StrTest(unittest.TestCase, BaseStrTest):
         finally:
             r = s = None
 
-    # The original test_translate is overriden here, so as to get the
+    # The original test_translate is overridden here, so as to get the
     # correct size estimate: str.translate() uses an intermediate Py_UCS4
     # representation.
 
index 823740c..e9dbddc 100644 (file)
@@ -58,7 +58,7 @@ class Rat(object):
     den = property(_get_den, None)
 
     def __repr__(self):
-        """Convert a Rat to an string resembling a Rat constructor call."""
+        """Convert a Rat to a string resembling a Rat constructor call."""
         return "Rat(%d, %d)" % (self.__num, self.__den)
 
     def __str__(self):
index 2507439..d30a3b9 100644 (file)
@@ -314,6 +314,10 @@ class BoolTest(unittest.TestCase):
                 return -1
         self.assertRaises(ValueError, bool, Eggs())
 
+    def test_from_bytes(self):
+        self.assertIs(bool.from_bytes(b'\x00'*8, 'big'), False)
+        self.assertIs(bool.from_bytes(b'abcd', 'little'), True)
+
     def test_sane_len(self):
         # this test just tests our assumptions about __len__
         # this will start failing if __len__ changes assertions
index 5deeb72..8cc1b00 100644 (file)
@@ -1668,6 +1668,161 @@ class ShutdownTest(unittest.TestCase):
         self.assertEqual(["before", "after"], out.decode().splitlines())
 
 
+class TestType(unittest.TestCase):
+    def test_new_type(self):
+        A = type('A', (), {})
+        self.assertEqual(A.__name__, 'A')
+        self.assertEqual(A.__qualname__, 'A')
+        self.assertEqual(A.__module__, __name__)
+        self.assertEqual(A.__bases__, (object,))
+        self.assertIs(A.__base__, object)
+        x = A()
+        self.assertIs(type(x), A)
+        self.assertIs(x.__class__, A)
+
+        class B:
+            def ham(self):
+                return 'ham%d' % self
+        C = type('C', (B, int), {'spam': lambda self: 'spam%s' % self})
+        self.assertEqual(C.__name__, 'C')
+        self.assertEqual(C.__qualname__, 'C')
+        self.assertEqual(C.__module__, __name__)
+        self.assertEqual(C.__bases__, (B, int))
+        self.assertIs(C.__base__, int)
+        self.assertIn('spam', C.__dict__)
+        self.assertNotIn('ham', C.__dict__)
+        x = C(42)
+        self.assertEqual(x, 42)
+        self.assertIs(type(x), C)
+        self.assertIs(x.__class__, C)
+        self.assertEqual(x.ham(), 'ham42')
+        self.assertEqual(x.spam(), 'spam42')
+        self.assertEqual(x.to_bytes(2, 'little'), b'\x2a\x00')
+
+    def test_type_new_keywords(self):
+        class B:
+            def ham(self):
+                return 'ham%d' % self
+        C = type.__new__(type,
+                         name='C',
+                         bases=(B, int),
+                         dict={'spam': lambda self: 'spam%s' % self})
+        self.assertEqual(C.__name__, 'C')
+        self.assertEqual(C.__qualname__, 'C')
+        self.assertEqual(C.__module__, __name__)
+        self.assertEqual(C.__bases__, (B, int))
+        self.assertIs(C.__base__, int)
+        self.assertIn('spam', C.__dict__)
+        self.assertNotIn('ham', C.__dict__)
+
+    def test_type_name(self):
+        for name in 'A', '\xc4', '\U0001f40d', 'B.A', '42', '':
+            with self.subTest(name=name):
+                A = type(name, (), {})
+                self.assertEqual(A.__name__, name)
+                self.assertEqual(A.__qualname__, name)
+                self.assertEqual(A.__module__, __name__)
+        with self.assertRaises(ValueError):
+            type('A\x00B', (), {})
+        with self.assertRaises(ValueError):
+            type('A\udcdcB', (), {})
+        with self.assertRaises(TypeError):
+            type(b'A', (), {})
+
+        C = type('C', (), {})
+        for name in 'A', '\xc4', '\U0001f40d', 'B.A', '42', '':
+            with self.subTest(name=name):
+                C.__name__ = name
+                self.assertEqual(C.__name__, name)
+                self.assertEqual(C.__qualname__, 'C')
+                self.assertEqual(C.__module__, __name__)
+
+        A = type('C', (), {})
+        with self.assertRaises(ValueError):
+            A.__name__ = 'A\x00B'
+        self.assertEqual(A.__name__, 'C')
+        with self.assertRaises(ValueError):
+            A.__name__ = 'A\udcdcB'
+        self.assertEqual(A.__name__, 'C')
+        with self.assertRaises(TypeError):
+            A.__name__ = b'A'
+        self.assertEqual(A.__name__, 'C')
+
+    def test_type_qualname(self):
+        A = type('A', (), {'__qualname__': 'B.C'})
+        self.assertEqual(A.__name__, 'A')
+        self.assertEqual(A.__qualname__, 'B.C')
+        self.assertEqual(A.__module__, __name__)
+        with self.assertRaises(TypeError):
+            type('A', (), {'__qualname__': b'B'})
+        self.assertEqual(A.__qualname__, 'B.C')
+
+        A.__qualname__ = 'D.E'
+        self.assertEqual(A.__name__, 'A')
+        self.assertEqual(A.__qualname__, 'D.E')
+        with self.assertRaises(TypeError):
+            A.__qualname__ = b'B'
+        self.assertEqual(A.__qualname__, 'D.E')
+
+    def test_type_doc(self):
+        for doc in 'x', '\xc4', '\U0001f40d', 'x\x00y', b'x', 42, None:
+            A = type('A', (), {'__doc__': doc})
+            self.assertEqual(A.__doc__, doc)
+        with self.assertRaises(UnicodeEncodeError):
+            type('A', (), {'__doc__': 'x\udcdcy'})
+
+        A = type('A', (), {})
+        self.assertEqual(A.__doc__, None)
+        for doc in 'x', '\xc4', '\U0001f40d', 'x\x00y', 'x\udcdcy', b'x', 42, None:
+            A.__doc__ = doc
+            self.assertEqual(A.__doc__, doc)
+
+    def test_bad_args(self):
+        with self.assertRaises(TypeError):
+            type()
+        with self.assertRaises(TypeError):
+            type('A', ())
+        with self.assertRaises(TypeError):
+            type('A', (), {}, ())
+        with self.assertRaises(TypeError):
+            type('A', (), dict={})
+        with self.assertRaises(TypeError):
+            type('A', [], {})
+        with self.assertRaises(TypeError):
+            type('A', (), types.MappingProxyType({}))
+        with self.assertRaises(TypeError):
+            type('A', (None,), {})
+        with self.assertRaises(TypeError):
+            type('A', (bool,), {})
+        with self.assertRaises(TypeError):
+            type('A', (int, str), {})
+
+    def test_bad_slots(self):
+        with self.assertRaises(TypeError):
+            type('A', (), {'__slots__': b'x'})
+        with self.assertRaises(TypeError):
+            type('A', (int,), {'__slots__': 'x'})
+        with self.assertRaises(TypeError):
+            type('A', (), {'__slots__': ''})
+        with self.assertRaises(TypeError):
+            type('A', (), {'__slots__': '42'})
+        with self.assertRaises(TypeError):
+            type('A', (), {'__slots__': 'x\x00y'})
+        with self.assertRaises(ValueError):
+            type('A', (), {'__slots__': 'x', 'x': 0})
+        with self.assertRaises(TypeError):
+            type('A', (), {'__slots__': ('__dict__', '__dict__')})
+        with self.assertRaises(TypeError):
+            type('A', (), {'__slots__': ('__weakref__', '__weakref__')})
+
+        class B:
+            pass
+        with self.assertRaises(TypeError):
+            type('A', (B,), {'__slots__': '__dict__'})
+        with self.assertRaises(TypeError):
+            type('A', (B,), {'__slots__': '__weakref__'})
+
+
 def load_tests(loader, tests, pattern):
     from doctest import DocTestSuite
     tests.addTest(DocTestSuite(builtins))
index 53a80f4..65c00d7 100644 (file)
@@ -1,8 +1,7 @@
 """Unit tests for the bytes and bytearray types.
 
-XXX This is a mess.  Common tests should be moved to buffer_tests.py,
-which itself ought to be unified with string_tests.py (and the latter
-should be modernized).
+XXX This is a mess.  Common tests should be unified with string_tests.py (and
+the latter should be modernized).
 """
 
 import os
@@ -16,7 +15,7 @@ import unittest
 
 import test.support
 import test.string_tests
-import test.buffer_tests
+import test.list_tests
 from test.support import bigaddrspacetest, MAX_Py_ssize_t
 
 
@@ -470,94 +469,49 @@ class BaseBytesTest:
         self.assertRaises(ValueError, b.rindex, w, 1, 3)
 
     def test_mod(self):
-        b = b'hello, %b!'
+        b = self.type2test(b'hello, %b!')
         orig = b
         b = b % b'world'
         self.assertEqual(b, b'hello, world!')
         self.assertEqual(orig, b'hello, %b!')
         self.assertFalse(b is orig)
-        b = b'%s / 100 = %d%%'
+        b = self.type2test(b'%s / 100 = %d%%')
         a = b % (b'seventy-nine', 79)
         self.assertEqual(a, b'seventy-nine / 100 = 79%')
+        self.assertIs(type(a), self.type2test)
 
     def test_imod(self):
-        b = b'hello, %b!'
+        b = self.type2test(b'hello, %b!')
         orig = b
         b %= b'world'
         self.assertEqual(b, b'hello, world!')
         self.assertEqual(orig, b'hello, %b!')
         self.assertFalse(b is orig)
-        b = b'%s / 100 = %d%%'
+        b = self.type2test(b'%s / 100 = %d%%')
         b %= (b'seventy-nine', 79)
         self.assertEqual(b, b'seventy-nine / 100 = 79%')
+        self.assertIs(type(b), self.type2test)
+
+    def test_rmod(self):
+        with self.assertRaises(TypeError):
+            object() % self.type2test(b'abc')
+        self.assertIs(self.type2test(b'abc').__rmod__('%r'), NotImplemented)
 
     def test_replace(self):
         b = self.type2test(b'mississippi')
         self.assertEqual(b.replace(b'i', b'a'), b'massassappa')
         self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi')
 
-    def test_split(self):
-        b = self.type2test(b'mississippi')
-        self.assertEqual(b.split(b'i'), [b'm', b'ss', b'ss', b'pp', b''])
-        self.assertEqual(b.split(b'ss'), [b'mi', b'i', b'ippi'])
-        self.assertEqual(b.split(b'w'), [b])
-        # with keyword args
-        b = self.type2test(b'a|b|c|d')
-        self.assertEqual(b.split(sep=b'|'), [b'a', b'b', b'c', b'd'])
-        self.assertEqual(b.split(b'|', maxsplit=1), [b'a', b'b|c|d'])
-        self.assertEqual(b.split(sep=b'|', maxsplit=1), [b'a', b'b|c|d'])
-        self.assertEqual(b.split(maxsplit=1, sep=b'|'), [b'a', b'b|c|d'])
-        b = self.type2test(b'a b c d')
-        self.assertEqual(b.split(maxsplit=1), [b'a', b'b c d'])
-
-    def test_split_whitespace(self):
-        for b in (b'  arf  barf  ', b'arf\tbarf', b'arf\nbarf', b'arf\rbarf',
-                  b'arf\fbarf', b'arf\vbarf'):
-            b = self.type2test(b)
-            self.assertEqual(b.split(), [b'arf', b'barf'])
-            self.assertEqual(b.split(None), [b'arf', b'barf'])
-            self.assertEqual(b.split(None, 2), [b'arf', b'barf'])
-        for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
-            b = self.type2test(b)
-            self.assertEqual(b.split(), [b])
-        self.assertEqual(self.type2test(b'  a  bb  c  ').split(None, 0), [b'a  bb  c  '])
-        self.assertEqual(self.type2test(b'  a  bb  c  ').split(None, 1), [b'a', b'bb  c  '])
-        self.assertEqual(self.type2test(b'  a  bb  c  ').split(None, 2), [b'a', b'bb', b'c  '])
-        self.assertEqual(self.type2test(b'  a  bb  c  ').split(None, 3), [b'a', b'bb', b'c'])
-
     def test_split_string_error(self):
         self.assertRaises(TypeError, self.type2test(b'a b').split, ' ')
 
     def test_split_unicodewhitespace(self):
+        for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
+            b = self.type2test(b)
+            self.assertEqual(b.split(), [b])
         b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
         self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f'])
 
-    def test_rsplit(self):
-        b = self.type2test(b'mississippi')
-        self.assertEqual(b.rsplit(b'i'), [b'm', b'ss', b'ss', b'pp', b''])
-        self.assertEqual(b.rsplit(b'ss'), [b'mi', b'i', b'ippi'])
-        self.assertEqual(b.rsplit(b'w'), [b])
-        # with keyword args
-        b = self.type2test(b'a|b|c|d')
-        self.assertEqual(b.rsplit(sep=b'|'), [b'a', b'b', b'c', b'd'])
-        self.assertEqual(b.rsplit(b'|', maxsplit=1), [b'a|b|c', b'd'])
-        self.assertEqual(b.rsplit(sep=b'|', maxsplit=1), [b'a|b|c', b'd'])
-        self.assertEqual(b.rsplit(maxsplit=1, sep=b'|'), [b'a|b|c', b'd'])
-        b = self.type2test(b'a b c d')
-        self.assertEqual(b.rsplit(maxsplit=1), [b'a b c', b'd'])
-
-    def test_rsplit_whitespace(self):
-        for b in (b'  arf  barf  ', b'arf\tbarf', b'arf\nbarf', b'arf\rbarf',
-                  b'arf\fbarf', b'arf\vbarf'):
-            b = self.type2test(b)
-            self.assertEqual(b.rsplit(), [b'arf', b'barf'])
-            self.assertEqual(b.rsplit(None), [b'arf', b'barf'])
-            self.assertEqual(b.rsplit(None, 2), [b'arf', b'barf'])
-        self.assertEqual(self.type2test(b'  a  bb  c  ').rsplit(None, 0), [b'  a  bb  c'])
-        self.assertEqual(self.type2test(b'  a  bb  c  ').rsplit(None, 1), [b'  a  bb', b'c'])
-        self.assertEqual(self.type2test(b'  a  bb  c  ').rsplit(None, 2), [b'  a', b'bb', b'c'])
-        self.assertEqual(self.type2test(b'  a  bb  c  ').rsplit(None, 3), [b'a', b'bb', b'c'])
-
     def test_rsplit_string_error(self):
         self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ')
 
@@ -595,45 +549,13 @@ class BaseBytesTest:
                 self.assertEqual(list(it), data)
 
                 it = pickle.loads(d)
-                try:
-                    next(it)
-                except StopIteration:
+                if not b:
                     continue
+                next(it)
                 d = pickle.dumps(it, proto)
                 it = pickle.loads(d)
                 self.assertEqual(list(it), data[1:])
 
-    def test_strip(self):
-        b = self.type2test(b'mississippi')
-        self.assertEqual(b.strip(b'i'), b'mississipp')
-        self.assertEqual(b.strip(b'm'), b'ississippi')
-        self.assertEqual(b.strip(b'pi'), b'mississ')
-        self.assertEqual(b.strip(b'im'), b'ssissipp')
-        self.assertEqual(b.strip(b'pim'), b'ssiss')
-        self.assertEqual(b.strip(b), b'')
-
-    def test_lstrip(self):
-        b = self.type2test(b'mississippi')
-        self.assertEqual(b.lstrip(b'i'), b'mississippi')
-        self.assertEqual(b.lstrip(b'm'), b'ississippi')
-        self.assertEqual(b.lstrip(b'pi'), b'mississippi')
-        self.assertEqual(b.lstrip(b'im'), b'ssissippi')
-        self.assertEqual(b.lstrip(b'pim'), b'ssissippi')
-
-    def test_rstrip(self):
-        b = self.type2test(b'mississippi')
-        self.assertEqual(b.rstrip(b'i'), b'mississipp')
-        self.assertEqual(b.rstrip(b'm'), b'mississippi')
-        self.assertEqual(b.rstrip(b'pi'), b'mississ')
-        self.assertEqual(b.rstrip(b'im'), b'mississipp')
-        self.assertEqual(b.rstrip(b'pim'), b'mississ')
-
-    def test_strip_whitespace(self):
-        b = self.type2test(b' \t\n\r\f\vabc \t\n\r\f\v')
-        self.assertEqual(b.strip(), b'abc')
-        self.assertEqual(b.lstrip(), b'abc \t\n\r\f\v')
-        self.assertEqual(b.rstrip(), b' \t\n\r\f\vabc')
-
     def test_strip_bytearray(self):
         self.assertEqual(self.type2test(b'abc').strip(memoryview(b'ac')), b'b')
         self.assertEqual(self.type2test(b'abc').lstrip(memoryview(b'ac')), b'bc')
@@ -748,6 +670,10 @@ class BaseBytesTest:
         self.assertRaisesRegex(TypeError, r'\bendswith\b', b.endswith,
                                 x, None, None, None)
 
+    def test_free_after_iterating(self):
+        test.support.check_free_after_iterating(self, iter, self.type2test)
+        test.support.check_free_after_iterating(self, reversed, self.type2test)
+
 
 class BytesTest(BaseBytesTest, unittest.TestCase):
     type2test = bytes
@@ -779,6 +705,20 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
             def __index__(self):
                 return 42
         self.assertEqual(bytes(A()), b'a')
+        # Issue #25766
+        class A(str):
+            def __bytes__(self):
+                return b'abc'
+        self.assertEqual(bytes(A('\u20ac')), b'abc')
+        self.assertEqual(bytes(A('\u20ac'), 'iso8859-15'), b'\xa4')
+        # Issue #24731
+        class A:
+            def __bytes__(self):
+                return OtherBytesSubclass(b'abc')
+        self.assertEqual(bytes(A()), b'abc')
+        self.assertIs(type(bytes(A())), OtherBytesSubclass)
+        self.assertEqual(BytesSubclass(A()), b'abc')
+        self.assertIs(type(BytesSubclass(A())), BytesSubclass)
 
     # Test PyBytes_FromFormat()
     def test_from_format(self):
@@ -1036,28 +976,6 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
         b[8:] = b
         self.assertEqual(b, bytearray(list(range(8)) + list(range(256))))
 
-    def test_mod(self):
-        b = bytearray(b'hello, %b!')
-        orig = b
-        b = b % b'world'
-        self.assertEqual(b, b'hello, world!')
-        self.assertEqual(orig, bytearray(b'hello, %b!'))
-        self.assertFalse(b is orig)
-        b = bytearray(b'%s / 100 = %d%%')
-        a = b % (b'seventy-nine', 79)
-        self.assertEqual(a, bytearray(b'seventy-nine / 100 = 79%'))
-
-    def test_imod(self):
-        b = bytearray(b'hello, %b!')
-        orig = b
-        b %= b'world'
-        self.assertEqual(b, b'hello, world!')
-        self.assertEqual(orig, bytearray(b'hello, %b!'))
-        self.assertFalse(b is orig)
-        b = bytearray(b'%s / 100 = %d%%')
-        b %= (b'seventy-nine', 79)
-        self.assertEqual(b, bytearray(b'seventy-nine / 100 = 79%'))
-
     def test_iconcat(self):
         b = bytearray(b"abc")
         b1 = b
@@ -1164,6 +1082,13 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
         b.remove(Indexable(ord('e')))
         self.assertEqual(b, b'')
 
+        # test values outside of the ascii range: (0, 127)
+        c = bytearray([126, 127, 128, 129])
+        c.remove(127)
+        self.assertEqual(c, bytes([126, 128, 129]))
+        c.remove(129)
+        self.assertEqual(c, bytes([126, 128]))
+
     def test_pop(self):
         b = bytearray(b'world')
         self.assertEqual(b.pop(), ord('d'))
@@ -1270,6 +1195,44 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
         from _testcapi import getbuffer_with_null_view
         self.assertRaises(BufferError, getbuffer_with_null_view, bytearray())
 
+    def test_iterator_pickling2(self):
+        orig = bytearray(b'abc')
+        data = list(b'qwerty')
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            # initial iterator
+            itorig = iter(orig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, b = pickle.loads(d)
+            b[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data)
+
+            # running iterator
+            next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, b = pickle.loads(d)
+            b[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data[1:])
+
+            # empty iterator
+            for i in range(1, len(orig)):
+                next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, b = pickle.loads(d)
+            b[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data[len(orig):])
+
+            # exhausted iterator
+            self.assertRaises(StopIteration, next, itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, b = pickle.loads(d)
+            b[:] = data
+            self.assertEqual(list(it), [])
+
+    test_exhausted_iterator = test.list_tests.CommonTest.test_exhausted_iterator
+
 class AssortedBytesTest(unittest.TestCase):
     #
     # Test various combinations of bytes and bytearray
@@ -1416,7 +1379,7 @@ class AssortedBytesTest(unittest.TestCase):
     # XXX More string methods?  (Those that don't use character properties)
 
     # There are tests in string_tests.py that are more
-    # comprehensive for things like split, partition, etc.
+    # comprehensive for things like partition, etc.
     # Unfortunately they are all bundled with tests that
     # are not appropriate for bytes
 
@@ -1424,8 +1387,7 @@ class AssortedBytesTest(unittest.TestCase):
     # the rest that make sense (the code can be cleaned up to use modern
     # unittest methods at the same time).
 
-class BytearrayPEP3137Test(unittest.TestCase,
-                       test.buffer_tests.MixinBytesBufferCommonTests):
+class BytearrayPEP3137Test(unittest.TestCase):
     def marshal(self, x):
         return bytearray(x)
 
@@ -1453,41 +1415,28 @@ class BytearrayPEP3137Test(unittest.TestCase,
 
 
 class FixedStringTest(test.string_tests.BaseTest):
-
     def fixtype(self, obj):
         if isinstance(obj, str):
-            return obj.encode("utf-8")
+            return self.type2test(obj.encode("utf-8"))
         return super().fixtype(obj)
 
-    # Currently the bytes containment testing uses a single integer
-    # value. This may not be the final design, but until then the
-    # bytes section with in a bytes containment not valid
-    def test_contains(self):
-        pass
-    def test_expandtabs(self):
-        pass
-    def test_upper(self):
-        pass
-    def test_lower(self):
-        pass
+    contains_bytes = True
 
 class ByteArrayAsStringTest(FixedStringTest, unittest.TestCase):
     type2test = bytearray
-    contains_bytes = True
 
 class BytesAsStringTest(FixedStringTest, unittest.TestCase):
     type2test = bytes
-    contains_bytes = True
 
 
 class SubclassTest:
 
     def test_basic(self):
-        self.assertTrue(issubclass(self.subclass2test, self.type2test))
-        self.assertIsInstance(self.subclass2test(), self.type2test)
+        self.assertTrue(issubclass(self.type2test, self.basetype))
+        self.assertIsInstance(self.type2test(), self.basetype)
 
         a, b = b"abcd", b"efgh"
-        _a, _b = self.subclass2test(a), self.subclass2test(b)
+        _a, _b = self.type2test(a), self.type2test(b)
 
         # test comparison operators with subclass instances
         self.assertTrue(_a == _a)
@@ -1510,19 +1459,19 @@ class SubclassTest:
         # Make sure join returns a NEW object for single item sequences
         # involving a subclass.
         # Make sure that it is of the appropriate type.
-        s1 = self.subclass2test(b"abcd")
-        s2 = self.type2test().join([s1])
+        s1 = self.type2test(b"abcd")
+        s2 = self.basetype().join([s1])
         self.assertTrue(s1 is not s2)
-        self.assertTrue(type(s2) is self.type2test, type(s2))
+        self.assertTrue(type(s2) is self.basetype, type(s2))
 
         # Test reverse, calling join on subclass
         s3 = s1.join([b"abcd"])
-        self.assertTrue(type(s3) is self.type2test)
+        self.assertTrue(type(s3) is self.basetype)
 
     def test_pickle(self):
-        a = self.subclass2test(b"abcd")
+        a = self.type2test(b"abcd")
         a.x = 10
-        a.y = self.subclass2test(b"efgh")
+        a.y = self.type2test(b"efgh")
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
             b = pickle.loads(pickle.dumps(a, proto))
             self.assertNotEqual(id(a), id(b))
@@ -1533,9 +1482,9 @@ class SubclassTest:
             self.assertEqual(type(a.y), type(b.y))
 
     def test_copy(self):
-        a = self.subclass2test(b"abcd")
+        a = self.type2test(b"abcd")
         a.x = 10
-        a.y = self.subclass2test(b"efgh")
+        a.y = self.type2test(b"efgh")
         for copy_method in (copy.copy, copy.deepcopy):
             b = copy_method(a)
             self.assertNotEqual(id(a), id(b))
@@ -1545,6 +1494,8 @@ class SubclassTest:
             self.assertEqual(type(a), type(b))
             self.assertEqual(type(a.y), type(b.y))
 
+    test_fromhex = BaseBytesTest.test_fromhex
+
 
 class ByteArraySubclass(bytearray):
     pass
@@ -1552,9 +1503,12 @@ class ByteArraySubclass(bytearray):
 class BytesSubclass(bytes):
     pass
 
+class OtherBytesSubclass(bytes):
+    pass
+
 class ByteArraySubclassTest(SubclassTest, unittest.TestCase):
-    type2test = bytearray
-    subclass2test = ByteArraySubclass
+    basetype = bytearray
+    type2test = ByteArraySubclass
 
     def test_init_override(self):
         class subclass(bytearray):
@@ -1568,8 +1522,8 @@ class ByteArraySubclassTest(SubclassTest, unittest.TestCase):
 
 
 class BytesSubclassTest(SubclassTest, unittest.TestCase):
-    type2test = bytes
-    subclass2test = BytesSubclass
+    basetype = bytes
+    type2test = BytesSubclass
 
 
 if __name__ == "__main__":
index eae3add..1eadd22 100644 (file)
@@ -236,6 +236,9 @@ class CAPITest(unittest.TestCase):
                              'return_result_with_error.* '
                              'returned a result with an error set')
 
+    def test_buildvalue_N(self):
+        _testcapi.test_buildvalue_N()
+
 
 @unittest.skipUnless(threading, 'Threading required for this test.')
 class TestPendingCalls(unittest.TestCase):
@@ -343,7 +346,8 @@ class Test6012(unittest.TestCase):
 
 class EmbeddingTests(unittest.TestCase):
     def setUp(self):
-        basepath = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
+        here = os.path.abspath(__file__)
+        basepath = os.path.dirname(os.path.dirname(os.path.dirname(here)))
         exename = "_testembed"
         if sys.platform.startswith("win"):
             ext = ("_d" if "_d" in sys.executable else "") + ".exe"
@@ -457,7 +461,7 @@ class SkipitemTest(unittest.TestCase):
         test and not for the other, there's a mismatch, and the test fails.
 
            ** Some format units have special funny semantics and it would
-              be difficult to accomodate them here.  Since these are all
+              be difficult to accommodate them here.  Since these are all
               well-established and properly skipped in skipitem() we can
               get away with not testing them--this test is really intended
               to catch *new* format units.
@@ -488,7 +492,7 @@ class SkipitemTest(unittest.TestCase):
                     format.encode("ascii"), keywords)
                 when_not_skipped = False
             except TypeError as e:
-                s = "argument 1 must be impossible<bad format char>, not int"
+                s = "argument 1 (impossible<bad format char>)"
                 when_not_skipped = (str(e) == s)
             except RuntimeError as e:
                 when_not_skipped = False
index 0feb63f..dce418b 100644 (file)
@@ -403,12 +403,24 @@ class CmdLineTest(unittest.TestCase):
         # Verify that -R enables hash randomization:
         self.verify_valid_flag('-R')
         hashes = []
-        for i in range(2):
+        if os.environ.get('PYTHONHASHSEED', 'random') != 'random':
+            env = dict(os.environ)  # copy
+            # We need to test that it is enabled by default without
+            # the environment variable enabling it for us.
+            del env['PYTHONHASHSEED']
+            env['__cleanenv'] = '1'  # consumed by assert_python_ok()
+        else:
+            env = {}
+        for i in range(3):
             code = 'print(hash("spam"))'
-            rc, out, err = assert_python_ok('-c', code)
+            rc, out, err = assert_python_ok('-c', code, **env)
             self.assertEqual(rc, 0)
             hashes.append(out)
-        self.assertNotEqual(hashes[0], hashes[1])
+        hashes = sorted(set(hashes))  # uniq
+        # Rare chance of failure due to 3 random seeds honestly being equal.
+        self.assertGreater(len(hashes), 1,
+                           msg='3 runs produced an identical random hash '
+                               ' for "spam": {}'.format(hashes))
 
         # Verify that sys.flags contains hash_randomization
         code = 'import sys; print("random is", sys.flags.hash_randomization)'
index fda3e62..b2be9b1 100644 (file)
@@ -397,20 +397,87 @@ class CmdLineTest(unittest.TestCase):
                                       script_name, script_name, '', '',
                                       importlib.machinery.SourceFileLoader)
 
+    @contextlib.contextmanager
+    def setup_test_pkg(self, *args):
+        with support.temp_dir() as script_dir, \
+                support.change_cwd(path=script_dir):
+            pkg_dir = os.path.join(script_dir, 'test_pkg')
+            make_pkg(pkg_dir, *args)
+            yield pkg_dir
+
+    def check_dash_m_failure(self, *args):
+        rc, out, err = assert_python_failure('-m', *args, __isolated=False)
+        if verbose > 1:
+            print(repr(out))
+        self.assertEqual(rc, 1)
+        return err
+
     def test_dash_m_error_code_is_one(self):
         # If a module is invoked with the -m command line flag
         # and results in an error that the return code to the
         # shell is '1'
-        with support.temp_dir() as script_dir:
-            with support.change_cwd(path=script_dir):
-                pkg_dir = os.path.join(script_dir, 'test_pkg')
-                make_pkg(pkg_dir)
-                script_name = _make_test_script(pkg_dir, 'other',
-                                                "if __name__ == '__main__': raise ValueError")
-                rc, out, err = assert_python_failure('-m', 'test_pkg.other', *example_args)
-                if verbose > 1:
-                    print(repr(out))
+        with self.setup_test_pkg() as pkg_dir:
+            script_name = _make_test_script(pkg_dir, 'other',
+                                            "if __name__ == '__main__': raise ValueError")
+            err = self.check_dash_m_failure('test_pkg.other', *example_args)
+            self.assertIn(b'ValueError', err)
+
+    def test_dash_m_errors(self):
+        # Exercise error reporting for various invalid package executions
+        tests = (
+            ('builtins', br'No code object available'),
+            ('builtins.x', br'Error while finding spec.*AttributeError'),
+            ('builtins.x.y', br'Error while finding spec.*'
+                br'ImportError.*No module named.*not a package'),
+            ('os.path', br'loader.*cannot handle'),
+            ('importlib', br'No module named.*'
+                br'is a package and cannot be directly executed'),
+            ('importlib.nonexistant', br'No module named'),
+            ('.unittest', br'Relative module names not supported'),
+        )
+        for name, regex in tests:
+            with self.subTest(name):
+                rc, _, err = assert_python_failure('-m', name)
                 self.assertEqual(rc, 1)
+                self.assertRegex(err, regex)
+                self.assertNotIn(b'Traceback', err)
+
+    def test_dash_m_bad_pyc(self):
+        with support.temp_dir() as script_dir, \
+                support.change_cwd(path=script_dir):
+            os.mkdir('test_pkg')
+            # Create invalid *.pyc as empty file
+            with open('test_pkg/__init__.pyc', 'wb'):
+                pass
+            err = self.check_dash_m_failure('test_pkg')
+            self.assertRegex(err, br'Error while finding spec.*'
+                br'ImportError.*bad magic number')
+            self.assertNotIn(b'is a package', err)
+            self.assertNotIn(b'Traceback', err)
+
+    def test_dash_m_init_traceback(self):
+        # These were wrapped in an ImportError and tracebacks were
+        # suppressed; see Issue 14285
+        exceptions = (ImportError, AttributeError, TypeError, ValueError)
+        for exception in exceptions:
+            exception = exception.__name__
+            init = "raise {0}('Exception in __init__.py')".format(exception)
+            with self.subTest(exception), \
+                    self.setup_test_pkg(init) as pkg_dir:
+                err = self.check_dash_m_failure('test_pkg')
+                self.assertIn(exception.encode('ascii'), err)
+                self.assertIn(b'Exception in __init__.py', err)
+                self.assertIn(b'Traceback', err)
+
+    def test_dash_m_main_traceback(self):
+        # Ensure that an ImportError's traceback is reported
+        with self.setup_test_pkg() as pkg_dir:
+            main = "raise ImportError('Exception in __main__ module')"
+            _make_test_script(pkg_dir, '__main__', main)
+            err = self.check_dash_m_failure('test_pkg')
+            self.assertIn(b'ImportError', err)
+            self.assertIn(b'Exception in __main__ module', err)
+            self.assertIn(b'Traceback', err)
 
     def test_pep_409_verbiage(self):
         # Make sure PEP 409 syntax properly suppresses
@@ -432,7 +499,7 @@ class CmdLineTest(unittest.TestCase):
 
     def test_non_ascii(self):
         # Mac OS X denies the creation of a file with an invalid UTF-8 name.
-        # Windows allows to create a name with an arbitrary bytes name, but
+        # Windows allows creating a name with an arbitrary bytes name, but
         # Python cannot a undecodable bytes argument to a subprocess.
         if (support.TESTFN_UNDECODABLE
         and sys.platform not in ('win32', 'darwin')):
index b93e0ab..0479542 100644 (file)
@@ -2355,7 +2355,7 @@ class TypesTest(unittest.TestCase):
             self.assertRaises(TypeError, decoder, "xxx")
 
     def test_unicode_escape(self):
-        # Escape-decoding an unicode string is supported ang gives the same
+        # Escape-decoding a unicode string is supported and gives the same
         # result as decoding the equivalent ASCII bytes string.
         self.assertEqual(codecs.unicode_escape_decode(r"\u1234"), ("\u1234", 6))
         self.assertEqual(codecs.unicode_escape_decode(br"\u1234"), ("\u1234", 6))
@@ -2762,7 +2762,7 @@ class TransformCodecTest(unittest.TestCase):
 # type and a single str argument.
 
 # Use a local codec registry to avoid appearing to leak objects when
-# registering multiple seach functions
+# registering multiple search functions
 _TEST_CODECS = {}
 
 def _get_test_codec(codec_name):
index b9fdf79..4c32e09 100644 (file)
@@ -1,18 +1,21 @@
 """Unit tests for collections.py."""
 
-import unittest, doctest, operator
-from test.support import TESTFN, forget, unlink, import_fresh_module
-import contextlib
+import collections
+import copy
+import doctest
 import inspect
-from test import support
-from collections import namedtuple, Counter, OrderedDict, _count_elements
-from test import mapping_tests
-import pickle, copy
-from random import randrange, shuffle
 import keyword
+import operator
+import pickle
+from random import choice, randrange
 import re
+import string
 import sys
+from test import support
 import types
+import unittest
+
+from collections import namedtuple, Counter, OrderedDict, _count_elements
 from collections import UserDict, UserString, UserList
 from collections import ChainMap
 from collections import deque
@@ -313,8 +316,7 @@ class TestNamedTuple(unittest.TestCase):
 
         # n = 5000
         n = 254 # SyntaxError: more than 255 arguments:
-        import string, random
-        names = list(set(''.join([random.choice(string.ascii_letters)
+        names = list(set(''.join([choice(string.ascii_letters)
                                   for j in range(10)]) for i in range(n)))
         n = len(names)
         Big = namedtuple('Big', names)
@@ -1621,694 +1623,13 @@ class TestCounter(unittest.TestCase):
 
 
 ################################################################################
-### OrderedDict
-################################################################################
-
-py_coll = import_fresh_module('collections', blocked=['_collections'])
-c_coll = import_fresh_module('collections', fresh=['_collections'])
-
-
-@contextlib.contextmanager
-def replaced_module(name, replacement):
-    original_module = sys.modules[name]
-    sys.modules[name] = replacement
-    try:
-        yield
-    finally:
-        sys.modules[name] = original_module
-
-
-class OrderedDictTests:
-
-    def test_init(self):
-        OrderedDict = self.OrderedDict
-        with self.assertRaises(TypeError):
-            OrderedDict([('a', 1), ('b', 2)], None)                                 # too many args
-        pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
-        self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs)           # dict input
-        self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs)         # kwds input
-        self.assertEqual(list(OrderedDict(pairs).items()), pairs)                   # pairs input
-        self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
-                                          c=3, e=5).items()), pairs)                # mixed input
-
-        # make sure no positional args conflict with possible kwdargs
-        self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)])
-        self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)])
-        self.assertRaises(TypeError, OrderedDict, 42)
-        self.assertRaises(TypeError, OrderedDict, (), ())
-        self.assertRaises(TypeError, OrderedDict.__init__)
-
-        # Make sure that direct calls to __init__ do not clear previous contents
-        d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
-        d.__init__([('e', 5), ('f', 6)], g=7, d=4)
-        self.assertEqual(list(d.items()),
-            [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
-
-    def test_update(self):
-        OrderedDict = self.OrderedDict
-        with self.assertRaises(TypeError):
-            OrderedDict().update([('a', 1), ('b', 2)], None)                        # too many args
-        pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
-        od = OrderedDict()
-        od.update(dict(pairs))
-        self.assertEqual(sorted(od.items()), pairs)                                 # dict input
-        od = OrderedDict()
-        od.update(**dict(pairs))
-        self.assertEqual(sorted(od.items()), pairs)                                 # kwds input
-        od = OrderedDict()
-        od.update(pairs)
-        self.assertEqual(list(od.items()), pairs)                                   # pairs input
-        od = OrderedDict()
-        od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
-        self.assertEqual(list(od.items()), pairs)                                   # mixed input
-
-        # Issue 9137: Named argument called 'other' or 'self'
-        # shouldn't be treated specially.
-        od = OrderedDict()
-        od.update(self=23)
-        self.assertEqual(list(od.items()), [('self', 23)])
-        od = OrderedDict()
-        od.update(other={})
-        self.assertEqual(list(od.items()), [('other', {})])
-        od = OrderedDict()
-        od.update(red=5, blue=6, other=7, self=8)
-        self.assertEqual(sorted(list(od.items())),
-                         [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
-
-        # Make sure that direct calls to update do not clear previous contents
-        # add that updates items are not moved to the end
-        d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
-        d.update([('e', 5), ('f', 6)], g=7, d=4)
-        self.assertEqual(list(d.items()),
-            [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
-
-        self.assertRaises(TypeError, OrderedDict().update, 42)
-        self.assertRaises(TypeError, OrderedDict().update, (), ())
-        self.assertRaises(TypeError, OrderedDict.update)
-
-        self.assertRaises(TypeError, OrderedDict().update, 42)
-        self.assertRaises(TypeError, OrderedDict().update, (), ())
-        self.assertRaises(TypeError, OrderedDict.update)
-
-    def test_fromkeys(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict.fromkeys('abc')
-        self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
-        od = OrderedDict.fromkeys('abc', value=None)
-        self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
-        od = OrderedDict.fromkeys('abc', value=0)
-        self.assertEqual(list(od.items()), [(c, 0) for c in 'abc'])
-
-    def test_abc(self):
-        OrderedDict = self.OrderedDict
-        self.assertIsInstance(OrderedDict(), MutableMapping)
-        self.assertTrue(issubclass(OrderedDict, MutableMapping))
-
-    def test_clear(self):
-        OrderedDict = self.OrderedDict
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        shuffle(pairs)
-        od = OrderedDict(pairs)
-        self.assertEqual(len(od), len(pairs))
-        od.clear()
-        self.assertEqual(len(od), 0)
-
-    def test_delitem(self):
-        OrderedDict = self.OrderedDict
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        od = OrderedDict(pairs)
-        del od['a']
-        self.assertNotIn('a', od)
-        with self.assertRaises(KeyError):
-            del od['a']
-        self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
-
-    def test_setitem(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
-        od['c'] = 10           # existing element
-        od['f'] = 20           # new element
-        self.assertEqual(list(od.items()),
-                         [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
-
-    def test_iterators(self):
-        OrderedDict = self.OrderedDict
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        shuffle(pairs)
-        od = OrderedDict(pairs)
-        self.assertEqual(list(od), [t[0] for t in pairs])
-        self.assertEqual(list(od.keys()), [t[0] for t in pairs])
-        self.assertEqual(list(od.values()), [t[1] for t in pairs])
-        self.assertEqual(list(od.items()), pairs)
-        self.assertEqual(list(reversed(od)),
-                         [t[0] for t in reversed(pairs)])
-        self.assertEqual(list(reversed(od.keys())),
-                         [t[0] for t in reversed(pairs)])
-        self.assertEqual(list(reversed(od.values())),
-                         [t[1] for t in reversed(pairs)])
-        self.assertEqual(list(reversed(od.items())), list(reversed(pairs)))
-
-    def test_detect_deletion_during_iteration(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict.fromkeys('abc')
-        it = iter(od)
-        key = next(it)
-        del od[key]
-        with self.assertRaises(Exception):
-            # Note, the exact exception raised is not guaranteed
-            # The only guarantee that the next() will not succeed
-            next(it)
-
-    def test_sorted_iterators(self):
-        OrderedDict = self.OrderedDict
-        with self.assertRaises(TypeError):
-            OrderedDict([('a', 1), ('b', 2)], None)
-        pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
-        od = OrderedDict(pairs)
-        self.assertEqual(sorted(od), [t[0] for t in pairs])
-        self.assertEqual(sorted(od.keys()), [t[0] for t in pairs])
-        self.assertEqual(sorted(od.values()), [t[1] for t in pairs])
-        self.assertEqual(sorted(od.items()), pairs)
-        self.assertEqual(sorted(reversed(od)),
-                         sorted([t[0] for t in reversed(pairs)]))
-
-    def test_iterators_empty(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict()
-        empty = []
-        self.assertEqual(list(od), empty)
-        self.assertEqual(list(od.keys()), empty)
-        self.assertEqual(list(od.values()), empty)
-        self.assertEqual(list(od.items()), empty)
-        self.assertEqual(list(reversed(od)), empty)
-        self.assertEqual(list(reversed(od.keys())), empty)
-        self.assertEqual(list(reversed(od.values())), empty)
-        self.assertEqual(list(reversed(od.items())), empty)
-
-    def test_popitem(self):
-        OrderedDict = self.OrderedDict
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        shuffle(pairs)
-        od = OrderedDict(pairs)
-        while pairs:
-            self.assertEqual(od.popitem(), pairs.pop())
-        with self.assertRaises(KeyError):
-            od.popitem()
-        self.assertEqual(len(od), 0)
-
-    def test_popitem_last(self):
-        OrderedDict = self.OrderedDict
-        pairs = [(i, i) for i in range(30)]
-
-        obj = OrderedDict(pairs)
-        for i in range(8):
-            obj.popitem(True)
-        obj.popitem(True)
-        obj.popitem(last=True)
-        self.assertEqual(len(obj), 20)
-
-    def test_pop(self):
-        OrderedDict = self.OrderedDict
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        shuffle(pairs)
-        od = OrderedDict(pairs)
-        shuffle(pairs)
-        while pairs:
-            k, v = pairs.pop()
-            self.assertEqual(od.pop(k), v)
-        with self.assertRaises(KeyError):
-            od.pop('xyz')
-        self.assertEqual(len(od), 0)
-        self.assertEqual(od.pop(k, 12345), 12345)
-
-        # make sure pop still works when __missing__ is defined
-        class Missing(OrderedDict):
-            def __missing__(self, key):
-                return 0
-        m = Missing(a=1)
-        self.assertEqual(m.pop('b', 5), 5)
-        self.assertEqual(m.pop('a', 6), 1)
-        self.assertEqual(m.pop('a', 6), 6)
-        self.assertEqual(m.pop('a', default=6), 6)
-        with self.assertRaises(KeyError):
-            m.pop('a')
-
-    def test_equality(self):
-        OrderedDict = self.OrderedDict
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        shuffle(pairs)
-        od1 = OrderedDict(pairs)
-        od2 = OrderedDict(pairs)
-        self.assertEqual(od1, od2)          # same order implies equality
-        pairs = pairs[2:] + pairs[:2]
-        od2 = OrderedDict(pairs)
-        self.assertNotEqual(od1, od2)       # different order implies inequality
-        # comparison to regular dict is not order sensitive
-        self.assertEqual(od1, dict(od2))
-        self.assertEqual(dict(od2), od1)
-        # different length implied inequality
-        self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
-
-    def test_copying(self):
-        OrderedDict = self.OrderedDict
-        # Check that ordered dicts are copyable, deepcopyable, picklable,
-        # and have a repr/eval round-trip
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        od = OrderedDict(pairs)
-        def check(dup):
-            msg = "\ncopy: %s\nod: %s" % (dup, od)
-            self.assertIsNot(dup, od, msg)
-            self.assertEqual(dup, od)
-            self.assertEqual(list(dup.items()), list(od.items()))
-            self.assertEqual(len(dup), len(od))
-            self.assertEqual(type(dup), type(od))
-        check(od.copy())
-        check(copy.copy(od))
-        check(copy.deepcopy(od))
-        # pickle directly pulls the module, so we have to fake it
-        with replaced_module('collections', self.module):
-            for proto in range(pickle.HIGHEST_PROTOCOL + 1):
-                with self.subTest(proto=proto):
-                    check(pickle.loads(pickle.dumps(od, proto)))
-        check(eval(repr(od)))
-        update_test = OrderedDict()
-        update_test.update(od)
-        check(update_test)
-        check(OrderedDict(od))
-
-    def test_yaml_linkage(self):
-        OrderedDict = self.OrderedDict
-        # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
-        # In yaml, lists are native but tuples are not.
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        od = OrderedDict(pairs)
-        # yaml.dump(od) -->
-        # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n  - [b, 2]\n'
-        self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
-
-    def test_reduce_not_too_fat(self):
-        OrderedDict = self.OrderedDict
-        # do not save instance dictionary if not needed
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        od = OrderedDict(pairs)
-        self.assertIsNone(od.__reduce__()[2])
-        od.x = 10
-        self.assertIsNotNone(od.__reduce__()[2])
-
-    def test_pickle_recursive(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict()
-        od[1] = od
-
-        # pickle directly pulls the module, so we have to fake it
-        with replaced_module('collections', self.module):
-            for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1):
-                dup = pickle.loads(pickle.dumps(od, proto))
-                self.assertIsNot(dup, od)
-                self.assertEqual(list(dup.keys()), [1])
-                self.assertIs(dup[1], dup)
-
-    def test_repr(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
-        self.assertEqual(repr(od),
-            "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
-        self.assertEqual(eval(repr(od)), od)
-        self.assertEqual(repr(OrderedDict()), "OrderedDict()")
-
-    def test_repr_recursive(self):
-        OrderedDict = self.OrderedDict
-        # See issue #9826
-        od = OrderedDict.fromkeys('abc')
-        od['x'] = od
-        self.assertEqual(repr(od),
-            "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
-
-    def test_setdefault(self):
-        OrderedDict = self.OrderedDict
-        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
-        shuffle(pairs)
-        od = OrderedDict(pairs)
-        pair_order = list(od.items())
-        self.assertEqual(od.setdefault('a', 10), 3)
-        # make sure order didn't change
-        self.assertEqual(list(od.items()), pair_order)
-        self.assertEqual(od.setdefault('x', 10), 10)
-        # make sure 'x' is added to the end
-        self.assertEqual(list(od.items())[-1], ('x', 10))
-        self.assertEqual(od.setdefault('g', default=9), 9)
-
-        # make sure setdefault still works when __missing__ is defined
-        class Missing(OrderedDict):
-            def __missing__(self, key):
-                return 0
-        self.assertEqual(Missing().setdefault(5, 9), 9)
-
-    def test_reinsert(self):
-        OrderedDict = self.OrderedDict
-        # Given insert a, insert b, delete a, re-insert a,
-        # verify that a is now later than b.
-        od = OrderedDict()
-        od['a'] = 1
-        od['b'] = 2
-        del od['a']
-        self.assertEqual(list(od.items()), [('b', 2)])
-        od['a'] = 1
-        self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
-
-    def test_move_to_end(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict.fromkeys('abcde')
-        self.assertEqual(list(od), list('abcde'))
-        od.move_to_end('c')
-        self.assertEqual(list(od), list('abdec'))
-        od.move_to_end('c', 0)
-        self.assertEqual(list(od), list('cabde'))
-        od.move_to_end('c', 0)
-        self.assertEqual(list(od), list('cabde'))
-        od.move_to_end('e')
-        self.assertEqual(list(od), list('cabde'))
-        od.move_to_end('b', last=False)
-        self.assertEqual(list(od), list('bcade'))
-        with self.assertRaises(KeyError):
-            od.move_to_end('x')
-        with self.assertRaises(KeyError):
-            od.move_to_end('x', 0)
-
-    def test_move_to_end_issue25406(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict.fromkeys('abc')
-        od.move_to_end('c', last=False)
-        self.assertEqual(list(od), list('cab'))
-        od.move_to_end('a', last=False)
-        self.assertEqual(list(od), list('acb'))
-
-        od = OrderedDict.fromkeys('abc')
-        od.move_to_end('a')
-        self.assertEqual(list(od), list('bca'))
-        od.move_to_end('c')
-        self.assertEqual(list(od), list('bac'))
-
-    def test_sizeof(self):
-        OrderedDict = self.OrderedDict
-        # Wimpy test: Just verify the reported size is larger than a regular dict
-        d = dict(a=1)
-        od = OrderedDict(**d)
-        self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
-
-    def test_override_update(self):
-        OrderedDict = self.OrderedDict
-        # Verify that subclasses can override update() without breaking __init__()
-        class MyOD(OrderedDict):
-            def update(self, *args, **kwds):
-                raise Exception()
-        items = [('a', 1), ('c', 3), ('b', 2)]
-        self.assertEqual(list(MyOD(items).items()), items)
-
-    def test_highly_nested(self):
-        # Issue 25395: crashes during garbage collection
-        OrderedDict = self.OrderedDict
-        obj = None
-        for _ in range(1000):
-            obj = OrderedDict([(None, obj)])
-        del obj
-        support.gc_collect()
-
-    def test_highly_nested_subclass(self):
-        # Issue 25395: crashes during garbage collection
-        OrderedDict = self.OrderedDict
-        deleted = []
-        class MyOD(OrderedDict):
-            def __del__(self):
-                deleted.append(self.i)
-        obj = None
-        for i in range(100):
-            obj = MyOD([(None, obj)])
-            obj.i = i
-        del obj
-        support.gc_collect()
-        self.assertEqual(deleted, list(reversed(range(100))))
-
-    def test_delitem_hash_collision(self):
-        OrderedDict = self.OrderedDict
-
-        class Key:
-            def __init__(self, hash):
-                self._hash = hash
-                self.value = str(id(self))
-            def __hash__(self):
-                return self._hash
-            def __eq__(self, other):
-                try:
-                    return self.value == other.value
-                except AttributeError:
-                    return False
-            def __repr__(self):
-                return self.value
-
-        def blocking_hash(hash):
-            # See the collision-handling in lookdict (in Objects/dictobject.c).
-            MINSIZE = 8
-            i = (hash & MINSIZE-1)
-            return (i << 2) + i + hash + 1
-
-        COLLIDING = 1
-
-        key = Key(COLLIDING)
-        colliding = Key(COLLIDING)
-        blocking = Key(blocking_hash(COLLIDING))
-
-        od = OrderedDict()
-        od[key] = ...
-        od[blocking] = ...
-        od[colliding] = ...
-        od['after'] = ...
-
-        del od[blocking]
-        del od[colliding]
-        self.assertEqual(list(od.items()), [(key, ...), ('after', ...)])
-
-    def test_issue24347(self):
-        OrderedDict = self.OrderedDict
-
-        class Key:
-            def __hash__(self):
-                return randrange(100000)
-
-        od = OrderedDict()
-        for i in range(100):
-            key = Key()
-            od[key] = i
-
-        # These should not crash.
-        with self.assertRaises(KeyError):
-            list(od.values())
-        with self.assertRaises(KeyError):
-            list(od.items())
-        with self.assertRaises(KeyError):
-            repr(od)
-        with self.assertRaises(KeyError):
-            od.copy()
-
-    def test_issue24348(self):
-        OrderedDict = self.OrderedDict
-
-        class Key:
-            def __hash__(self):
-                return 1
-
-        od = OrderedDict()
-        od[Key()] = 0
-        # This should not crash.
-        od.popitem()
-
-    def test_issue24667(self):
-        """
-        dict resizes after a certain number of insertion operations,
-        whether or not there were deletions that freed up slots in the
-        hash table.  During fast node lookup, OrderedDict must correctly
-        respond to all resizes, even if the current "size" is the same
-        as the old one.  We verify that here by forcing a dict resize
-        on a sparse odict and then perform an operation that should
-        trigger an odict resize (e.g. popitem).  One key aspect here is
-        that we will keep the size of the odict the same at each popitem
-        call.  This verifies that we handled the dict resize properly.
-        """
-        OrderedDict = self.OrderedDict
-
-        od = OrderedDict()
-        for c0 in '0123456789ABCDEF':
-            for c1 in '0123456789ABCDEF':
-                if len(od) == 4:
-                    # This should not raise a KeyError.
-                    od.popitem(last=False)
-                key = c0 + c1
-                od[key] = key
-
-    # Direct use of dict methods
-
-    def test_dict_setitem(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict()
-        dict.__setitem__(od, 'spam', 1)
-        self.assertNotIn('NULL', repr(od))
-
-    def test_dict_delitem(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict()
-        od['spam'] = 1
-        od['ham'] = 2
-        dict.__delitem__(od, 'spam')
-        with self.assertRaises(KeyError):
-            repr(od)
-
-    def test_dict_clear(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict()
-        od['spam'] = 1
-        od['ham'] = 2
-        dict.clear(od)
-        self.assertNotIn('NULL', repr(od))
-
-    def test_dict_pop(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict()
-        od['spam'] = 1
-        od['ham'] = 2
-        dict.pop(od, 'spam')
-        with self.assertRaises(KeyError):
-            repr(od)
-
-    def test_dict_popitem(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict()
-        od['spam'] = 1
-        od['ham'] = 2
-        dict.popitem(od)
-        with self.assertRaises(KeyError):
-            repr(od)
-
-    def test_dict_setdefault(self):
-        OrderedDict = self.OrderedDict
-        od = OrderedDict()
-        dict.setdefault(od, 'spam', 1)
-        self.assertNotIn('NULL', repr(od))
-
-    def test_dict_update(self):
-        od = OrderedDict()
-        dict.update(od, [('spam', 1)])
-        self.assertNotIn('NULL', repr(od))
-
-
-class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
-
-    module = py_coll
-    OrderedDict = py_coll.OrderedDict
-
-
-@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
-class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
-
-    module = c_coll
-    OrderedDict = c_coll.OrderedDict
-
-    def test_key_change_during_iteration(self):
-        OrderedDict = self.OrderedDict
-
-        od = OrderedDict.fromkeys('abcde')
-        self.assertEqual(list(od), list('abcde'))
-        with self.assertRaises(RuntimeError):
-            for i, k in enumerate(od):
-                od.move_to_end(k)
-                self.assertLess(i, 5)
-        with self.assertRaises(RuntimeError):
-            for k in od:
-                od['f'] = None
-        with self.assertRaises(RuntimeError):
-            for k in od:
-                del od['c']
-        self.assertEqual(list(od), list('bdeaf'))
-
-
-class PurePythonOrderedDictSubclassTests(PurePythonOrderedDictTests):
-
-    module = py_coll
-    class OrderedDict(py_coll.OrderedDict):
-        pass
-
-
-class CPythonOrderedDictSubclassTests(CPythonOrderedDictTests):
-
-    module = c_coll
-    class OrderedDict(c_coll.OrderedDict):
-        pass
-
-
-class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
-
-    @classmethod
-    def setUpClass(cls):
-        cls.type2test = py_coll.OrderedDict
-
-    def test_popitem(self):
-        d = self._empty_mapping()
-        self.assertRaises(KeyError, d.popitem)
-
-
-@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
-class CPythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
-
-    @classmethod
-    def setUpClass(cls):
-        cls.type2test = c_coll.OrderedDict
-
-    def test_popitem(self):
-        d = self._empty_mapping()
-        self.assertRaises(KeyError, d.popitem)
-
-
-class PurePythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
-
-    @classmethod
-    def setUpClass(cls):
-        class MyOrderedDict(py_coll.OrderedDict):
-            pass
-        cls.type2test = MyOrderedDict
-
-    def test_popitem(self):
-        d = self._empty_mapping()
-        self.assertRaises(KeyError, d.popitem)
-
-
-@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
-class CPythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
-
-    @classmethod
-    def setUpClass(cls):
-        class MyOrderedDict(c_coll.OrderedDict):
-            pass
-        cls.type2test = MyOrderedDict
-
-    def test_popitem(self):
-        d = self._empty_mapping()
-        self.assertRaises(KeyError, d.popitem)
-
-
-################################################################################
 ### Run tests
 ################################################################################
 
-import doctest, collections
-
 def test_main(verbose=None):
     NamedTupleDocs = doctest.DocTestSuite(module=collections)
     test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
                     TestCollectionABCs, TestCounter, TestChainMap,
-                    PurePythonOrderedDictTests, CPythonOrderedDictTests,
-                    PurePythonOrderedDictSubclassTests,
-                    CPythonOrderedDictSubclassTests,
-                    PurePythonGeneralMappingTests, CPythonGeneralMappingTests,
-                    PurePythonSubclassMappingTests, CPythonSubclassMappingTests,
                     TestUserObjects,
                     ]
     support.run_unittest(*test_classes)
index 8935c65..e0fdee3 100644 (file)
@@ -572,6 +572,88 @@ if 1:
         exec(memoryview(b"ax = 123")[1:-1], namespace)
         self.assertEqual(namespace['x'], 12)
 
+    def check_constant(self, func, expected):
+        for const in func.__code__.co_consts:
+            if repr(const) == repr(expected):
+                break
+        else:
+            self.fail("unable to find constant %r in %r"
+                      % (expected, func.__code__.co_consts))
+
+    # Merging equal constants is not a strict requirement for the Python
+    # semantics, it's a more an implementation detail.
+    @support.cpython_only
+    def test_merge_constants(self):
+        # Issue #25843: compile() must merge constants which are equal
+        # and have the same type.
+
+        def check_same_constant(const):
+            ns = {}
+            code = "f1, f2 = lambda: %r, lambda: %r" % (const, const)
+            exec(code, ns)
+            f1 = ns['f1']
+            f2 = ns['f2']
+            self.assertIs(f1.__code__, f2.__code__)
+            self.check_constant(f1, const)
+            self.assertEqual(repr(f1()), repr(const))
+
+        check_same_constant(None)
+        check_same_constant(0)
+        check_same_constant(0.0)
+        check_same_constant(b'abc')
+        check_same_constant('abc')
+
+        # Note: "lambda: ..." emits "LOAD_CONST Ellipsis",
+        # whereas "lambda: Ellipsis" emits "LOAD_GLOBAL Ellipsis"
+        f1, f2 = lambda: ..., lambda: ...
+        self.assertIs(f1.__code__, f2.__code__)
+        self.check_constant(f1, Ellipsis)
+        self.assertEqual(repr(f1()), repr(Ellipsis))
+
+        # {0} is converted to a constant frozenset({0}) by the peephole
+        # optimizer
+        f1, f2 = lambda x: x in {0}, lambda x: x in {0}
+        self.assertIs(f1.__code__, f2.__code__)
+        self.check_constant(f1, frozenset({0}))
+        self.assertTrue(f1(0))
+
+    def test_dont_merge_constants(self):
+        # Issue #25843: compile() must not merge constants which are equal
+        # but have a different type.
+
+        def check_different_constants(const1, const2):
+            ns = {}
+            exec("f1, f2 = lambda: %r, lambda: %r" % (const1, const2), ns)
+            f1 = ns['f1']
+            f2 = ns['f2']
+            self.assertIsNot(f1.__code__, f2.__code__)
+            self.check_constant(f1, const1)
+            self.check_constant(f2, const2)
+            self.assertEqual(repr(f1()), repr(const1))
+            self.assertEqual(repr(f2()), repr(const2))
+
+        check_different_constants(0, 0.0)
+        check_different_constants(+0.0, -0.0)
+        check_different_constants((0,), (0.0,))
+
+        # check_different_constants() cannot be used because repr(-0j) is
+        # '(-0-0j)', but when '(-0-0j)' is evaluated to 0j: we loose the sign.
+        f1, f2 = lambda: +0.0j, lambda: -0.0j
+        self.assertIsNot(f1.__code__, f2.__code__)
+        self.check_constant(f1, +0.0j)
+        self.check_constant(f2, -0.0j)
+        self.assertEqual(repr(f1()), repr(+0.0j))
+        self.assertEqual(repr(f2()), repr(-0.0j))
+
+        # {0} is converted to a constant frozenset({0}) by the peephole
+        # optimizer
+        f1, f2 = lambda x: x in {0}, lambda x: x in {0.0}
+        self.assertIsNot(f1.__code__, f2.__code__)
+        self.check_constant(f1, frozenset({0}))
+        self.check_constant(f2, frozenset({0.0}))
+        self.assertTrue(f1(0))
+        self.assertTrue(f2(0.0))
+
 
 class TestStackSize(unittest.TestCase):
     # These tests check that the computed stack size for a code object
index ef2b669..2ce8a61 100644 (file)
@@ -398,14 +398,6 @@ class CommandLineTests(unittest.TestCase):
         self.assertCompiled(init2fn)
         self.assertCompiled(bar2fn)
 
-    def test_d_takes_exactly_one_dir(self):
-        rc, out, err = self.assertRunNotOK('-d', 'foo')
-        self.assertEqual(out, b'')
-        self.assertRegex(err, b'-d')
-        rc, out, err = self.assertRunNotOK('-d', 'foo', 'bar')
-        self.assertEqual(out, b'')
-        self.assertRegex(err, b'-d')
-
     def test_d_compile_error(self):
         script_helper.make_script(self.pkgdir, 'crunchyfrog', 'bad(syntax')
         rc, out, err = self.assertRunNotOK('-q', '-d', 'dinsdale', self.pkgdir)
index b99740b..cdb9308 100644 (file)
@@ -676,7 +676,7 @@ class FutureTests(unittest.TestCase):
         self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42)
 
     def test_result_with_success(self):
-        # TODO(brian@sweetapp.com): This test is timing dependant.
+        # TODO(brian@sweetapp.com): This test is timing dependent.
         def notification():
             # Wait until the main thread is waiting for the result.
             time.sleep(1)
@@ -689,7 +689,7 @@ class FutureTests(unittest.TestCase):
         self.assertEqual(f1.result(timeout=5), 42)
 
     def test_result_with_cancel(self):
-        # TODO(brian@sweetapp.com): This test is timing dependant.
+        # TODO(brian@sweetapp.com): This test is timing dependent.
         def notification():
             # Wait until the main thread is waiting for the result.
             time.sleep(1)
index b9eaddd..0e1f670 100644 (file)
@@ -95,24 +95,67 @@ class TestCopy(unittest.TestCase):
             pass
         class WithMetaclass(metaclass=abc.ABCMeta):
             pass
-        tests = [None, 42, 2**100, 3.14, True, False, 1j,
+        tests = [None, ..., NotImplemented,
+                 42, 2**100, 3.14, True, False, 1j,
                  "hello", "hello\u1234", f.__code__,
-                 b"world", bytes(range(256)),
-                 NewStyle, range(10), Classic, max, WithMetaclass]
+                 b"world", bytes(range(256)), range(10),
+                 NewStyle, Classic, max, WithMetaclass]
         for x in tests:
             self.assertIs(copy.copy(x), x)
 
     def test_copy_list(self):
         x = [1, 2, 3]
-        self.assertEqual(copy.copy(x), x)
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        x = []
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
 
     def test_copy_tuple(self):
         x = (1, 2, 3)
-        self.assertEqual(copy.copy(x), x)
+        self.assertIs(copy.copy(x), x)
+        x = ()
+        self.assertIs(copy.copy(x), x)
+        x = (1, 2, 3, [])
+        self.assertIs(copy.copy(x), x)
 
     def test_copy_dict(self):
         x = {"foo": 1, "bar": 2}
-        self.assertEqual(copy.copy(x), x)
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        x = {}
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+
+    def test_copy_set(self):
+        x = {1, 2, 3}
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        x = set()
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+
+    def test_copy_frozenset(self):
+        x = frozenset({1, 2, 3})
+        self.assertIs(copy.copy(x), x)
+        x = frozenset()
+        self.assertIs(copy.copy(x), x)
+
+    def test_copy_bytearray(self):
+        x = bytearray(b'abc')
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        x = bytearray()
+        y = copy.copy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
 
     def test_copy_inst_vanilla(self):
         class C:
@@ -213,6 +256,9 @@ class TestCopy(unittest.TestCase):
                 return self.foo == other.foo
         x = C(42)
         self.assertEqual(copy.copy(x), x)
+        # State with boolean value is false (issue #25718)
+        x = C(0.0)
+        self.assertEqual(copy.copy(x), x)
 
     # The deepcopy() method
 
@@ -311,7 +357,7 @@ class TestCopy(unittest.TestCase):
             pass
         tests = [None, 42, 2**100, 3.14, True, False, 1j,
                  "hello", "hello\u1234", f.__code__,
-                 NewStyle, range(10), Classic, max]
+                 NewStyle, Classic, max]
         for x in tests:
             self.assertIs(copy.deepcopy(x), x)
 
@@ -517,6 +563,12 @@ class TestCopy(unittest.TestCase):
         self.assertEqual(y, x)
         self.assertIsNot(y, x)
         self.assertIsNot(y.foo, x.foo)
+        # State with boolean value is false (issue #25718)
+        x = C([])
+        y = copy.deepcopy(x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        self.assertIsNot(y.foo, x.foo)
 
     def test_deepcopy_reflexive_inst(self):
         class C:
@@ -527,6 +579,17 @@ class TestCopy(unittest.TestCase):
         self.assertIsNot(y, x)
         self.assertIs(y.foo, y)
 
+    def test_deepcopy_range(self):
+        class I(int):
+            pass
+        x = range(I(10))
+        y = copy.deepcopy(x)
+        self.assertIsNot(y, x)
+        self.assertEqual(y, x)
+        self.assertIsNot(y.stop, x.stop)
+        self.assertEqual(y.stop, x.stop)
+        self.assertIsInstance(y.stop, I)
+
     # _reconstruct()
 
     def test_reconstruct_string(self):
index 07c1cdf..4f725ae 100644 (file)
@@ -569,6 +569,147 @@ class CoroutineTest(unittest.TestCase):
                                     "coroutine ignored GeneratorExit"):
             c.close()
 
+    def test_func_15(self):
+        # See http://bugs.python.org/issue25887 for details
+
+        async def spammer():
+            return 'spam'
+        async def reader(coro):
+            return await coro
+
+        spammer_coro = spammer()
+
+        with self.assertRaisesRegex(StopIteration, 'spam'):
+            reader(spammer_coro).send(None)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            reader(spammer_coro).send(None)
+
+    def test_func_16(self):
+        # See http://bugs.python.org/issue25887 for details
+
+        @types.coroutine
+        def nop():
+            yield
+        async def send():
+            await nop()
+            return 'spam'
+        async def read(coro):
+            await nop()
+            return await coro
+
+        spammer = send()
+
+        reader = read(spammer)
+        reader.send(None)
+        reader.send(None)
+        with self.assertRaisesRegex(Exception, 'ham'):
+            reader.throw(Exception('ham'))
+
+        reader = read(spammer)
+        reader.send(None)
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            reader.send(None)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            reader.throw(Exception('wat'))
+
+    def test_func_17(self):
+        # See http://bugs.python.org/issue25887 for details
+
+        async def coroutine():
+            return 'spam'
+
+        coro = coroutine()
+        with self.assertRaisesRegex(StopIteration, 'spam'):
+            coro.send(None)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            coro.send(None)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            coro.throw(Exception('wat'))
+
+        # Closing a coroutine shouldn't raise any exception even if it's
+        # already closed/exhausted (similar to generators)
+        coro.close()
+        coro.close()
+
+    def test_func_18(self):
+        # See http://bugs.python.org/issue25887 for details
+
+        async def coroutine():
+            return 'spam'
+
+        coro = coroutine()
+        await_iter = coro.__await__()
+        it = iter(await_iter)
+
+        with self.assertRaisesRegex(StopIteration, 'spam'):
+            it.send(None)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            it.send(None)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            # Although the iterator protocol requires iterators to
+            # raise another StopIteration here, we don't want to do
+            # that.  In this particular case, the iterator will raise
+            # a RuntimeError, so that 'yield from' and 'await'
+            # expressions will trigger the error, instead of silently
+            # ignoring the call.
+            next(it)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            it.throw(Exception('wat'))
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    'cannot reuse already awaited coroutine'):
+            it.throw(Exception('wat'))
+
+        # Closing a coroutine shouldn't raise any exception even if it's
+        # already closed/exhausted (similar to generators)
+        it.close()
+        it.close()
+
+    def test_func_19(self):
+        CHK = 0
+
+        @types.coroutine
+        def foo():
+            nonlocal CHK
+            yield
+            try:
+                yield
+            except GeneratorExit:
+                CHK += 1
+
+        async def coroutine():
+            await foo()
+
+        coro = coroutine()
+
+        coro.send(None)
+        coro.send(None)
+
+        self.assertEqual(CHK, 0)
+        coro.close()
+        self.assertEqual(CHK, 1)
+
+        for _ in range(3):
+            # Closing a coroutine shouldn't raise any exception even if it's
+            # already closed/exhausted (similar to generators)
+            coro.close()
+            self.assertEqual(CHK, 1)
+
     def test_cr_await(self):
         @types.coroutine
         def a():
@@ -801,6 +942,24 @@ class CoroutineTest(unittest.TestCase):
         with self.assertRaises(Marker):
             c.throw(ZeroDivisionError)
 
+    def test_await_15(self):
+        @types.coroutine
+        def nop():
+            yield
+
+        async def coroutine():
+            await nop()
+
+        async def waiter(coro):
+            await coro
+
+        coro = coroutine()
+        coro.send(None)
+
+        with self.assertRaisesRegex(RuntimeError,
+                                    "coroutine is being awaited already"):
+            waiter(coro).send(None)
+
     def test_with_1(self):
         class Manager:
             def __init__(self, name):
@@ -1096,8 +1255,9 @@ class CoroutineTest(unittest.TestCase):
 
         buffer = []
         async def test1():
-            async for i1, i2 in AsyncIter():
-                buffer.append(i1 + i2)
+            with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+                async for i1, i2 in AsyncIter():
+                    buffer.append(i1 + i2)
 
         yielded, _ = run_async(test1())
         # Make sure that __aiter__ was called only once
@@ -1109,12 +1269,13 @@ class CoroutineTest(unittest.TestCase):
         buffer = []
         async def test2():
             nonlocal buffer
-            async for i in AsyncIter():
-                buffer.append(i[0])
-                if i[0] == 20:
-                    break
-            else:
-                buffer.append('what?')
+            with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+                async for i in AsyncIter():
+                    buffer.append(i[0])
+                    if i[0] == 20:
+                        break
+                else:
+                    buffer.append('what?')
             buffer.append('end')
 
         yielded, _ = run_async(test2())
@@ -1127,12 +1288,13 @@ class CoroutineTest(unittest.TestCase):
         buffer = []
         async def test3():
             nonlocal buffer
-            async for i in AsyncIter():
-                if i[0] > 20:
-                    continue
-                buffer.append(i[0])
-            else:
-                buffer.append('what?')
+            with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+                async for i in AsyncIter():
+                    if i[0] > 20:
+                        continue
+                    buffer.append(i[0])
+                else:
+                    buffer.append('what?')
             buffer.append('end')
 
         yielded, _ = run_async(test3())
@@ -1179,7 +1341,7 @@ class CoroutineTest(unittest.TestCase):
 
     def test_for_4(self):
         class I:
-            async def __aiter__(self):
+            def __aiter__(self):
                 return self
 
             def __anext__(self):
@@ -1209,8 +1371,9 @@ class CoroutineTest(unittest.TestCase):
                 return 123
 
         async def foo():
-            async for i in I():
-                print('never going to happen')
+            with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+                async for i in I():
+                    print('never going to happen')
 
         with self.assertRaisesRegex(
                 TypeError,
@@ -1234,7 +1397,7 @@ class CoroutineTest(unittest.TestCase):
             def __init__(self):
                 self.i = 0
 
-            async def __aiter__(self):
+            def __aiter__(self):
                 return self
 
             async def __anext__(self):
@@ -1258,7 +1421,11 @@ class CoroutineTest(unittest.TestCase):
                     I += 1
             I += 1000
 
-        run_async(main())
+        with warnings.catch_warnings():
+            warnings.simplefilter("error")
+            # Test that __aiter__ that returns an asyncronous iterator
+            # directly does not throw any warnings.
+            run_async(main())
         self.assertEqual(I, 111011)
 
         self.assertEqual(sys.getrefcount(manager), mrefs_before)
@@ -1313,13 +1480,63 @@ class CoroutineTest(unittest.TestCase):
                 1/0
         async def foo():
             nonlocal CNT
+            with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
+                async for i in AI():
+                    CNT += 1
+            CNT += 10
+        with self.assertRaises(ZeroDivisionError):
+            run_async(foo())
+        self.assertEqual(CNT, 0)
+
+    def test_for_8(self):
+        CNT = 0
+        class AI:
+            def __aiter__(self):
+                1/0
+        async def foo():
+            nonlocal CNT
             async for i in AI():
                 CNT += 1
             CNT += 10
         with self.assertRaises(ZeroDivisionError):
-            run_async(foo())
+            with warnings.catch_warnings():
+                warnings.simplefilter("error")
+                # Test that if __aiter__ raises an exception it propagates
+                # without any kind of warning.
+                run_async(foo())
         self.assertEqual(CNT, 0)
 
+    def test_for_9(self):
+        # Test that PendingDeprecationWarning can safely be converted into
+        # an exception (__aiter__ should not have a chance to raise
+        # a ZeroDivisionError.)
+        class AI:
+            async def __aiter__(self):
+                1/0
+        async def foo():
+            async for i in AI():
+                pass
+
+        with self.assertRaises(PendingDeprecationWarning):
+            with warnings.catch_warnings():
+                warnings.simplefilter("error")
+                run_async(foo())
+
+    def test_for_10(self):
+        # Test that PendingDeprecationWarning can safely be converted into
+        # an exception.
+        class AI:
+            async def __aiter__(self):
+                pass
+        async def foo():
+            async for i in AI():
+                pass
+
+        with self.assertRaises(PendingDeprecationWarning):
+            with warnings.catch_warnings():
+                warnings.simplefilter("error")
+                run_async(foo())
+
     def test_copy(self):
         async def func(): pass
         coro = func()
index 624d702..e4f5897 100644 (file)
@@ -25,7 +25,7 @@ class CryptTestCase(unittest.TestCase):
             self.assertEqual(len(pw), method.total_size)
 
     def test_methods(self):
-        # Gurantee that METHOD_CRYPT is the last method in crypt.methods.
+        # Guarantee that METHOD_CRYPT is the last method in crypt.methods.
         self.assertTrue(len(crypt.methods) >= 1)
         self.assertEqual(crypt.METHOD_CRYPT, crypt.methods[-1])
 
index 8e9c2b4..77c315e 100644 (file)
@@ -1,6 +1,7 @@
 # Copyright (C) 2001,2002 Python Software Foundation
 # csv package unit tests
 
+import copy
 import io
 import sys
 import os
@@ -9,6 +10,7 @@ from io import StringIO
 from tempfile import TemporaryFile
 import csv
 import gc
+import pickle
 from test import support
 
 class Test_Csv(unittest.TestCase):
@@ -424,6 +426,18 @@ class TestDialectRegistry(unittest.TestCase):
         self.assertRaises(TypeError, csv.reader, [], quoting = -1)
         self.assertRaises(TypeError, csv.reader, [], quoting = 100)
 
+    # See issue #22995
+    ## def test_copy(self):
+    ##     for name in csv.list_dialects():
+    ##         dialect = csv.get_dialect(name)
+    ##         self.assertRaises(TypeError, copy.copy, dialect)
+
+    ## def test_pickle(self):
+    ##     for name in csv.list_dialects():
+    ##         dialect = csv.get_dialect(name)
+    ##         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+    ##             self.assertRaises(TypeError, pickle.dumps, dialect, proto)
+
 class TestCsvBase(unittest.TestCase):
     def readerAssertEqual(self, input, expected_result):
         with TemporaryFile("w+", newline='') as fileobj:
index 2747041..8411cdb 100644 (file)
@@ -24,19 +24,41 @@ requires('curses')
 
 # If either of these don't exist, skip the tests.
 curses = import_module('curses')
-curses.panel = import_module('curses.panel')
+import_module('curses.panel')
+import_module('curses.ascii')
 
-term = os.environ.get('TERM', 'unknown')
+def requires_curses_func(name):
+    return unittest.skipUnless(hasattr(curses, name),
+                               'requires curses.%s' % name)
 
-@unittest.skipUnless(sys.__stdout__.isatty(), 'sys.__stdout__ is not a tty')
-@unittest.skipIf(term == 'unknown',
+term = os.environ.get('TERM')
+
+# If newterm was supported we could use it instead of initscr and not exit
+@unittest.skipIf(not term or term == 'unknown',
                  "$TERM=%r, calling initscr() may cause exit" % term)
 @unittest.skipIf(sys.platform == "cygwin",
                  "cygwin's curses mostly just hangs")
 class TestCurses(unittest.TestCase):
+
     @classmethod
     def setUpClass(cls):
-        curses.setupterm(fd=sys.__stdout__.fileno())
+        if not sys.__stdout__.isatty():
+            # Temporary skip tests on non-tty
+            raise unittest.SkipTest('sys.__stdout__ is not a tty')
+            cls.tmp = tempfile.TemporaryFile()
+            fd = cls.tmp.fileno()
+        else:
+            cls.tmp = None
+            fd = sys.__stdout__.fileno()
+        # testing setupterm() inside initscr/endwin
+        # causes terminal breakage
+        curses.setupterm(fd=fd)
+
+    @classmethod
+    def tearDownClass(cls):
+        if cls.tmp:
+            cls.tmp.close()
+            del cls.tmp
 
     def setUp(self):
         if verbose:
@@ -59,7 +81,8 @@ class TestCurses(unittest.TestCase):
         for meth in [stdscr.addch, stdscr.addstr]:
             for args in [('a'), ('a', curses.A_BOLD),
                          (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
-                meth(*args)
+                with self.subTest(meth=meth.__qualname__, args=args):
+                    meth(*args)
 
         for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
                      stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
@@ -70,7 +93,8 @@ class TestCurses(unittest.TestCase):
                      win.noutrefresh, stdscr.redrawwin, stdscr.refresh,
                      stdscr.standout, stdscr.standend, stdscr.syncdown,
                      stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]:
-            meth()
+            with self.subTest(meth=meth.__qualname__):
+                meth()
 
         stdscr.addnstr('1234', 3)
         stdscr.addnstr('1234', 3, curses.A_BOLD)
@@ -166,7 +190,6 @@ class TestCurses(unittest.TestCase):
 
     def test_module_funcs(self):
         "Test module-level functions"
-        stdscr = self.stdscr
         for func in [curses.baudrate, curses.beep, curses.can_change_color,
                      curses.cbreak, curses.def_prog_mode, curses.doupdate,
                      curses.filter, curses.flash, curses.flushinp,
@@ -176,7 +199,8 @@ class TestCurses(unittest.TestCase):
                      curses.noqiflush, curses.noraw,
                      curses.reset_prog_mode, curses.termattrs,
                      curses.termname, curses.erasechar, curses.getsyx]:
-            func()
+            with self.subTest(func=func.__qualname__):
+                func()
 
         # Functions that actually need arguments
         if curses.tigetstr("cnorm"):
@@ -184,11 +208,10 @@ class TestCurses(unittest.TestCase):
         curses.delay_output(1)
         curses.echo() ; curses.echo(1)
 
-        f = tempfile.TemporaryFile()
-        stdscr.putwin(f)
-        f.seek(0)
-        curses.getwin(f)
-        f.close()
+        with tempfile.TemporaryFile() as f:
+            self.stdscr.putwin(f)
+            f.seek(0)
+            curses.getwin(f)
 
         curses.halfdelay(1)
         curses.intrflush(1)
@@ -211,51 +234,37 @@ class TestCurses(unittest.TestCase):
         curses.ungetch('a')
         curses.use_env(1)
 
-        # Functions only available on a few platforms
-        if curses.has_colors():
-            curses.start_color()
-            curses.init_pair(2, 1,1)
-            curses.color_content(1)
-            curses.color_pair(2)
-            curses.pair_content(curses.COLOR_PAIRS - 1)
-            curses.pair_number(0)
-
-            if hasattr(curses, 'use_default_colors'):
-                curses.use_default_colors()
-
-        if hasattr(curses, 'keyname'):
-            curses.keyname(13)
-
-        if hasattr(curses, 'has_key'):
-            curses.has_key(13)
-
-        if hasattr(curses, 'getmouse'):
-            (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED)
-            # availmask indicates that mouse stuff not available.
-            if availmask != 0:
-                curses.mouseinterval(10)
-                # just verify these don't cause errors
-                curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED)
-                m = curses.getmouse()
-
-        if hasattr(curses, 'is_term_resized'):
-            curses.is_term_resized(*stdscr.getmaxyx())
-        if hasattr(curses, 'resizeterm'):
-            curses.resizeterm(*stdscr.getmaxyx())
-        if hasattr(curses, 'resize_term'):
-            curses.resize_term(*stdscr.getmaxyx())
-
-    def test_unctrl(self):
-        from curses import ascii
-        for ch, expected in [('a', 'a'), ('A', 'A'),
-                             (';', ';'), (' ', ' '),
-                             ('\x7f', '^?'), ('\n', '^J'), ('\0', '^@'),
-                             # Meta-bit characters
-                             ('\x8a', '!^J'), ('\xc1', '!A'),
-                             ]:
-            self.assertEqual(ascii.unctrl(ch), expected,
-                             'curses.unctrl fails on character %r' % ch)
-
+    # Functions only available on a few platforms
+    def test_colors_funcs(self):
+        if not curses.has_colors():
+            self.skip('requires colors support')
+        curses.start_color()
+        curses.init_pair(2, 1,1)
+        curses.color_content(1)
+        curses.color_pair(2)
+        curses.pair_content(curses.COLOR_PAIRS - 1)
+        curses.pair_number(0)
+
+        if hasattr(curses, 'use_default_colors'):
+            curses.use_default_colors()
+
+    @requires_curses_func('keyname')
+    def test_keyname(self):
+        curses.keyname(13)
+
+    @requires_curses_func('has_key')
+    def test_has_key(self):
+        curses.has_key(13)
+
+    @requires_curses_func('getmouse')
+    def test_getmouse(self):
+        (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED)
+        if availmask == 0:
+            self.skip('mouse stuff not available')
+        curses.mouseinterval(10)
+        # just verify these don't cause errors
+        curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED)
+        m = curses.getmouse()
 
     def test_userptr_without_set(self):
         w = curses.newwin(10, 10)
@@ -285,9 +294,21 @@ class TestCurses(unittest.TestCase):
         panel.set_userptr(A())
         panel.set_userptr(None)
 
-    @unittest.skipUnless(hasattr(curses, 'resizeterm'),
-                           'resizeterm not available')
+    def test_new_curses_panel(self):
+        panel = curses.panel.new_panel(self.stdscr)
+        self.assertRaises(TypeError, type(panel))
+
+    @requires_curses_func('is_term_resized')
+    def test_is_term_resized(self):
+        curses.is_term_resized(*self.stdscr.getmaxyx())
+
+    @requires_curses_func('resize_term')
     def test_resize_term(self):
+        curses.resize_term(*self.stdscr.getmaxyx())
+
+    @requires_curses_func('resizeterm')
+    def test_resizeterm(self):
+        stdscr = self.stdscr
         lines, cols = curses.LINES, curses.COLS
         new_lines = lines - 1
         new_cols = cols + 1
@@ -300,8 +321,7 @@ class TestCurses(unittest.TestCase):
         curses.ungetch(1025)
         self.stdscr.getkey()
 
-    @unittest.skipUnless(hasattr(curses, 'unget_wch'),
-                         'unget_wch not available')
+    @requires_curses_func('unget_wch')
     def test_unget_wch(self):
         stdscr = self.stdscr
         encoding = stdscr.encoding
@@ -326,17 +346,14 @@ class TestCurses(unittest.TestCase):
     def test_issue10570(self):
         b = curses.tparm(curses.tigetstr("cup"), 5, 3)
         self.assertIs(type(b), bytes)
-        curses.putp(b)
 
     def test_encoding(self):
         stdscr = self.stdscr
         import codecs
         encoding = stdscr.encoding
         codecs.lookup(encoding)
-
         with self.assertRaises(TypeError):
             stdscr.encoding = 10
-
         stdscr.encoding = encoding
         with self.assertRaises(TypeError):
             del stdscr.encoding
@@ -367,8 +384,10 @@ class TestCurses(unittest.TestCase):
         # be reasonably certain the generated parsing code will be
         # correct too.
         human_readable_signature = stdscr.addch.__doc__.split("\n")[0]
-        offset = human_readable_signature.find("[y, x,]")
-        assert offset >= 0, ""
+        self.assertIn("[y, x,]", human_readable_signature)
+
+
+class MiscTests(unittest.TestCase):
 
     def test_update_lines_cols(self):
         # this doesn't actually test that LINES and COLS are updated,
@@ -378,5 +397,21 @@ class TestCurses(unittest.TestCase):
         curses.update_lines_cols()
 
 
+class TestAscii(unittest.TestCase):
+
+    def test_unctrl(self):
+        unctrl = curses.ascii.unctrl
+        self.assertEqual(unctrl('a'), 'a')
+        self.assertEqual(unctrl('A'), 'A')
+        self.assertEqual(unctrl(';'), ';')
+        self.assertEqual(unctrl(' '), ' ')
+        self.assertEqual(unctrl('\x7f'), '^?')
+        self.assertEqual(unctrl('\n'), '^J')
+        self.assertEqual(unctrl('\0'), '^@')
+        # Meta-bit characters
+        self.assertEqual(unctrl('\x8a'), '!^J')
+        self.assertEqual(unctrl('\xc1'), '!A')
+
+
 if __name__ == '__main__':
     unittest.main()
index 137aaa5..c0d21b1 100644 (file)
@@ -4173,7 +4173,6 @@ class CheckAttributes(unittest.TestCase):
         self.assertTrue(P.HAVE_THREADS is True or P.HAVE_THREADS is False)
 
         self.assertEqual(C.__version__, P.__version__)
-        self.assertEqual(C.__libmpdec_version__, P.__libmpdec_version__)
 
         self.assertEqual(dir(C), dir(P))
 
index 8718716..f525429 100644 (file)
@@ -304,6 +304,21 @@ class TestBasic(unittest.TestCase):
             s.insert(i, 'Z')
             self.assertEqual(list(d), s)
 
+    def test_insert_bug_26194(self):
+        data = 'ABC'
+        d = deque(data, maxlen=len(data))
+        with self.assertRaises(IndexError):
+            d.insert(2, None)
+
+        elements = 'ABCDEFGHI'
+        for i in range(-len(elements), len(elements)):
+            d = deque(elements, maxlen=len(elements)+1)
+            d.insert(i, 'Z')
+            if i >= 0:
+                self.assertEqual(d[i], 'Z')
+            else:
+                self.assertEqual(d[i-1], 'Z')
+
     def test_imul(self):
         for n in (-10, -1, 0, 1, 2, 10, 1000):
             d = deque()
@@ -623,18 +638,45 @@ class TestBasic(unittest.TestCase):
 ##            self.assertEqual(id(e), id(e[-1]))
 
     def test_iterator_pickle(self):
-        data = deque(range(200))
+        orig = deque(range(200))
+        data = [i*1.01 for i in orig]
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
-            it = itorg = iter(data)
-            d = pickle.dumps(it, proto)
-            it = pickle.loads(d)
-            self.assertEqual(type(itorg), type(it))
-            self.assertEqual(list(it), list(data))
-
-            it = pickle.loads(d)
-            next(it)
-            d = pickle.dumps(it, proto)
-            self.assertEqual(list(it), list(data)[1:])
+            # initial iterator
+            itorg = iter(orig)
+            dump = pickle.dumps((itorg, orig), proto)
+            it, d = pickle.loads(dump)
+            for i, x in enumerate(data):
+                d[i] = x
+            self.assertEqual(type(it), type(itorg))
+            self.assertEqual(list(it), data)
+
+            # running iterator
+            next(itorg)
+            dump = pickle.dumps((itorg, orig), proto)
+            it, d = pickle.loads(dump)
+            for i, x in enumerate(data):
+                d[i] = x
+            self.assertEqual(type(it), type(itorg))
+            self.assertEqual(list(it), data[1:])
+
+            # empty iterator
+            for i in range(1, len(data)):
+                next(itorg)
+            dump = pickle.dumps((itorg, orig), proto)
+            it, d = pickle.loads(dump)
+            for i, x in enumerate(data):
+                d[i] = x
+            self.assertEqual(type(it), type(itorg))
+            self.assertEqual(list(it), [])
+
+            # exhausted iterator
+            self.assertRaises(StopIteration, next, itorg)
+            dump = pickle.dumps((itorg, orig), proto)
+            it, d = pickle.loads(dump)
+            for i, x in enumerate(data):
+                d[i] = x
+            self.assertEqual(type(it), type(itorg))
+            self.assertEqual(list(it), [])
 
     def test_deepcopy(self):
         mut = [10]
@@ -702,8 +744,8 @@ class TestBasic(unittest.TestCase):
     @support.cpython_only
     def test_sizeof(self):
         BLOCKLEN = 64
-        basesize = support.calcobjsize('2P4nlP')
-        blocksize = struct.calcsize('2P%dP' % BLOCKLEN)
+        basesize = support.calcvobjsize('2P4nP')
+        blocksize = struct.calcsize('P%dPP' % BLOCKLEN)
         self.assertEqual(object.__sizeof__(deque()), basesize)
         check = self.check_sizeof
         check(deque(), basesize + blocksize)
@@ -863,6 +905,10 @@ class TestSequence(seq_tests.CommonTest):
         # For now, bypass tests that require slicing
         pass
 
+    def test_free_after_iterating(self):
+        # For now, bypass tests that require slicing
+        self.skipTest("Exhausted deque iterator doesn't free a deque")
+
 #==============================================================================
 
 libreftest = """
index d096390..a130cec 100644 (file)
@@ -3489,7 +3489,7 @@ order (MRO) for bases """
         b.a = a
         z = deepcopy(a) # This blew up before
 
-    def test_unintialized_modules(self):
+    def test_uninitialized_modules(self):
         # Testing uninitialized module objects...
         from types import ModuleType as M
         m = M.__new__(M)
@@ -5092,6 +5092,23 @@ class PicklingTests(unittest.TestCase):
                     objcopy2 = deepcopy(objcopy)
                     self._assert_is_copy(obj, objcopy2)
 
+    def test_issue24097(self):
+        # Slot name is freed inside __getattr__ and is later used.
+        class S(str):  # Not interned
+            pass
+        class A:
+            __slotnames__ = [S('spam')]
+            def __getattr__(self, attr):
+                if attr == 'spam':
+                    A.__slotnames__[:] = [S('spam')]
+                    return 42
+                else:
+                    raise AttributeError
+
+        import copyreg
+        expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None)
+        self.assertEqual(A().__reduce__(2), expected)  # Shouldn't crash
+
 
 class SharedKeyTests(unittest.TestCase):
 
index 3b42414..6d68e76 100644 (file)
@@ -861,7 +861,7 @@ class DictTest(unittest.TestCase):
             itorg = iter(data.items())
             d = pickle.dumps(itorg, proto)
             it = pickle.loads(d)
-            # note that the type of type of the unpickled iterator
+            # note that the type of the unpickled iterator
             # is not necessarily the same as the original.  It is
             # merely an object supporting the iterator protocol, yielding
             # the same objects as the original one.
@@ -952,6 +952,12 @@ class DictTest(unittest.TestCase):
         d = {X(): 0, 1: 1}
         self.assertRaises(RuntimeError, d.update, other)
 
+    def test_free_after_iterating(self):
+        support.check_free_after_iterating(self, iter, dict)
+        support.check_free_after_iterating(self, lambda d: iter(d.keys()), dict)
+        support.check_free_after_iterating(self, lambda d: iter(d.values()), dict)
+        support.check_free_after_iterating(self, lambda d: iter(d.items()), dict)
+
 from test import mapping_tests
 
 class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
index 787ef20..ab23ca1 100644 (file)
@@ -96,6 +96,7 @@ class DictSetTest(unittest.TestCase):
         self.assertEqual(d1.keys() & set(d1.keys()), {'a', 'b'})
         self.assertEqual(d1.keys() & set(d2.keys()), {'b'})
         self.assertEqual(d1.keys() & set(d3.keys()), set())
+        self.assertEqual(d1.keys() & tuple(d1.keys()), {'a', 'b'})
 
         self.assertEqual(d1.keys() | d1.keys(), {'a', 'b'})
         self.assertEqual(d1.keys() | d2.keys(), {'a', 'b', 'c'})
@@ -104,6 +105,7 @@ class DictSetTest(unittest.TestCase):
         self.assertEqual(d1.keys() | set(d2.keys()), {'a', 'b', 'c'})
         self.assertEqual(d1.keys() | set(d3.keys()),
                          {'a', 'b', 'd', 'e'})
+        self.assertEqual(d1.keys() | (1, 2), {'a', 'b', 1, 2})
 
         self.assertEqual(d1.keys() ^ d1.keys(), set())
         self.assertEqual(d1.keys() ^ d2.keys(), {'a', 'c'})
@@ -112,6 +114,7 @@ class DictSetTest(unittest.TestCase):
         self.assertEqual(d1.keys() ^ set(d2.keys()), {'a', 'c'})
         self.assertEqual(d1.keys() ^ set(d3.keys()),
                          {'a', 'b', 'd', 'e'})
+        self.assertEqual(d1.keys() ^ tuple(d2.keys()), {'a', 'c'})
 
         self.assertEqual(d1.keys() - d1.keys(), set())
         self.assertEqual(d1.keys() - d2.keys(), {'a'})
@@ -119,6 +122,7 @@ class DictSetTest(unittest.TestCase):
         self.assertEqual(d1.keys() - set(d1.keys()), set())
         self.assertEqual(d1.keys() - set(d2.keys()), {'a'})
         self.assertEqual(d1.keys() - set(d3.keys()), {'a', 'b'})
+        self.assertEqual(d1.keys() - (0, 1), {'a', 'b'})
 
         self.assertFalse(d1.keys().isdisjoint(d1.keys()))
         self.assertFalse(d1.keys().isdisjoint(d2.keys()))
index 421bbad..0fd1348 100644 (file)
@@ -30,8 +30,16 @@ class _C:
     def __init__(self, x):
         self.x = x == 1
 
+    @staticmethod
+    def sm(x):
+        x = x == 1
+
+    @classmethod
+    def cm(cls, x):
+        cls.x = x == 1
+
 dis_c_instance_method = """\
- %-4d         0 LOAD_FAST                1 (x)
+%3d           0 LOAD_FAST                1 (x)
               3 LOAD_CONST               1 (1)
               6 COMPARE_OP               2 (==)
               9 LOAD_FAST                0 (self)
@@ -50,17 +58,48 @@ dis_c_instance_method_bytes = """\
          18 RETURN_VALUE
 """
 
+dis_c_class_method = """\
+%3d           0 LOAD_FAST                1 (x)
+              3 LOAD_CONST               1 (1)
+              6 COMPARE_OP               2 (==)
+              9 LOAD_FAST                0 (cls)
+             12 STORE_ATTR               0 (x)
+             15 LOAD_CONST               0 (None)
+             18 RETURN_VALUE
+""" % (_C.cm.__code__.co_firstlineno + 2,)
+
+dis_c_static_method = """\
+%3d           0 LOAD_FAST                0 (x)
+              3 LOAD_CONST               1 (1)
+              6 COMPARE_OP               2 (==)
+              9 STORE_FAST               0 (x)
+             12 LOAD_CONST               0 (None)
+             15 RETURN_VALUE
+""" % (_C.sm.__code__.co_firstlineno + 2,)
+
+# Class disassembling info has an extra newline at end.
+dis_c = """\
+Disassembly of %s:
+%s
+Disassembly of %s:
+%s
+Disassembly of %s:
+%s
+""" % (_C.__init__.__name__, dis_c_instance_method,
+       _C.cm.__name__, dis_c_class_method,
+       _C.sm.__name__, dis_c_static_method)
+
 def _f(a):
     print(a)
     return 1
 
 dis_f = """\
- %-4d         0 LOAD_GLOBAL              0 (print)
+%3d           0 LOAD_GLOBAL              0 (print)
               3 LOAD_FAST                0 (a)
               6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
               9 POP_TOP
 
- %-4d        10 LOAD_CONST               1 (1)
+%3d          10 LOAD_CONST               1 (1)
              13 RETURN_VALUE
 """ % (_f.__code__.co_firstlineno + 1,
        _f.__code__.co_firstlineno + 2)
@@ -82,17 +121,17 @@ def bug708901():
         pass
 
 dis_bug708901 = """\
- %-4d         0 SETUP_LOOP              23 (to 26)
+%3d           0 SETUP_LOOP              23 (to 26)
               3 LOAD_GLOBAL              0 (range)
               6 LOAD_CONST               1 (1)
 
- %-4d         9 LOAD_CONST               2 (10)
+%3d           9 LOAD_CONST               2 (10)
              12 CALL_FUNCTION            2 (2 positional, 0 keyword pair)
              15 GET_ITER
         >>   16 FOR_ITER                 6 (to 25)
              19 STORE_FAST               0 (res)
 
- %-4d        22 JUMP_ABSOLUTE           16
+%3d          22 JUMP_ABSOLUTE           16
         >>   25 POP_BLOCK
         >>   26 LOAD_CONST               0 (None)
              29 RETURN_VALUE
@@ -191,16 +230,16 @@ dis_compound_stmt_str = """\
 """
 
 dis_traceback = """\
- %-4d         0 SETUP_EXCEPT            12 (to 15)
+%3d           0 SETUP_EXCEPT            12 (to 15)
 
- %-4d         3 LOAD_CONST               1 (1)
+%3d           3 LOAD_CONST               1 (1)
               6 LOAD_CONST               2 (0)
     -->       9 BINARY_TRUE_DIVIDE
              10 POP_TOP
              11 POP_BLOCK
              12 JUMP_FORWARD            46 (to 61)
 
- %-4d   >>   15 DUP_TOP
+%3d     >>   15 DUP_TOP
              16 LOAD_GLOBAL              0 (Exception)
              19 COMPARE_OP              10 (exception match)
              22 POP_JUMP_IF_FALSE       60
@@ -209,7 +248,7 @@ dis_traceback = """\
              29 POP_TOP
              30 SETUP_FINALLY           14 (to 47)
 
- %-4d        33 LOAD_FAST                0 (e)
+%3d          33 LOAD_FAST                0 (e)
              36 LOAD_ATTR                1 (__traceback__)
              39 STORE_FAST               1 (tb)
              42 POP_BLOCK
@@ -222,7 +261,7 @@ dis_traceback = """\
              57 JUMP_FORWARD             1 (to 61)
         >>   60 END_FINALLY
 
- %-4d   >>   61 LOAD_FAST                1 (tb)
+%3d     >>   61 LOAD_FAST                1 (tb)
              64 RETURN_VALUE
 """ % (TRACEBACK_CODE.co_firstlineno + 1,
        TRACEBACK_CODE.co_firstlineno + 2,
@@ -311,13 +350,22 @@ class DisTests(unittest.TestCase):
     def test_disassemble_bytes(self):
         self.do_disassembly_test(_f.__code__.co_code, dis_f_co_code)
 
-    def test_disassemble_method(self):
+    def test_disassemble_class(self):
+        self.do_disassembly_test(_C, dis_c)
+
+    def test_disassemble_instance_method(self):
         self.do_disassembly_test(_C(1).__init__, dis_c_instance_method)
 
-    def test_disassemble_method_bytes(self):
+    def test_disassemble_instance_method_bytes(self):
         method_bytecode = _C(1).__init__.__code__.co_code
         self.do_disassembly_test(method_bytecode, dis_c_instance_method_bytes)
 
+    def test_disassemble_static_method(self):
+        self.do_disassembly_test(_C.sm, dis_c_static_method)
+
+    def test_disassemble_class_method(self):
+        self.do_disassembly_test(_C.cm, dis_c_class_method)
+
     def test_disassemble_generator(self):
         gen_func_disas = self.get_disassembly(_g)  # Disassemble generator function
         gen_disas = self.get_disassembly(_g(1))  # Disassemble generator itself
index 73b4452..29426a3 100644 (file)
@@ -324,7 +324,7 @@ containing test:
     >>> test.lineno + e2.lineno
     26
 
-If the docstring contains inconsistant leading whitespace in the
+If the docstring contains inconsistent leading whitespace in the
 expected output of an example, then `DocTest` will raise a ValueError:
 
     >>> docstring = r'''
@@ -2647,7 +2647,7 @@ Windows line endings first:
     >>> with open(fn, 'wb') as f:
     ...    f.write(b'Test:\r\n\r\n  >>> x = 1 + 1\r\n\r\nDone.\r\n')
     35
-    >>> doctest.testfile(fn, False)
+    >>> doctest.testfile(fn, module_relative=False, verbose=False)
     TestResults(failed=0, attempted=1)
     >>> os.remove(fn)
 
@@ -2657,7 +2657,7 @@ And now *nix line endings:
     >>> with open(fn, 'wb') as f:
     ...     f.write(b'Test:\n\n  >>> x = 1 + 1\n\nDone.\n')
     30
-    >>> doctest.testfile(fn, False)
+    >>> doctest.testfile(fn, module_relative=False, verbose=False)
     TestResults(failed=0, attempted=1)
     >>> os.remove(fn)
 
@@ -2775,7 +2775,7 @@ Now we'll write a couple files, one with three tests, the other a python module
 with two tests, both of the files having "errors" in the tests that can be made
 non-errors by applying the appropriate doctest options to the run (ELLIPSIS in
 the first file, NORMALIZE_WHITESPACE in the second).  This combination will
-allow to thoroughly test the -f and -o flags, as well as the doctest command's
+allow thoroughly testing the -f and -o flags, as well as the doctest command's
 ability to process more than one file on the command line and, since the second
 file ends in '.py', its handling of python module files (as opposed to straight
 text files).
index 2fafe1d..a6a2856 100644 (file)
@@ -24,14 +24,14 @@ class LockTests(unittest.TestCase):
 
     def test_initlock(self):
         #Make sure locks start locked
-        self.assertTrue(not self.lock.locked(),
+        self.assertFalse(self.lock.locked(),
                         "Lock object is not initialized unlocked.")
 
     def test_release(self):
         # Test self.lock.release()
         self.lock.acquire()
         self.lock.release()
-        self.assertTrue(not self.lock.locked(),
+        self.assertFalse(self.lock.locked(),
                         "Lock object did not release properly.")
 
     def test_improper_release(self):
@@ -46,7 +46,7 @@ class LockTests(unittest.TestCase):
     def test_cond_acquire_fail(self):
         #Test acquiring locked lock returns False
         self.lock.acquire(0)
-        self.assertTrue(not self.lock.acquire(0),
+        self.assertFalse(self.lock.acquire(0),
                         "Conditional acquiring of a locked lock incorrectly "
                          "succeeded.")
 
@@ -58,9 +58,9 @@ class LockTests(unittest.TestCase):
 
     def test_uncond_acquire_return_val(self):
         #Make sure that an unconditional locking returns True.
-        self.assertTrue(self.lock.acquire(1) is True,
+        self.assertIs(self.lock.acquire(1), True,
                         "Unconditional locking did not return True.")
-        self.assertTrue(self.lock.acquire() is True)
+        self.assertIs(self.lock.acquire(), True)
 
     def test_uncond_acquire_blocking(self):
         #Make sure that unconditional acquiring of a locked lock blocks.
@@ -80,7 +80,7 @@ class LockTests(unittest.TestCase):
         end_time = int(time.time())
         if support.verbose:
             print("done")
-        self.assertTrue((end_time - start_time) >= DELAY,
+        self.assertGreaterEqual(end_time - start_time, DELAY,
                         "Blocking by unconditional acquiring failed.")
 
 class MiscTests(unittest.TestCase):
@@ -94,7 +94,7 @@ class MiscTests(unittest.TestCase):
         #Test sanity of _thread.get_ident()
         self.assertIsInstance(_thread.get_ident(), int,
                               "_thread.get_ident() returned a non-integer")
-        self.assertTrue(_thread.get_ident() != 0,
+        self.assertNotEqual(_thread.get_ident(), 0,
                         "_thread.get_ident() returned 0")
 
     def test_LockType(self):
@@ -164,7 +164,7 @@ class ThreadTests(unittest.TestCase):
         time.sleep(DELAY)
         if support.verbose:
             print('done')
-        self.assertTrue(testing_queue.qsize() == thread_count,
+        self.assertEqual(testing_queue.qsize(), thread_count,
                         "Not all %s threads executed properly after %s sec." %
                         (thread_count, DELAY))
 
index d028f74..f7ac0e3 100644 (file)
@@ -2498,7 +2498,7 @@ class Test_parse_mime_parameters(TestParserMixin, TestEmailBase):
         # Note that it is undefined what we should do for error recovery when
         # there are duplicate parameter names or duplicate parts in a split
         # part.  We choose to ignore all duplicate parameters after the first
-        # and to take duplicate or missing rfc 2231 parts in apperance order.
+        # and to take duplicate or missing rfc 2231 parts in appearance order.
         # This is backward compatible with get_param's behavior, but the
         # decisions are arbitrary.
 
index 089269f..f9cd7d9 100644 (file)
@@ -5,7 +5,7 @@
 import unittest
 from test.support import run_unittest
 
-from test.test_email.test_email import TestEmailBase
+from test.test_email import TestEmailBase
 from email.charset import Charset
 from email.header import Header, decode_header
 from email.message import Message
@@ -18,7 +18,7 @@ except LookupError:
     raise unittest.SkipTest
 
 
-\f
+
 class TestEmailAsianCodecs(TestEmailBase):
     def test_japanese_codecs(self):
         eq = self.ndiffAssertEqual
@@ -77,6 +77,6 @@ Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?=
         self.assertEqual(jhello, ustr)
 
 
-\f
+
 if __name__ == '__main__':
     unittest.main()
index cdb04e4..169058e 100644 (file)
@@ -621,7 +621,7 @@ class TestRawDataManager(TestEmailBase):
         self.assertEqual(m.get_content(), content)
 
     def test_set_application_octet_stream_with_8bit_cte(self):
-        # In 8bit mode, univeral line end logic applies.  It is up to the
+        # In 8bit mode, universal line end logic applies.  It is up to the
         # application to make sure the lines are short enough; we don't check.
         m = self._make_message()
         content = b'b\xFFgus\tcon\nt\rent\n' + b'z'*60 + b'\n'
index 9bb32f0..70ac4db 100644 (file)
@@ -177,7 +177,7 @@ class PolicyAPITests(unittest.TestCase):
         with self.assertRaisesRegex(self.MyDefect, "the telly is broken"):
             self.MyPolicy(raise_on_defect=True).handle_defect(foo, defect)
 
-    def test_overriden_register_defect_works(self):
+    def test_overridden_register_defect_works(self):
         foo = self.MyObj()
         defect1 = self.MyDefect("one")
         my_policy = self.MyPolicy()
index 19cf64f..e72a146 100644 (file)
@@ -10,10 +10,9 @@ import sys
 import os
 import unittest
 from io import StringIO
-from types import ListType
 
-from email.test.test_email import TestEmailBase
-from test.support import TestSkipped, run_unittest
+from test.test_email import TestEmailBase
+from test.support import run_unittest
 
 import email
 from email import __file__ as testfile
@@ -28,10 +27,10 @@ def openfile(filename):
 try:
     openfile('crispin-torture.txt')
 except OSError:
-    raise TestSkipped
+    raise unittest.SkipTest
+
 
 
-\f
 class TortureBase(TestEmailBase):
     def _msgobj(self, filename):
         fp = openfile(filename)
@@ -42,7 +41,7 @@ class TortureBase(TestEmailBase):
         return msg
 
 
-\f
+
 class TestCrispinTorture(TortureBase):
     # Mark Crispin's torture test from the SquirrelMail project
     def test_mondo_message(self):
@@ -50,7 +49,7 @@ class TestCrispinTorture(TortureBase):
         neq = self.ndiffAssertEqual
         msg = self._msgobj('crispin-torture.txt')
         payload = msg.get_payload()
-        eq(type(payload), ListType)
+        eq(type(payload), list)
         eq(len(payload), 12)
         eq(msg.preamble, None)
         eq(msg.epilogue, '\n')
@@ -113,7 +112,6 @@ multipart/mixed
                         audio/x-sun
 """)
 
-\f
 def _testclasses():
     mod = sys.modules[__name__]
     return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
@@ -131,6 +129,5 @@ def test_main():
         run_unittest(testclass)
 
 
-\f
 if __name__ == '__main__':
     unittest.main(defaultTest='suite')
index 4b5d0d0..e970a26 100644 (file)
@@ -253,6 +253,19 @@ class TestEnum(unittest.TestCase):
         with self.assertRaises(AttributeError):
             del Season.SPRING.name
 
+    def test_bool_of_class(self):
+        class Empty(Enum):
+            pass
+        self.assertTrue(bool(Empty))
+
+    def test_bool_of_member(self):
+        class Count(Enum):
+            zero = 0
+            one = 1
+            two = 2
+        for member in Count:
+            self.assertTrue(bool(member))
+
     def test_invalid_names(self):
         with self.assertRaises(ValueError):
             class Wrong(Enum):
@@ -528,6 +541,18 @@ class TestEnum(unittest.TestCase):
         self.assertEqual([k for k,v in WeekDay.__members__.items()
                 if v.name != k], ['TEUSDAY', ])
 
+    def test_intenum_from_bytes(self):
+        self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE)
+        with self.assertRaises(ValueError):
+            IntStooges.from_bytes(b'\x00\x05', 'big')
+
+    def test_floatenum_fromhex(self):
+        h = float.hex(FloatStooges.MOE.value)
+        self.assertIs(FloatStooges.fromhex(h), FloatStooges.MOE)
+        h = float.hex(FloatStooges.MOE.value + 0.01)
+        with self.assertRaises(ValueError):
+            FloatStooges.fromhex(h)
+
     def test_pickle_enum(self):
         if isinstance(Stooges, Exception):
             raise Stooges
@@ -1555,6 +1580,19 @@ class TestUnique(unittest.TestCase):
                 triple = 3
                 turkey = 3
 
+    def test_unique_with_name(self):
+        @unique
+        class Silly(Enum):
+            one = 1
+            two = 'dos'
+            name = 3
+        @unique
+        class Sillier(IntEnum):
+            single = 1
+            name = 2
+            triple = 3
+            value = 4
+
 
 expected_help_output_with_docs = """\
 Help on class Color in module %s:
index 8a49045..458ddc1 100644 (file)
@@ -7,7 +7,7 @@ import pickle
 import weakref
 import errno
 
-from test.support import (TESTFN, captured_output, check_impl_detail,
+from test.support import (TESTFN, captured_stderr, check_impl_detail,
                           check_warnings, cpython_only, gc_collect, run_unittest,
                           no_tracing, unlink, import_module)
 
@@ -20,6 +20,10 @@ class SlottedNaiveException(Exception):
     def __init__(self, x):
         self.x = x
 
+class BrokenStrException(Exception):
+    def __str__(self):
+        raise Exception("str() is broken")
+
 # XXX This is not really enough, each *operation* should be tested!
 
 class ExceptionTests(unittest.TestCase):
@@ -882,7 +886,7 @@ class ExceptionTests(unittest.TestCase):
         class MyException(Exception, metaclass=Meta):
             pass
 
-        with captured_output("stderr") as stderr:
+        with captured_stderr() as stderr:
             try:
                 raise KeyError()
             except MyException as e:
@@ -1011,6 +1015,66 @@ class ExceptionTests(unittest.TestCase):
             os.listdir(__file__)
         self.assertEqual(cm.exception.errno, errno.ENOTDIR, cm.exception)
 
+    def test_unraisable(self):
+        # Issue #22836: PyErr_WriteUnraisable() should give sensible reports
+        class BrokenDel:
+            def __del__(self):
+                exc = ValueError("del is broken")
+                # The following line is included in the traceback report:
+                raise exc
+
+        class BrokenRepr(BrokenDel):
+            def __repr__(self):
+                raise AttributeError("repr() is broken")
+
+        class BrokenExceptionDel:
+            def __del__(self):
+                exc = BrokenStrException()
+                # The following line is included in the traceback report:
+                raise exc
+
+        for test_class in (BrokenDel, BrokenRepr, BrokenExceptionDel):
+            with self.subTest(test_class):
+                obj = test_class()
+                with captured_stderr() as stderr:
+                    del obj
+                report = stderr.getvalue()
+                self.assertIn("Exception ignored", report)
+                if test_class is BrokenRepr:
+                    self.assertIn("<object repr() failed>", report)
+                else:
+                    self.assertIn(test_class.__del__.__qualname__, report)
+                self.assertIn("test_exceptions.py", report)
+                self.assertIn("raise exc", report)
+                if test_class is BrokenExceptionDel:
+                    self.assertIn("BrokenStrException", report)
+                    self.assertIn("<exception str() failed>", report)
+                else:
+                    self.assertIn("ValueError", report)
+                    self.assertIn("del is broken", report)
+                self.assertTrue(report.endswith("\n"))
+
+    def test_unhandled(self):
+        # Check for sensible reporting of unhandled exceptions
+        for exc_type in (ValueError, BrokenStrException):
+            with self.subTest(exc_type):
+                try:
+                    exc = exc_type("test message")
+                    # The following line is included in the traceback report:
+                    raise exc
+                except exc_type:
+                    with captured_stderr() as stderr:
+                        sys.__excepthook__(*sys.exc_info())
+                report = stderr.getvalue()
+                self.assertIn("test_exceptions.py", report)
+                self.assertIn("raise exc", report)
+                self.assertIn(exc_type.__name__, report)
+                if exc_type is BrokenStrException:
+                    self.assertIn("<exception str() failed>", report)
+                else:
+                    self.assertIn("test message", report)
+                self.assertTrue(report.endswith("\n"))
+
 
 class ImportErrorTests(unittest.TestCase):
 
index 654258e..d526b5f 100644 (file)
@@ -114,7 +114,7 @@ Verify clearing of SF bug #733667
     >>> g(*Nothing())
     Traceback (most recent call last):
       ...
-    TypeError: g() argument after * must be a sequence, not Nothing
+    TypeError: g() argument after * must be an iterable, not Nothing
 
     >>> class Nothing:
     ...     def __len__(self): return 5
@@ -123,7 +123,7 @@ Verify clearing of SF bug #733667
     >>> g(*Nothing())
     Traceback (most recent call last):
       ...
-    TypeError: g() argument after * must be a sequence, not Nothing
+    TypeError: g() argument after * must be an iterable, not Nothing
 
     >>> class Nothing():
     ...     def __len__(self): return 5
@@ -149,6 +149,45 @@ Verify clearing of SF bug #733667
     >>> g(*Nothing())
     0 (1, 2, 3) {}
 
+Check for issue #4806: Does a TypeError in a generator get propagated with the
+right error message? (Also check with other iterables.)
+
+    >>> def broken(): raise TypeError("myerror")
+    ...
+
+    >>> g(*(broken() for i in range(1)))
+    Traceback (most recent call last):
+      ...
+    TypeError: myerror
+
+    >>> class BrokenIterable1:
+    ...     def __iter__(self):
+    ...         raise TypeError('myerror')
+    ...
+    >>> g(*BrokenIterable1())
+    Traceback (most recent call last):
+      ...
+    TypeError: myerror
+
+    >>> class BrokenIterable2:
+    ...     def __iter__(self):
+    ...         yield 0
+    ...         raise TypeError('myerror')
+    ...
+    >>> g(*BrokenIterable2())
+    Traceback (most recent call last):
+      ...
+    TypeError: myerror
+
+    >>> class BrokenSequence:
+    ...     def __getitem__(self, idx):
+    ...         raise TypeError('myerror')
+    ...
+    >>> g(*BrokenSequence())
+    Traceback (most recent call last):
+      ...
+    TypeError: myerror
+
 Make sure that the function doesn't stomp the dictionary
 
     >>> d = {'a': 1, 'b': 2, 'c': 3}
@@ -188,17 +227,17 @@ What about willful misconduct?
     >>> h(*h)
     Traceback (most recent call last):
       ...
-    TypeError: h() argument after * must be a sequence, not function
+    TypeError: h() argument after * must be an iterable, not function
 
     >>> dir(*h)
     Traceback (most recent call last):
       ...
-    TypeError: dir() argument after * must be a sequence, not function
+    TypeError: dir() argument after * must be an iterable, not function
 
     >>> None(*h)
     Traceback (most recent call last):
       ...
-    TypeError: NoneType object argument after * must be a sequence, \
+    TypeError: NoneType object argument after * must be an iterable, \
 not function
 
     >>> h(**h)
index 0d86cb5..1562eec 100644 (file)
@@ -185,6 +185,14 @@ class FaultHandlerTests(unittest.TestCase):
             2,
             'xyz')
 
+    def test_fatal_error_without_gil(self):
+        self.check_fatal_error("""
+            import faulthandler
+            faulthandler._fatal_error(b'xyz', True)
+            """,
+            2,
+            'xyz')
+
     @unittest.skipIf(sys.platform.startswith('openbsd') and HAVE_THREADS,
                      "Issue #12868: sigaltstack() doesn't work on "
                      "OpenBSD if Python is compiled with pthread")
@@ -675,7 +683,7 @@ class FaultHandlerTests(unittest.TestCase):
             sys.stderr = stderr
 
     def test_stderr_None(self):
-        # Issue #21497: provide an helpful error if sys.stderr is None,
+        # Issue #21497: provide a helpful error if sys.stderr is None,
         # instead of just an attribute error: "None has no attribute fileno".
         with self.check_stderr_none():
             faulthandler.enable()
index 4765a05..784bc92 100644 (file)
@@ -46,6 +46,42 @@ def remove_tempfiles(*names):
         if name:
             safe_unlink(name)
 
+class LineReader:
+
+    def __init__(self):
+        self._linesread = []
+
+    @property
+    def linesread(self):
+        try:
+            return self._linesread[:]
+        finally:
+            self._linesread = []
+
+    def openhook(self, filename, mode):
+        self.it = iter(filename.splitlines(True))
+        return self
+
+    def readline(self, size=None):
+        line = next(self.it, '')
+        self._linesread.append(line)
+        return line
+
+    def readlines(self, hint=-1):
+        lines = []
+        size = 0
+        while True:
+            line = self.readline()
+            if not line:
+                return lines
+            lines.append(line)
+            size += len(line)
+            if size >= hint:
+                return lines
+
+    def close(self):
+        pass
+
 class BufferSizesTests(unittest.TestCase):
     def test_buffer_sizes(self):
         # First, run the tests with default and teeny buffer size.
@@ -240,6 +276,17 @@ class FileInputTests(unittest.TestCase):
             lines = list(fi)
             self.assertEqual(lines, [b'spam, bacon, sausage, and spam'])
 
+    def test_detached_stdin_binary_mode(self):
+        orig_stdin = sys.stdin
+        try:
+            sys.stdin = BytesIO(b'spam, bacon, sausage, and spam')
+            self.assertFalse(hasattr(sys.stdin, 'buffer'))
+            fi = FileInput(files=['-'], mode='rb')
+            lines = list(fi)
+            self.assertEqual(lines, [b'spam, bacon, sausage, and spam'])
+        finally:
+            sys.stdin = orig_stdin
+
     def test_file_opening_hook(self):
         try:
             # cannot use openhook and inplace mode
@@ -278,7 +325,7 @@ class FileInputTests(unittest.TestCase):
         self.addCleanup(safe_unlink, TESTFN)
 
         with FileInput(files=TESTFN,
-                       openhook=hook_encoded('ascii'), bufsize=8) as fi:
+                       openhook=hook_encoded('ascii')) as fi:
             try:
                 self.assertEqual(fi.readline(), 'A\n')
                 self.assertEqual(fi.readline(), 'B\n')
@@ -446,6 +493,38 @@ class FileInputTests(unittest.TestCase):
 
         self.assertEqual(result, -1, "fileno() should return -1")
 
+    def test_readline_buffering(self):
+        src = LineReader()
+        with FileInput(files=['line1\nline2', 'line3\n'],
+                       openhook=src.openhook) as fi:
+            self.assertEqual(src.linesread, [])
+            self.assertEqual(fi.readline(), 'line1\n')
+            self.assertEqual(src.linesread, ['line1\n'])
+            self.assertEqual(fi.readline(), 'line2')
+            self.assertEqual(src.linesread, ['line2'])
+            self.assertEqual(fi.readline(), 'line3\n')
+            self.assertEqual(src.linesread, ['', 'line3\n'])
+            self.assertEqual(fi.readline(), '')
+            self.assertEqual(src.linesread, [''])
+            self.assertEqual(fi.readline(), '')
+            self.assertEqual(src.linesread, [])
+
+    def test_iteration_buffering(self):
+        src = LineReader()
+        with FileInput(files=['line1\nline2', 'line3\n'],
+                       openhook=src.openhook) as fi:
+            self.assertEqual(src.linesread, [])
+            self.assertEqual(next(fi), 'line1\n')
+            self.assertEqual(src.linesread, ['line1\n'])
+            self.assertEqual(next(fi), 'line2')
+            self.assertEqual(src.linesread, ['line2'])
+            self.assertEqual(next(fi), 'line3\n')
+            self.assertEqual(src.linesread, ['', 'line3\n'])
+            self.assertRaises(StopIteration, next, fi)
+            self.assertEqual(src.linesread, [''])
+            self.assertRaises(StopIteration, next, fi)
+            self.assertEqual(src.linesread, [])
+
 class MockFileInput:
     """A class that mocks out fileinput.FileInput for use during unit tests"""
 
index 723beb3..cb1f6db 100644 (file)
@@ -25,6 +25,12 @@ requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"),
 test_dir = os.path.dirname(__file__) or os.curdir
 format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
 
+class FloatSubclass(float):
+    pass
+
+class OtherFloatSubclass(float):
+    pass
+
 class GeneralFloatCases(unittest.TestCase):
 
     def test_float(self):
@@ -167,6 +173,15 @@ class GeneralFloatCases(unittest.TestCase):
                 return ""
         self.assertRaises(TypeError, time.sleep, Foo5())
 
+        # Issue #24731
+        class F:
+            def __float__(self):
+                return OtherFloatSubclass(42.)
+        self.assertAlmostEqual(float(F()), 42.)
+        self.assertIs(type(float(F())), OtherFloatSubclass)
+        self.assertAlmostEqual(FloatSubclass(F()), 42.)
+        self.assertIs(type(FloatSubclass(F())), FloatSubclass)
+
     def test_is_integer(self):
         self.assertFalse((1.1).is_integer())
         self.assertTrue((1.).is_integer())
@@ -1340,6 +1355,24 @@ class HexFloatTestCase(unittest.TestCase):
             else:
                 self.identical(x, fromHex(toHex(x)))
 
+    def test_subclass(self):
+        class F(float):
+            def __new__(cls, value):
+                return float.__new__(cls, value + 1)
+
+        f = F.fromhex((1.5).hex())
+        self.assertIs(type(f), F)
+        self.assertEqual(f, 2.5)
+
+        class F2(float):
+            def __init__(self, value):
+                self.foo = 'bar'
+
+        f = F2.fromhex((1.5).hex())
+        self.assertIs(type(f), F2)
+        self.assertEqual(f, 1.5)
+        self.assertEqual(getattr(f, 'foo', 'none'), 'bar')
+
 
 if __name__ == '__main__':
     unittest.main()
index eeba306..da46fe5 100644 (file)
@@ -6,6 +6,7 @@ import os
 import signal
 import sys
 import time
+import unittest
 
 from test.fork_wait import ForkWait
 from test.support import (reap_children, get_attribute,
index d822b2d..9abe984 100644 (file)
@@ -30,6 +30,16 @@ def signature(part):
     """ return the signature of a partial object """
     return (part.func, part.args, part.keywords, part.__dict__)
 
+class MyTuple(tuple):
+    pass
+
+class BadTuple(tuple):
+    def __add__(self, other):
+        return list(self) + list(other)
+
+class MyDict(dict):
+    pass
+
 
 class TestPartial:
 
@@ -208,11 +218,84 @@ class TestPartialC(TestPartial, unittest.TestCase):
                        for kwargs_repr in kwargs_reprs])
 
     def test_pickle(self):
-        f = self.partial(signature, 'asdf', bar=True)
-        f.add_something_to__dict__ = True
+        f = self.partial(signature, ['asdf'], bar=[True])
+        f.attr = []
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
             f_copy = pickle.loads(pickle.dumps(f, proto))
-            self.assertEqual(signature(f), signature(f_copy))
+            self.assertEqual(signature(f_copy), signature(f))
+
+    def test_copy(self):
+        f = self.partial(signature, ['asdf'], bar=[True])
+        f.attr = []
+        f_copy = copy.copy(f)
+        self.assertEqual(signature(f_copy), signature(f))
+        self.assertIs(f_copy.attr, f.attr)
+        self.assertIs(f_copy.args, f.args)
+        self.assertIs(f_copy.keywords, f.keywords)
+
+    def test_deepcopy(self):
+        f = self.partial(signature, ['asdf'], bar=[True])
+        f.attr = []
+        f_copy = copy.deepcopy(f)
+        self.assertEqual(signature(f_copy), signature(f))
+        self.assertIsNot(f_copy.attr, f.attr)
+        self.assertIsNot(f_copy.args, f.args)
+        self.assertIsNot(f_copy.args[0], f.args[0])
+        self.assertIsNot(f_copy.keywords, f.keywords)
+        self.assertIsNot(f_copy.keywords['bar'], f.keywords['bar'])
+
+    def test_setstate(self):
+        f = self.partial(signature)
+        f.__setstate__((capture, (1,), dict(a=10), dict(attr=[])))
+        self.assertEqual(signature(f),
+                         (capture, (1,), dict(a=10), dict(attr=[])))
+        self.assertEqual(f(2, b=20), ((1, 2), {'a': 10, 'b': 20}))
+
+        f.__setstate__((capture, (1,), dict(a=10), None))
+        self.assertEqual(signature(f), (capture, (1,), dict(a=10), {}))
+        self.assertEqual(f(2, b=20), ((1, 2), {'a': 10, 'b': 20}))
+
+        f.__setstate__((capture, (1,), None, None))
+        #self.assertEqual(signature(f), (capture, (1,), {}, {}))
+        self.assertEqual(f(2, b=20), ((1, 2), {'b': 20}))
+        self.assertEqual(f(2), ((1, 2), {}))
+        self.assertEqual(f(), ((1,), {}))
+
+        f.__setstate__((capture, (), {}, None))
+        self.assertEqual(signature(f), (capture, (), {}, {}))
+        self.assertEqual(f(2, b=20), ((2,), {'b': 20}))
+        self.assertEqual(f(2), ((2,), {}))
+        self.assertEqual(f(), ((), {}))
+
+    def test_setstate_errors(self):
+        f = self.partial(signature)
+        self.assertRaises(TypeError, f.__setstate__, (capture, (), {}))
+        self.assertRaises(TypeError, f.__setstate__, (capture, (), {}, {}, None))
+        self.assertRaises(TypeError, f.__setstate__, [capture, (), {}, None])
+        self.assertRaises(TypeError, f.__setstate__, (None, (), {}, None))
+        self.assertRaises(TypeError, f.__setstate__, (capture, None, {}, None))
+        self.assertRaises(TypeError, f.__setstate__, (capture, [], {}, None))
+        self.assertRaises(TypeError, f.__setstate__, (capture, (), [], None))
+
+    def test_setstate_subclasses(self):
+        f = self.partial(signature)
+        f.__setstate__((capture, MyTuple((1,)), MyDict(a=10), None))
+        s = signature(f)
+        self.assertEqual(s, (capture, (1,), dict(a=10), {}))
+        self.assertIs(type(s[1]), tuple)
+        self.assertIs(type(s[2]), dict)
+        r = f()
+        self.assertEqual(r, ((1,), {'a': 10}))
+        self.assertIs(type(r[0]), tuple)
+        self.assertIs(type(r[1]), dict)
+
+        f.__setstate__((capture, BadTuple((1,)), {}, None))
+        s = signature(f)
+        self.assertEqual(s, (capture, (1,), {}, {}))
+        self.assertIs(type(s[1]), tuple)
+        r = f(2)
+        self.assertEqual(r, ((1, 2), {}))
+        self.assertIs(type(r[0]), tuple)
 
     # Issue 6083: Reference counting bug
     def test_setstate_refcount(self):
@@ -229,9 +312,7 @@ class TestPartialC(TestPartial, unittest.TestCase):
                 raise IndexError
 
         f = self.partial(object)
-        self.assertRaisesRegex(SystemError,
-                "new style getargs format but argument is not a tuple",
-                f.__setstate__, BadSequence())
+        self.assertRaises(TypeError, f.__setstate__, BadSequence())
 
 
 class TestPartialPy(TestPartial, unittest.TestCase):
@@ -1262,14 +1343,24 @@ class TestLRU:
 
     def test_copy(self):
         cls = self.__class__
-        for f in cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth:
+        def orig(x, y):
+            return 3 * x + y
+        part = self.module.partial(orig, 2)
+        funcs = (cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth,
+                 self.module.lru_cache(2)(part))
+        for f in funcs:
             with self.subTest(func=f):
                 f_copy = copy.copy(f)
                 self.assertIs(f_copy, f)
 
     def test_deepcopy(self):
         cls = self.__class__
-        for f in cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth:
+        def orig(x, y):
+            return 3 * x + y
+        part = self.module.partial(orig, 2)
+        funcs = (cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth,
+                 self.module.lru_cache(2)(part))
+        for f in funcs:
             with self.subTest(func=f):
                 f_copy = copy.deepcopy(f)
                 self.assertIs(f_copy, f)
@@ -1415,7 +1506,7 @@ class TestSingleDispatch(unittest.TestCase):
                                  object])
 
         # MutableSequence below is registered directly on D. In other words, it
-        # preceeds MutableMapping which means single dispatch will always
+        # precedes MutableMapping which means single dispatch will always
         # choose MutableSequence here.
         class D(c.defaultdict):
             pass
index 6c4a348..cd7d292 100644 (file)
@@ -75,6 +75,9 @@ def run_gdb(*args, **env_vars):
     if (gdb_major_version, gdb_minor_version) >= (7, 4):
         base_cmd += ('-iex', 'add-auto-load-safe-path ' + checkout_hook_path)
     proc = subprocess.Popen(base_cmd + args,
+                            # Redirect stdin to prevent GDB from messing with
+                            # the terminal settings
+                            stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             env=env)
@@ -89,7 +92,6 @@ if not gdbpy_version:
 
 # Verify that "gdb" can load our custom hooks, as OS security settings may
 # disallow this without a customised .gdbinit.
-cmd = ['--args', sys.executable]
 _, gdbpy_errors = run_gdb('--args', sys.executable)
 if "auto-loading has been declined" in gdbpy_errors:
     msg = "gdb security settings prevent use of custom hooks: "
@@ -171,8 +173,7 @@ class DebuggerTests(unittest.TestCase):
         # print commands
 
         # Use "commands" to generate the arguments with which to invoke "gdb":
-        args = ["gdb", "--batch", "-nx"]
-        args += ['--eval-command=%s' % cmd for cmd in commands]
+        args = ['--eval-command=%s' % cmd for cmd in commands]
         args += ["--args",
                  sys.executable]
 
@@ -197,27 +198,17 @@ class DebuggerTests(unittest.TestCase):
         # Ignore some benign messages on stderr.
         ignore_patterns = (
             'Function "%s" not defined.' % breakpoint,
-            "warning: no loadable sections found in added symbol-file"
-            " system-supplied DSO",
-            "warning: Unable to find libthread_db matching"
-            " inferior's thread library, thread debugging will"
-            " not be available.",
-            "warning: Cannot initialize thread debugging"
-            " library: Debugger service failed",
-            'warning: Could not load shared library symbols for '
-            'linux-vdso.so',
-            'warning: Could not load shared library symbols for '
-            'linux-gate.so',
-            'warning: Could not load shared library symbols for '
-            'linux-vdso64.so',
             'Do you need "set solib-search-path" or '
             '"set sysroot"?',
-            'warning: Source file is more recent than executable.',
-            # Issue #19753: missing symbols on System Z
-            'Missing separate debuginfo for ',
-            'Try: zypper install -C ',
+            # BFD: /usr/lib/debug/(...): unable to initialize decompress
+            # status for section .debug_aranges
+            'BFD: ',
+            # ignore all warnings
+            'warning: ',
             )
         for line in errlines:
+            if not line:
+                continue
             if not line.startswith(ignore_patterns):
                 unexpected_errlines.append(line)
 
index b92d5ce..3f82462 100644 (file)
@@ -1351,7 +1351,7 @@ class Queens:
 
         # For each square, compute a bit vector of the columns and
         # diagonals it covers, and for each row compute a function that
-        # generates the possiblities for the columns in that row.
+        # generates the possibilities for the columns in that row.
         self.rowgenerators = []
         for i in rangen:
             rowuses = [(1 << j) |                  # column ordinal
index 6ba55df..86fc2de 100644 (file)
@@ -419,7 +419,7 @@ class CommonTest(GenericTest):
     def test_nonascii_abspath(self):
         if (support.TESTFN_UNDECODABLE
         # Mac OS X denies the creation of a directory with an invalid
-        # UTF-8 name. Windows allows to create a directory with an
+        # UTF-8 name. Windows allows creating a directory with an
         # arbitrary bytes name, but fails to enter this directory
         # (when the bytes name is used).
         and sys.platform not in ('win32', 'darwin')):
index 71472cd..984aac7 100644 (file)
@@ -1,4 +1,6 @@
 import unittest
+import math
+import sys
 from test import support
 # Skip this test if the _testcapi module isn't available.
 support.import_module('_testcapi')
@@ -43,7 +45,11 @@ VERY_LARGE = 0xFF0000121212121212121242
 
 from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \
      INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
-     SHRT_MIN, SHRT_MAX
+     SHRT_MIN, SHRT_MAX, FLT_MIN, FLT_MAX, DBL_MIN, DBL_MAX
+
+DBL_MAX_EXP = sys.float_info.max_exp
+INF = float('inf')
+NAN = float('nan')
 
 # fake, they are not defined in Python's header files
 LLONG_MAX = 2**63-1
@@ -71,6 +77,61 @@ class BadInt3(int):
         return True
 
 
+class Float:
+    def __float__(self):
+        return 4.25
+
+class FloatSubclass(float):
+    pass
+
+class FloatSubclass2(float):
+    def __float__(self):
+        return 4.25
+
+class BadFloat:
+    def __float__(self):
+        return 687
+
+class BadFloat2:
+    def __float__(self):
+        return FloatSubclass(4.25)
+
+class BadFloat3(float):
+    def __float__(self):
+        return FloatSubclass(4.25)
+
+
+class Complex:
+    def __complex__(self):
+        return 4.25+0.5j
+
+class ComplexSubclass(complex):
+    pass
+
+class ComplexSubclass2(complex):
+    def __complex__(self):
+        return 4.25+0.5j
+
+class BadComplex:
+    def __complex__(self):
+        return 1.25
+
+class BadComplex2:
+    def __complex__(self):
+        return ComplexSubclass(4.25+0.5j)
+
+class BadComplex3(complex):
+    def __complex__(self):
+        return ComplexSubclass(4.25+0.5j)
+
+
+class TupleSubclass(tuple):
+    pass
+
+class DictSubclass(dict):
+    pass
+
+
 class Unsigned_TestCase(unittest.TestCase):
     def test_b(self):
         from _testcapi import getargs_b
@@ -289,6 +350,81 @@ class LongLong_TestCase(unittest.TestCase):
 
         self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
 
+
+class Float_TestCase(unittest.TestCase):
+    def assertEqualWithSign(self, actual, expected):
+        self.assertEqual(actual, expected)
+        self.assertEqual(math.copysign(1, actual), math.copysign(1, expected))
+
+    def test_f(self):
+        from _testcapi import getargs_f
+        self.assertEqual(getargs_f(4.25), 4.25)
+        self.assertEqual(getargs_f(4), 4.0)
+        self.assertRaises(TypeError, getargs_f, 4.25+0j)
+        self.assertEqual(getargs_f(Float()), 4.25)
+        self.assertEqual(getargs_f(FloatSubclass(7.5)), 7.5)
+        self.assertEqual(getargs_f(FloatSubclass2(7.5)), 7.5)
+        self.assertRaises(TypeError, getargs_f, BadFloat())
+        self.assertEqual(getargs_f(BadFloat2()), 4.25)
+        self.assertEqual(getargs_f(BadFloat3(7.5)), 7.5)
+
+        for x in (FLT_MIN, -FLT_MIN, FLT_MAX, -FLT_MAX, INF, -INF):
+            self.assertEqual(getargs_f(x), x)
+        if FLT_MAX < DBL_MAX:
+            self.assertEqual(getargs_f(DBL_MAX), INF)
+            self.assertEqual(getargs_f(-DBL_MAX), -INF)
+        if FLT_MIN > DBL_MIN:
+            self.assertEqualWithSign(getargs_f(DBL_MIN), 0.0)
+            self.assertEqualWithSign(getargs_f(-DBL_MIN), -0.0)
+        self.assertEqualWithSign(getargs_f(0.0), 0.0)
+        self.assertEqualWithSign(getargs_f(-0.0), -0.0)
+        r = getargs_f(NAN)
+        self.assertNotEqual(r, r)
+
+    def test_d(self):
+        from _testcapi import getargs_d
+        self.assertEqual(getargs_d(4.25), 4.25)
+        self.assertEqual(getargs_d(4), 4.0)
+        self.assertRaises(TypeError, getargs_d, 4.25+0j)
+        self.assertEqual(getargs_d(Float()), 4.25)
+        self.assertEqual(getargs_d(FloatSubclass(7.5)), 7.5)
+        self.assertEqual(getargs_d(FloatSubclass2(7.5)), 7.5)
+        self.assertRaises(TypeError, getargs_d, BadFloat())
+        self.assertEqual(getargs_d(BadFloat2()), 4.25)
+        self.assertEqual(getargs_d(BadFloat3(7.5)), 7.5)
+
+        for x in (DBL_MIN, -DBL_MIN, DBL_MAX, -DBL_MAX, INF, -INF):
+            self.assertEqual(getargs_d(x), x)
+        self.assertRaises(OverflowError, getargs_d, 1<<DBL_MAX_EXP)
+        self.assertRaises(OverflowError, getargs_d, -1<<DBL_MAX_EXP)
+        self.assertEqualWithSign(getargs_d(0.0), 0.0)
+        self.assertEqualWithSign(getargs_d(-0.0), -0.0)
+        r = getargs_d(NAN)
+        self.assertNotEqual(r, r)
+
+    def test_D(self):
+        from _testcapi import getargs_D
+        self.assertEqual(getargs_D(4.25+0.5j), 4.25+0.5j)
+        self.assertEqual(getargs_D(4.25), 4.25+0j)
+        self.assertEqual(getargs_D(4), 4.0+0j)
+        self.assertEqual(getargs_D(Complex()), 4.25+0.5j)
+        self.assertEqual(getargs_D(ComplexSubclass(7.5+0.25j)), 7.5+0.25j)
+        self.assertEqual(getargs_D(ComplexSubclass2(7.5+0.25j)), 7.5+0.25j)
+        self.assertRaises(TypeError, getargs_D, BadComplex())
+        self.assertEqual(getargs_D(BadComplex2()), 4.25+0.5j)
+        self.assertEqual(getargs_D(BadComplex3(7.5+0.25j)), 7.5+0.25j)
+
+        for x in (DBL_MIN, -DBL_MIN, DBL_MAX, -DBL_MAX, INF, -INF):
+            c = complex(x, 1.0)
+            self.assertEqual(getargs_D(c), c)
+            c = complex(1.0, x)
+            self.assertEqual(getargs_D(c), c)
+        self.assertEqualWithSign(getargs_D(complex(0.0, 1.0)).real, 0.0)
+        self.assertEqualWithSign(getargs_D(complex(-0.0, 1.0)).real, -0.0)
+        self.assertEqualWithSign(getargs_D(complex(1.0, 0.0)).imag, 0.0)
+        self.assertEqualWithSign(getargs_D(complex(1.0, -0.0)).imag, -0.0)
+
+
 class Paradox:
     "This statement is false."
     def __bool__(self):
@@ -321,6 +457,33 @@ class Boolean_TestCase(unittest.TestCase):
 
 
 class Tuple_TestCase(unittest.TestCase):
+    def test_args(self):
+        from _testcapi import get_args
+
+        ret = get_args(1, 2)
+        self.assertEqual(ret, (1, 2))
+        self.assertIs(type(ret), tuple)
+
+        ret = get_args(1, *(2, 3))
+        self.assertEqual(ret, (1, 2, 3))
+        self.assertIs(type(ret), tuple)
+
+        ret = get_args(*[1, 2])
+        self.assertEqual(ret, (1, 2))
+        self.assertIs(type(ret), tuple)
+
+        ret = get_args(*TupleSubclass([1, 2]))
+        self.assertEqual(ret, (1, 2))
+        self.assertIsInstance(ret, tuple)
+
+        ret = get_args()
+        self.assertIn(ret, ((), None))
+        self.assertIn(type(ret), (tuple, type(None)))
+
+        ret = get_args(*())
+        self.assertIn(ret, ((), None))
+        self.assertIn(type(ret), (tuple, type(None)))
+
     def test_tuple(self):
         from _testcapi import getargs_tuple
 
@@ -336,6 +499,29 @@ class Tuple_TestCase(unittest.TestCase):
         self.assertRaises(TypeError, getargs_tuple, 1, seq())
 
 class Keywords_TestCase(unittest.TestCase):
+    def test_kwargs(self):
+        from _testcapi import get_kwargs
+
+        ret = get_kwargs(a=1, b=2)
+        self.assertEqual(ret, {'a': 1, 'b': 2})
+        self.assertIs(type(ret), dict)
+
+        ret = get_kwargs(a=1, **{'b': 2, 'c': 3})
+        self.assertEqual(ret, {'a': 1, 'b': 2, 'c': 3})
+        self.assertIs(type(ret), dict)
+
+        ret = get_kwargs(**DictSubclass({'a': 1, 'b': 2}))
+        self.assertEqual(ret, {'a': 1, 'b': 2})
+        self.assertIsInstance(ret, dict)
+
+        ret = get_kwargs()
+        self.assertIn(ret, ({}, None))
+        self.assertIn(type(ret), (dict, type(None)))
+
+        ret = get_kwargs(**{})
+        self.assertIn(ret, ({}, None))
+        self.assertIn(type(ret), (dict, type(None)))
+
     def test_positional_args(self):
         # using all positional args
         self.assertEqual(
@@ -469,16 +655,74 @@ class KeywordOnly_TestCase(unittest.TestCase):
             "'\udc80' is an invalid keyword argument for this function"):
             getargs_keyword_only(1, 2, **{'\uDC80': 10})
 
+
 class Bytes_TestCase(unittest.TestCase):
     def test_c(self):
         from _testcapi import getargs_c
         self.assertRaises(TypeError, getargs_c, b'abc')  # len > 1
-        self.assertEqual(getargs_c(b'a'), b'a')
-        self.assertEqual(getargs_c(bytearray(b'a')), b'a')
+        self.assertEqual(getargs_c(b'a'), 97)
+        self.assertEqual(getargs_c(bytearray(b'a')), 97)
         self.assertRaises(TypeError, getargs_c, memoryview(b'a'))
         self.assertRaises(TypeError, getargs_c, 's')
+        self.assertRaises(TypeError, getargs_c, 97)
         self.assertRaises(TypeError, getargs_c, None)
 
+    def test_y(self):
+        from _testcapi import getargs_y
+        self.assertRaises(TypeError, getargs_y, 'abc\xe9')
+        self.assertEqual(getargs_y(b'bytes'), b'bytes')
+        self.assertRaises(ValueError, getargs_y, b'nul:\0')
+        self.assertRaises(TypeError, getargs_y, bytearray(b'bytearray'))
+        self.assertRaises(TypeError, getargs_y, memoryview(b'memoryview'))
+        self.assertRaises(TypeError, getargs_y, None)
+
+    def test_y_star(self):
+        from _testcapi import getargs_y_star
+        self.assertRaises(TypeError, getargs_y_star, 'abc\xe9')
+        self.assertEqual(getargs_y_star(b'bytes'), b'bytes')
+        self.assertEqual(getargs_y_star(b'nul:\0'), b'nul:\0')
+        self.assertEqual(getargs_y_star(bytearray(b'bytearray')), b'bytearray')
+        self.assertEqual(getargs_y_star(memoryview(b'memoryview')), b'memoryview')
+        self.assertRaises(TypeError, getargs_y_star, None)
+
+    def test_y_hash(self):
+        from _testcapi import getargs_y_hash
+        self.assertRaises(TypeError, getargs_y_hash, 'abc\xe9')
+        self.assertEqual(getargs_y_hash(b'bytes'), b'bytes')
+        self.assertEqual(getargs_y_hash(b'nul:\0'), b'nul:\0')
+        self.assertRaises(TypeError, getargs_y_hash, bytearray(b'bytearray'))
+        self.assertRaises(TypeError, getargs_y_hash, memoryview(b'memoryview'))
+        self.assertRaises(TypeError, getargs_y_hash, None)
+
+    def test_w_star(self):
+        # getargs_w_star() modifies first and last byte
+        from _testcapi import getargs_w_star
+        self.assertRaises(TypeError, getargs_w_star, 'abc\xe9')
+        self.assertRaises(TypeError, getargs_w_star, b'bytes')
+        self.assertRaises(TypeError, getargs_w_star, b'nul:\0')
+        self.assertRaises(TypeError, getargs_w_star, memoryview(b'bytes'))
+        buf = bytearray(b'bytearray')
+        self.assertEqual(getargs_w_star(buf), b'[ytearra]')
+        self.assertEqual(buf, bytearray(b'[ytearra]'))
+        buf = bytearray(b'memoryview')
+        self.assertEqual(getargs_w_star(memoryview(buf)), b'[emoryvie]')
+        self.assertEqual(buf, bytearray(b'[emoryvie]'))
+        self.assertRaises(TypeError, getargs_w_star, None)
+
+
+class String_TestCase(unittest.TestCase):
+    def test_C(self):
+        from _testcapi import getargs_C
+        self.assertRaises(TypeError, getargs_C, 'abc')  # len > 1
+        self.assertEqual(getargs_C('a'), 97)
+        self.assertEqual(getargs_C('\u20ac'), 0x20ac)
+        self.assertEqual(getargs_C('\U0001f40d'), 0x1f40d)
+        self.assertRaises(TypeError, getargs_C, b'a')
+        self.assertRaises(TypeError, getargs_C, bytearray(b'a'))
+        self.assertRaises(TypeError, getargs_C, memoryview(b'a'))
+        self.assertRaises(TypeError, getargs_C, 97)
+        self.assertRaises(TypeError, getargs_C, None)
+
     def test_s(self):
         from _testcapi import getargs_s
         self.assertEqual(getargs_s('abc\xe9'), b'abc\xc3\xa9')
@@ -533,47 +777,82 @@ class Bytes_TestCase(unittest.TestCase):
         self.assertRaises(TypeError, getargs_z_hash, memoryview(b'memoryview'))
         self.assertIsNone(getargs_z_hash(None))
 
-    def test_y(self):
-        from _testcapi import getargs_y
-        self.assertRaises(TypeError, getargs_y, 'abc\xe9')
-        self.assertEqual(getargs_y(b'bytes'), b'bytes')
-        self.assertRaises(ValueError, getargs_y, b'nul:\0')
-        self.assertRaises(TypeError, getargs_y, bytearray(b'bytearray'))
-        self.assertRaises(TypeError, getargs_y, memoryview(b'memoryview'))
-        self.assertRaises(TypeError, getargs_y, None)
+    def test_es(self):
+        from _testcapi import getargs_es
+        self.assertEqual(getargs_es('abc\xe9'), b'abc\xc3\xa9')
+        self.assertEqual(getargs_es('abc\xe9', 'latin1'), b'abc\xe9')
+        self.assertRaises(UnicodeEncodeError, getargs_es, 'abc\xe9', 'ascii')
+        self.assertRaises(LookupError, getargs_es, 'abc\xe9', 'spam')
+        self.assertRaises(TypeError, getargs_es, b'bytes', 'latin1')
+        self.assertRaises(TypeError, getargs_es, bytearray(b'bytearray'), 'latin1')
+        self.assertRaises(TypeError, getargs_es, memoryview(b'memoryview'), 'latin1')
+        self.assertRaises(TypeError, getargs_es, None, 'latin1')
+        self.assertRaises(TypeError, getargs_es, 'nul:\0', 'latin1')
+
+    def test_et(self):
+        from _testcapi import getargs_et
+        self.assertEqual(getargs_et('abc\xe9'), b'abc\xc3\xa9')
+        self.assertEqual(getargs_et('abc\xe9', 'latin1'), b'abc\xe9')
+        self.assertRaises(UnicodeEncodeError, getargs_et, 'abc\xe9', 'ascii')
+        self.assertRaises(LookupError, getargs_et, 'abc\xe9', 'spam')
+        self.assertEqual(getargs_et(b'bytes', 'latin1'), b'bytes')
+        self.assertEqual(getargs_et(bytearray(b'bytearray'), 'latin1'), b'bytearray')
+        self.assertRaises(TypeError, getargs_et, memoryview(b'memoryview'), 'latin1')
+        self.assertRaises(TypeError, getargs_et, None, 'latin1')
+        self.assertRaises(TypeError, getargs_et, 'nul:\0', 'latin1')
+        self.assertRaises(TypeError, getargs_et, b'nul:\0', 'latin1')
+        self.assertRaises(TypeError, getargs_et, bytearray(b'nul:\0'), 'latin1')
+
+    def test_es_hash(self):
+        from _testcapi import getargs_es_hash
+        self.assertEqual(getargs_es_hash('abc\xe9'), b'abc\xc3\xa9')
+        self.assertEqual(getargs_es_hash('abc\xe9', 'latin1'), b'abc\xe9')
+        self.assertRaises(UnicodeEncodeError, getargs_es_hash, 'abc\xe9', 'ascii')
+        self.assertRaises(LookupError, getargs_es_hash, 'abc\xe9', 'spam')
+        self.assertRaises(TypeError, getargs_es_hash, b'bytes', 'latin1')
+        self.assertRaises(TypeError, getargs_es_hash, bytearray(b'bytearray'), 'latin1')
+        self.assertRaises(TypeError, getargs_es_hash, memoryview(b'memoryview'), 'latin1')
+        self.assertRaises(TypeError, getargs_es_hash, None, 'latin1')
+        self.assertEqual(getargs_es_hash('nul:\0', 'latin1'), b'nul:\0')
+
+        buf = bytearray(b'x'*8)
+        self.assertEqual(getargs_es_hash('abc\xe9', 'latin1', buf), b'abc\xe9')
+        self.assertEqual(buf, bytearray(b'abc\xe9\x00xxx'))
+        buf = bytearray(b'x'*5)
+        self.assertEqual(getargs_es_hash('abc\xe9', 'latin1', buf), b'abc\xe9')
+        self.assertEqual(buf, bytearray(b'abc\xe9\x00'))
+        buf = bytearray(b'x'*4)
+        self.assertRaises(TypeError, getargs_es_hash, 'abc\xe9', 'latin1', buf)
+        self.assertEqual(buf, bytearray(b'x'*4))
+        buf = bytearray()
+        self.assertRaises(TypeError, getargs_es_hash, 'abc\xe9', 'latin1', buf)
+
+    def test_et_hash(self):
+        from _testcapi import getargs_et_hash
+        self.assertEqual(getargs_et_hash('abc\xe9'), b'abc\xc3\xa9')
+        self.assertEqual(getargs_et_hash('abc\xe9', 'latin1'), b'abc\xe9')
+        self.assertRaises(UnicodeEncodeError, getargs_et_hash, 'abc\xe9', 'ascii')
+        self.assertRaises(LookupError, getargs_et_hash, 'abc\xe9', 'spam')
+        self.assertEqual(getargs_et_hash(b'bytes', 'latin1'), b'bytes')
+        self.assertEqual(getargs_et_hash(bytearray(b'bytearray'), 'latin1'), b'bytearray')
+        self.assertRaises(TypeError, getargs_et_hash, memoryview(b'memoryview'), 'latin1')
+        self.assertRaises(TypeError, getargs_et_hash, None, 'latin1')
+        self.assertEqual(getargs_et_hash('nul:\0', 'latin1'), b'nul:\0')
+        self.assertEqual(getargs_et_hash(b'nul:\0', 'latin1'), b'nul:\0')
+        self.assertEqual(getargs_et_hash(bytearray(b'nul:\0'), 'latin1'), b'nul:\0')
+
+        buf = bytearray(b'x'*8)
+        self.assertEqual(getargs_et_hash('abc\xe9', 'latin1', buf), b'abc\xe9')
+        self.assertEqual(buf, bytearray(b'abc\xe9\x00xxx'))
+        buf = bytearray(b'x'*5)
+        self.assertEqual(getargs_et_hash('abc\xe9', 'latin1', buf), b'abc\xe9')
+        self.assertEqual(buf, bytearray(b'abc\xe9\x00'))
+        buf = bytearray(b'x'*4)
+        self.assertRaises(TypeError, getargs_et_hash, 'abc\xe9', 'latin1', buf)
+        self.assertEqual(buf, bytearray(b'x'*4))
+        buf = bytearray()
+        self.assertRaises(TypeError, getargs_et_hash, 'abc\xe9', 'latin1', buf)
 
-    def test_y_star(self):
-        from _testcapi import getargs_y_star
-        self.assertRaises(TypeError, getargs_y_star, 'abc\xe9')
-        self.assertEqual(getargs_y_star(b'bytes'), b'bytes')
-        self.assertEqual(getargs_y_star(b'nul:\0'), b'nul:\0')
-        self.assertEqual(getargs_y_star(bytearray(b'bytearray')), b'bytearray')
-        self.assertEqual(getargs_y_star(memoryview(b'memoryview')), b'memoryview')
-        self.assertRaises(TypeError, getargs_y_star, None)
-
-    def test_y_hash(self):
-        from _testcapi import getargs_y_hash
-        self.assertRaises(TypeError, getargs_y_hash, 'abc\xe9')
-        self.assertEqual(getargs_y_hash(b'bytes'), b'bytes')
-        self.assertEqual(getargs_y_hash(b'nul:\0'), b'nul:\0')
-        self.assertRaises(TypeError, getargs_y_hash, bytearray(b'bytearray'))
-        self.assertRaises(TypeError, getargs_y_hash, memoryview(b'memoryview'))
-        self.assertRaises(TypeError, getargs_y_hash, None)
-
-    def test_w_star(self):
-        # getargs_w_star() modifies first and last byte
-        from _testcapi import getargs_w_star
-        self.assertRaises(TypeError, getargs_w_star, 'abc\xe9')
-        self.assertRaises(TypeError, getargs_w_star, b'bytes')
-        self.assertRaises(TypeError, getargs_w_star, b'nul:\0')
-        self.assertRaises(TypeError, getargs_w_star, memoryview(b'bytes'))
-        self.assertEqual(getargs_w_star(bytearray(b'bytearray')), b'[ytearra]')
-        self.assertEqual(getargs_w_star(memoryview(bytearray(b'memoryview'))),
-                         b'[emoryvie]')
-        self.assertRaises(TypeError, getargs_w_star, None)
-
-
-class Unicode_TestCase(unittest.TestCase):
     def test_u(self):
         from _testcapi import getargs_u
         self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9')
@@ -611,5 +890,33 @@ class Unicode_TestCase(unittest.TestCase):
         self.assertIsNone(getargs_Z_hash(None))
 
 
+class Object_TestCase(unittest.TestCase):
+    def test_S(self):
+        from _testcapi import getargs_S
+        obj = b'bytes'
+        self.assertIs(getargs_S(obj), obj)
+        self.assertRaises(TypeError, getargs_S, bytearray(b'bytearray'))
+        self.assertRaises(TypeError, getargs_S, 'str')
+        self.assertRaises(TypeError, getargs_S, None)
+        self.assertRaises(TypeError, getargs_S, memoryview(obj))
+
+    def test_Y(self):
+        from _testcapi import getargs_Y
+        obj = bytearray(b'bytearray')
+        self.assertIs(getargs_Y(obj), obj)
+        self.assertRaises(TypeError, getargs_Y, b'bytes')
+        self.assertRaises(TypeError, getargs_Y, 'str')
+        self.assertRaises(TypeError, getargs_Y, None)
+        self.assertRaises(TypeError, getargs_Y, memoryview(obj))
+
+    def test_U(self):
+        from _testcapi import getargs_U
+        obj = 'str'
+        self.assertIs(getargs_U(obj), obj)
+        self.assertRaises(TypeError, getargs_U, b'bytes')
+        self.assertRaises(TypeError, getargs_U, bytearray(b'bytearray'))
+        self.assertRaises(TypeError, getargs_U, None)
+
+
 if __name__ == "__main__":
     unittest.main()
index ec3d783..154e3b6 100644 (file)
@@ -994,7 +994,7 @@ class GrammarTests(unittest.TestCase):
         # Test ifelse expressions in various cases
         def _checkeval(msg, ret):
             "helper to check that evaluation of expressions is done correctly"
-            print(x)
+            print(msg)
             return ret
 
         # the next line is not allowed anymore
@@ -1076,7 +1076,7 @@ class GrammarTests(unittest.TestCase):
         class Done(Exception): pass
 
         class AIter:
-            async def __aiter__(self):
+            def __aiter__(self):
                 return self
             async def __anext__(self):
                 raise StopAsyncIteration
index 85ec2f9..c9b113e 100644 (file)
@@ -449,7 +449,7 @@ class KDFTests(unittest.TestCase):
 
     pbkdf2_results = {
         "sha1": [
-            # offical test vectors from RFC 6070
+            # official test vectors from RFC 6070
             (bytes.fromhex('0c60c80f961f0e71f3a9b524af6012062fe037a6'), None),
             (bytes.fromhex('ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'), None),
             (bytes.fromhex('4b007901b765489abead49d926f721d065a429c1'), None),
@@ -513,6 +513,9 @@ class KDFTests(unittest.TestCase):
         self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', 1, -1)
         with self.assertRaisesRegex(ValueError, 'unsupported hash type'):
             pbkdf2('unknown', b'pass', b'salt', 1)
+        out = pbkdf2(hash_name='sha1', password=b'password', salt=b'salt',
+            iterations=1, dklen=None)
+        self.assertEqual(out, self.pbkdf2_results['sha1'][0][0])
 
     def test_pbkdf2_hmac_py(self):
         self._test_pbkdf2_hmac(py_hashlib.pbkdf2_hmac)
index 50260ff..585838b 100644 (file)
@@ -91,6 +91,10 @@ class DateTimeTests(unittest.TestCase):
             '01-01-1980 25:00:00',
             '01-01-1980 00:61:00',
             '01-01-1980 00:00:62',
+            '08-Oct-3697739',
+            '08-01-3697739',
+            '09 Feb 19942632 22:23:32 GMT',
+            'Wed, 09 Feb 1994834 22:23:32 GMT',
             ]:
             self.assertIsNone(http2time(test),
                               "http2time(%s) is not None\n"
@@ -1725,7 +1729,7 @@ class LWPCookieTests(unittest.TestCase):
             key = "%s_after" % cookie.value
             counter[key] = counter[key] + 1
 
-            # a permanent cookie got lost accidently
+            # a permanent cookie got lost accidentally
         self.assertEqual(counter["perm_after"], counter["perm_before"])
             # a session cookie hasn't been cleared
         self.assertEqual(counter["session_after"], 0)
index d3e06a4..2432e0b 100644 (file)
@@ -210,6 +210,12 @@ class CookieTests(unittest.TestCase):
                 C1 = pickle.loads(pickle.dumps(C, protocol=proto))
                 self.assertEqual(C1.output(), expected_output)
 
+    def test_illegal_chars(self):
+        rawdata = "a=b; c,d=e"
+        C = cookies.SimpleCookie()
+        with self.assertRaises(cookies.CookieError):
+            C.load(rawdata)
+
 
 class MorselTests(unittest.TestCase):
     """Tests for the Morsel object."""
index d809414..329f068 100644 (file)
@@ -255,8 +255,8 @@ class HeaderTests(TestCase):
         self.assertIn(b'\xa0NonbreakSpace: value', conn._buffer)
 
     def test_ipv6host_header(self):
-        # Default host header on IPv6 transaction should wrapped by [] if
-        # its actual IPv6 address
+        # Default host header on IPv6 transaction should be wrapped by [] if
+        # it is an IPv6 address
         expected = b'GET /foo HTTP/1.1\r\nHost: [2001::]:81\r\n' \
                    b'Accept-Encoding: identity\r\n\r\n'
         conn = client.HTTPConnection('[2001::]:81')
@@ -341,8 +341,8 @@ class BasicTest(TestCase):
         self.assertEqual(repr(exc), '''BadStatusLine("\'\'",)''')
 
     def test_partial_reads(self):
-        # if we have a length, the system knows when to close itself
-        # same behaviour than when we read the whole thing with read()
+        # if we have Content-Length, HTTPResponse knows when to close itself,
+        # the same behaviour as when we read the whole thing with read()
         body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
         sock = FakeSocket(body)
         resp = client.HTTPResponse(sock)
@@ -355,9 +355,24 @@ class BasicTest(TestCase):
         resp.close()
         self.assertTrue(resp.closed)
 
+    def test_mixed_reads(self):
+        # readline() should update the remaining length, so that read() knows
+        # how much data is left and does not raise IncompleteRead
+        body = "HTTP/1.1 200 Ok\r\nContent-Length: 13\r\n\r\nText\r\nAnother"
+        sock = FakeSocket(body)
+        resp = client.HTTPResponse(sock)
+        resp.begin()
+        self.assertEqual(resp.readline(), b'Text\r\n')
+        self.assertFalse(resp.isclosed())
+        self.assertEqual(resp.read(), b'Another')
+        self.assertTrue(resp.isclosed())
+        self.assertFalse(resp.closed)
+        resp.close()
+        self.assertTrue(resp.closed)
+
     def test_partial_readintos(self):
-        # if we have a length, the system knows when to close itself
-        # same behaviour than when we read the whole thing with read()
+        # if we have Content-Length, HTTPResponse knows when to close itself,
+        # the same behaviour as when we read the whole thing with read()
         body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
         sock = FakeSocket(body)
         resp = client.HTTPResponse(sock)
@@ -827,7 +842,7 @@ class BasicTest(TestCase):
         resp.begin()
         self.assertEqual(resp.read(), expected)
         # we should have reached the end of the file
-        self.assertEqual(sock.file.read(100), b"") #we read to the end
+        self.assertEqual(sock.file.read(), b"") #we read to the end
         resp.close()
 
     def test_chunked_sync(self):
@@ -839,21 +854,108 @@ class BasicTest(TestCase):
         resp.begin()
         self.assertEqual(resp.read(), expected)
         # the file should now have our extradata ready to be read
-        self.assertEqual(sock.file.read(100), extradata.encode("ascii")) #we read to the end
+        self.assertEqual(sock.file.read(), extradata.encode("ascii")) #we read to the end
         resp.close()
 
     def test_content_length_sync(self):
         """Check that we don't read past the end of the Content-Length stream"""
-        extradata = "extradata"
+        extradata = b"extradata"
+        expected = b"Hello123\r\n"
+        sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n' + expected + extradata)
+        resp = client.HTTPResponse(sock, method="GET")
+        resp.begin()
+        self.assertEqual(resp.read(), expected)
+        # the file should now have our extradata ready to be read
+        self.assertEqual(sock.file.read(), extradata) #we read to the end
+        resp.close()
+
+    def test_readlines_content_length(self):
+        extradata = b"extradata"
+        expected = b"Hello123\r\n"
+        sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n' + expected + extradata)
+        resp = client.HTTPResponse(sock, method="GET")
+        resp.begin()
+        self.assertEqual(resp.readlines(2000), [expected])
+        # the file should now have our extradata ready to be read
+        self.assertEqual(sock.file.read(), extradata) #we read to the end
+        resp.close()
+
+    def test_read1_content_length(self):
+        extradata = b"extradata"
+        expected = b"Hello123\r\n"
+        sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n' + expected + extradata)
+        resp = client.HTTPResponse(sock, method="GET")
+        resp.begin()
+        self.assertEqual(resp.read1(2000), expected)
+        # the file should now have our extradata ready to be read
+        self.assertEqual(sock.file.read(), extradata) #we read to the end
+        resp.close()
+
+    def test_readline_bound_content_length(self):
+        extradata = b"extradata"
+        expected = b"Hello123\r\n"
+        sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n' + expected + extradata)
+        resp = client.HTTPResponse(sock, method="GET")
+        resp.begin()
+        self.assertEqual(resp.readline(10), expected)
+        self.assertEqual(resp.readline(10), b"")
+        # the file should now have our extradata ready to be read
+        self.assertEqual(sock.file.read(), extradata) #we read to the end
+        resp.close()
+
+    def test_read1_bound_content_length(self):
+        extradata = b"extradata"
         expected = b"Hello123\r\n"
-        sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello123\r\n' + extradata)
+        sock = FakeSocket(b'HTTP/1.1 200 OK\r\nContent-Length: 30\r\n\r\n' + expected*3 + extradata)
         resp = client.HTTPResponse(sock, method="GET")
         resp.begin()
+        self.assertEqual(resp.read1(20), expected*2)
         self.assertEqual(resp.read(), expected)
         # the file should now have our extradata ready to be read
-        self.assertEqual(sock.file.read(100), extradata.encode("ascii")) #we read to the end
+        self.assertEqual(sock.file.read(), extradata) #we read to the end
         resp.close()
 
+    def test_response_fileno(self):
+        # Make sure fd returned by fileno is valid.
+        threading = support.import_module("threading")
+
+        serv = socket.socket(
+            socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
+        self.addCleanup(serv.close)
+        serv.bind((HOST, 0))
+        serv.listen()
+
+        result = None
+        def run_server():
+            [conn, address] = serv.accept()
+            with conn, conn.makefile("rb") as reader:
+                # Read the request header until a blank line
+                while True:
+                    line = reader.readline()
+                    if not line.rstrip(b"\r\n"):
+                        break
+                conn.sendall(b"HTTP/1.1 200 Connection established\r\n\r\n")
+                nonlocal result
+                result = reader.read()
+
+        thread = threading.Thread(target=run_server)
+        thread.start()
+        conn = client.HTTPConnection(*serv.getsockname())
+        conn.request("CONNECT", "dummy:1234")
+        response = conn.getresponse()
+        try:
+            self.assertEqual(response.status, client.OK)
+            s = socket.socket(fileno=response.fileno())
+            try:
+                s.sendall(b"proxied data\n")
+            finally:
+                s.detach()
+        finally:
+            response.close()
+            conn.close()
+            thread.join()
+        self.assertEqual(result, b"proxied data\n")
+
 class ExtendedReadTest(TestCase):
     """
     Test peek(), read1(), readline()
@@ -1042,7 +1144,7 @@ class OfflineTest(TestCase):
         # intentionally omitted for simplicity
         blacklist = {"HTTPMessage", "parse_headers"}
         for name in dir(client):
-            if name in blacklist:
+            if name.startswith("_") or name in blacklist:
                 continue
             module_object = getattr(client, name)
             if getattr(module_object, "__module__", None) == "http.client":
index d4c8eab..72e6e08 100644 (file)
@@ -12,6 +12,7 @@ import os
 import sys
 import re
 import base64
+import ntpath
 import shutil
 import urllib.parse
 import html
@@ -98,7 +99,7 @@ class BaseHTTPServerTestCase(BaseTestCase):
 
         def do_EXPLAINERROR(self):
             self.send_error(999, "Short Message",
-                            "This is a long \n explaination")
+                            "This is a long \n explanation")
 
         def do_CUSTOM(self):
             self.send_response(999)
@@ -114,6 +115,12 @@ class BaseHTTPServerTestCase(BaseTestCase):
             body = self.headers['x-special-incoming'].encode('utf-8')
             self.wfile.write(body)
 
+        def do_SEND_ERROR(self):
+            self.send_error(int(self.path[1:]))
+
+        def do_HEAD(self):
+            self.send_error(int(self.path[1:]))
+
     def setUp(self):
         BaseTestCase.setUp(self)
         self.con = http.client.HTTPConnection(self.HOST, self.PORT)
@@ -235,6 +242,44 @@ class BaseHTTPServerTestCase(BaseTestCase):
         data = res.read()
         self.assertEqual(int(res.getheader('Content-Length')), len(data))
 
+    def test_send_error(self):
+        allow_transfer_encoding_codes = (HTTPStatus.NOT_MODIFIED,
+                                         HTTPStatus.RESET_CONTENT)
+        for code in (HTTPStatus.NO_CONTENT, HTTPStatus.NOT_MODIFIED,
+                     HTTPStatus.PROCESSING, HTTPStatus.RESET_CONTENT,
+                     HTTPStatus.SWITCHING_PROTOCOLS):
+            self.con.request('SEND_ERROR', '/{}'.format(code))
+            res = self.con.getresponse()
+            self.assertEqual(code, res.status)
+            self.assertEqual(None, res.getheader('Content-Length'))
+            self.assertEqual(None, res.getheader('Content-Type'))
+            if code not in allow_transfer_encoding_codes:
+                self.assertEqual(None, res.getheader('Transfer-Encoding'))
+
+            data = res.read()
+            self.assertEqual(b'', data)
+
+    def test_head_via_send_error(self):
+        allow_transfer_encoding_codes = (HTTPStatus.NOT_MODIFIED,
+                                         HTTPStatus.RESET_CONTENT)
+        for code in (HTTPStatus.OK, HTTPStatus.NO_CONTENT,
+                     HTTPStatus.NOT_MODIFIED, HTTPStatus.RESET_CONTENT,
+                     HTTPStatus.SWITCHING_PROTOCOLS):
+            self.con.request('HEAD', '/{}'.format(code))
+            res = self.con.getresponse()
+            self.assertEqual(code, res.status)
+            if code == HTTPStatus.OK:
+                self.assertTrue(int(res.getheader('Content-Length')) > 0)
+                self.assertIn('text/html', res.getheader('Content-Type'))
+            else:
+                self.assertEqual(None, res.getheader('Content-Length'))
+                self.assertEqual(None, res.getheader('Content-Type'))
+            if code not in allow_transfer_encoding_codes:
+                self.assertEqual(None, res.getheader('Transfer-Encoding'))
+
+            data = res.read()
+            self.assertEqual(b'', data)
+
 
 class RequestHandlerLoggingTestCase(BaseTestCase):
     class request_handler(BaseHTTPRequestHandler):
@@ -284,6 +329,7 @@ class SimpleHTTPServerTestCase(BaseTestCase):
         self.data = b'We are the knights who say Ni!'
         self.tempdir = tempfile.mkdtemp(dir=basetempdir)
         self.tempdir_name = os.path.basename(self.tempdir)
+        self.base_url = '/' + self.tempdir_name
         with open(os.path.join(self.tempdir, 'test'), 'wb') as temp:
             temp.write(self.data)
 
@@ -330,7 +376,7 @@ class SimpleHTTPServerTestCase(BaseTestCase):
         filename = os.fsdecode(support.TESTFN_UNDECODABLE) + '.txt'
         with open(os.path.join(self.tempdir, filename), 'wb') as f:
             f.write(support.TESTFN_UNDECODABLE)
-        response = self.request(self.tempdir_name + '/')
+        response = self.request(self.base_url + '/')
         if sys.platform == 'darwin':
             # On Mac OS the HFS+ filesystem replaces bytes that aren't valid
             # UTF-8 into a percent-encoded value.
@@ -344,27 +390,27 @@ class SimpleHTTPServerTestCase(BaseTestCase):
                       .encode(enc, 'surrogateescape'), body)
         self.assertIn(('>%s<' % html.escape(filename))
                       .encode(enc, 'surrogateescape'), body)
-        response = self.request(self.tempdir_name + '/' + quotedname)
+        response = self.request(self.base_url + '/' + quotedname)
         self.check_status_and_reason(response, HTTPStatus.OK,
                                      data=support.TESTFN_UNDECODABLE)
 
     def test_get(self):
         #constructs the path relative to the root directory of the HTTPServer
-        response = self.request(self.tempdir_name + '/test')
+        response = self.request(self.base_url + '/test')
         self.check_status_and_reason(response, HTTPStatus.OK, data=self.data)
         # check for trailing "/" which should return 404. See Issue17324
-        response = self.request(self.tempdir_name + '/test/')
+        response = self.request(self.base_url + '/test/')
         self.check_status_and_reason(response, HTTPStatus.NOT_FOUND)
-        response = self.request(self.tempdir_name + '/')
+        response = self.request(self.base_url + '/')
         self.check_status_and_reason(response, HTTPStatus.OK)
-        response = self.request(self.tempdir_name)
+        response = self.request(self.base_url)
         self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY)
-        response = self.request(self.tempdir_name + '/?hi=2')
+        response = self.request(self.base_url + '/?hi=2')
         self.check_status_and_reason(response, HTTPStatus.OK)
-        response = self.request(self.tempdir_name + '?hi=1')
+        response = self.request(self.base_url + '?hi=1')
         self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY)
         self.assertEqual(response.getheader("Location"),
-                         self.tempdir_name + "/?hi=1")
+                         self.base_url + "/?hi=1")
         response = self.request('/ThisDoesNotExist')
         self.check_status_and_reason(response, HTTPStatus.NOT_FOUND)
         response = self.request('/' + 'ThisDoesNotExist' + '/')
@@ -373,7 +419,7 @@ class SimpleHTTPServerTestCase(BaseTestCase):
         data = b"Dummy index file\r\n"
         with open(os.path.join(self.tempdir_name, 'index.html'), 'wb') as f:
             f.write(data)
-        response = self.request('/' + self.tempdir_name + '/')
+        response = self.request(self.base_url + '/')
         self.check_status_and_reason(response, HTTPStatus.OK, data)
 
         # chmod() doesn't work as expected on Windows, and filesystem
@@ -381,14 +427,14 @@ class SimpleHTTPServerTestCase(BaseTestCase):
         if os.name == 'posix' and os.geteuid() != 0:
             os.chmod(self.tempdir, 0)
             try:
-                response = self.request(self.tempdir_name + '/')
+                response = self.request(self.base_url + '/')
                 self.check_status_and_reason(response, HTTPStatus.NOT_FOUND)
             finally:
                 os.chmod(self.tempdir, 0o755)
 
     def test_head(self):
         response = self.request(
-            self.tempdir_name + '/test', method='HEAD')
+            self.base_url + '/test', method='HEAD')
         self.check_status_and_reason(response, HTTPStatus.OK)
         self.assertEqual(response.getheader('content-length'),
                          str(len(self.data)))
@@ -404,6 +450,22 @@ class SimpleHTTPServerTestCase(BaseTestCase):
         response = self.request('/', method='GETs')
         self.check_status_and_reason(response, HTTPStatus.NOT_IMPLEMENTED)
 
+    def test_path_without_leading_slash(self):
+        response = self.request(self.tempdir_name + '/test')
+        self.check_status_and_reason(response, HTTPStatus.OK, data=self.data)
+        response = self.request(self.tempdir_name + '/test/')
+        self.check_status_and_reason(response, HTTPStatus.NOT_FOUND)
+        response = self.request(self.tempdir_name + '/')
+        self.check_status_and_reason(response, HTTPStatus.OK)
+        response = self.request(self.tempdir_name)
+        self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY)
+        response = self.request(self.tempdir_name + '/?hi=2')
+        self.check_status_and_reason(response, HTTPStatus.OK)
+        response = self.request(self.tempdir_name + '?hi=1')
+        self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY)
+        self.assertEqual(response.getheader("Location"),
+                         self.tempdir_name + "/?hi=1")
+
 
 cgi_file1 = """\
 #!%s
@@ -858,6 +920,13 @@ class BaseHTTPRequestHandlerTestCase(unittest.TestCase):
         self.assertFalse(self.handler.get_called)
         self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1')
 
+    def test_too_many_headers(self):
+        result = self.send_typical_request(
+            b'GET / HTTP/1.1\r\n' + b'X-Foo: bar\r\n' * 101 + b'\r\n')
+        self.assertEqual(result[0], b'HTTP/1.1 431 Too many headers\r\n')
+        self.assertFalse(self.handler.get_called)
+        self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1')
+
     def test_close_connection(self):
         # handle_one_request() should be repeatedly called until
         # it sets close_connection
@@ -894,6 +963,24 @@ class SimpleHTTPRequestHandlerTestCase(unittest.TestCase):
         path = self.handler.translate_path('//filename?foo=bar')
         self.assertEqual(path, self.translated)
 
+    def test_windows_colon(self):
+        with support.swap_attr(server.os, 'path', ntpath):
+            path = self.handler.translate_path('c:c:c:foo/filename')
+            path = path.replace(ntpath.sep, os.sep)
+            self.assertEqual(path, self.translated)
+
+            path = self.handler.translate_path('\\c:../filename')
+            path = path.replace(ntpath.sep, os.sep)
+            self.assertEqual(path, self.translated)
+
+            path = self.handler.translate_path('c:\\c:..\\foo/filename')
+            path = path.replace(ntpath.sep, os.sep)
+            self.assertEqual(path, self.translated)
+
+            path = self.handler.translate_path('c:c:foo\\c:c:bar/filename')
+            path = path.replace(ntpath.sep, os.sep)
+            self.assertEqual(path, self.translated)
+
 
 class MiscTestCase(unittest.TestCase):
     def test_all(self):
index 14a688d..1e33274 100644 (file)
@@ -278,6 +278,7 @@ class ImportTests(unittest.TestCase):
             """))
         script_helper.assert_python_ok(testfn)
 
+    @skip_if_dont_write_bytecode
     def test_timestamp_overflow(self):
         # A modification timestamp larger than 2**32 should not be a problem
         # when importing a module (issue #11235).
index 28bb6f7..3bb819f 100644 (file)
@@ -207,6 +207,11 @@ class RelativeImports:
         with self.assertRaises(KeyError):
             self.__import__('sys', level=1)
 
+    def test_relative_import_no_package_exists_absolute(self):
+        with self.assertRaises(SystemError):
+            self.__import__('sys', {'__package__': '', '__spec__': None},
+                            level=1)
+
 
 (Frozen_RelativeImports,
  Source_RelativeImports
index b604afb..1e0771b 100644 (file)
@@ -14,7 +14,7 @@ import unittest
 import warnings
 
 
-CODING_RE = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII)
+CODING_RE = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII)
 
 
 class EncodingTest:
index 2e191bb..774b7a4 100644 (file)
@@ -54,6 +54,7 @@ class LazyLoaderTests(unittest.TestCase):
 
     def test_init(self):
         with self.assertRaises(TypeError):
+            # Classes that dono't define exec_module() trigger TypeError.
             util.LazyLoader(object)
 
     def new_module(self, source_code=None):
index 69ddb51..671e05a 100644 (file)
@@ -3324,6 +3324,13 @@ class TestBoundArguments(unittest.TestCase):
         ba.apply_defaults()
         self.assertEqual(list(ba.arguments.items()), [])
 
+        # Make sure a no-args binding still acquires proper defaults.
+        def foo(a='spam'): pass
+        sig = inspect.signature(foo)
+        ba = sig.bind()
+        ba.apply_defaults()
+        self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
+
 
 class TestSignaturePrivateHelpers(unittest.TestCase):
     def test_signature_get_bound_param(self):
index 3e4b4fc..b66c5d6 100644 (file)
@@ -24,6 +24,9 @@ L = [
         ("\u0200", ValueError)
 ]
 
+class IntSubclass(int):
+    pass
+
 class IntTestCases(unittest.TestCase):
 
     def test_basic(self):
@@ -441,6 +444,10 @@ class IntTestCases(unittest.TestCase):
         good_int = TruncReturnsIntSubclass()
         n = int(good_int)
         self.assertEqual(n, 1)
+        self.assertIs(type(n), bool)
+        n = IntSubclass(good_int)
+        self.assertEqual(n, 1)
+        self.assertIs(type(n), IntSubclass)
 
     def test_error_message(self):
         def check(s, base=None):
index 28f440d..000b525 100644 (file)
@@ -45,6 +45,22 @@ try:
 except ImportError:
     threading = None
 
+try:
+    import ctypes
+except ImportError:
+    def byteslike(*pos, **kw):
+        return array.array("b", bytes(*pos, **kw))
+else:
+    def byteslike(*pos, **kw):
+        """Create a bytes-like object having no string or sequence methods"""
+        data = bytes(*pos, **kw)
+        obj = EmptyStruct()
+        ctypes.resize(obj, len(data))
+        memoryview(obj).cast("B")[:] = data
+        return obj
+    class EmptyStruct(ctypes.Structure):
+        pass
+
 def _default_chunk_size():
     """Get the default TextIOWrapper chunk size"""
     with open(__file__, "r", encoding="latin-1") as f:
@@ -203,6 +219,9 @@ class MockUnseekableIO:
     def tell(self, *args):
         raise self.UnsupportedOperation("not seekable")
 
+    def truncate(self, *args):
+        raise self.UnsupportedOperation("not seekable")
+
 class CMockUnseekableIO(MockUnseekableIO, io.BytesIO):
     UnsupportedOperation = io.UnsupportedOperation
 
@@ -281,7 +300,9 @@ class IOTest(unittest.TestCase):
         self.assertEqual(f.tell(), 6)
         self.assertEqual(f.seek(-1, 1), 5)
         self.assertEqual(f.tell(), 5)
-        self.assertEqual(f.write(bytearray(b" world\n\n\n")), 9)
+        buffer = bytearray(b" world\n\n\n")
+        self.assertEqual(f.write(buffer), 9)
+        buffer[:] = b"*" * 9  # Overwrite our copy of the data
         self.assertEqual(f.seek(0), 0)
         self.assertEqual(f.write(b"h"), 1)
         self.assertEqual(f.seek(-1, 2), 13)
@@ -294,20 +315,21 @@ class IOTest(unittest.TestCase):
     def read_ops(self, f, buffered=False):
         data = f.read(5)
         self.assertEqual(data, b"hello")
-        data = bytearray(data)
+        data = byteslike(data)
         self.assertEqual(f.readinto(data), 5)
-        self.assertEqual(data, b" worl")
+        self.assertEqual(bytes(data), b" worl")
+        data = bytearray(5)
         self.assertEqual(f.readinto(data), 2)
         self.assertEqual(len(data), 5)
         self.assertEqual(data[:2], b"d\n")
         self.assertEqual(f.seek(0), 0)
         self.assertEqual(f.read(20), b"hello world\n")
         self.assertEqual(f.read(1), b"")
-        self.assertEqual(f.readinto(bytearray(b"x")), 0)
+        self.assertEqual(f.readinto(byteslike(b"x")), 0)
         self.assertEqual(f.seek(-6, 2), 6)
         self.assertEqual(f.read(5), b"world")
         self.assertEqual(f.read(0), b"")
-        self.assertEqual(f.readinto(bytearray()), 0)
+        self.assertEqual(f.readinto(byteslike()), 0)
         self.assertEqual(f.seek(-6, 1), 5)
         self.assertEqual(f.read(5), b" worl")
         self.assertEqual(f.tell(), 10)
@@ -318,6 +340,10 @@ class IOTest(unittest.TestCase):
             f.seek(6)
             self.assertEqual(f.read(), b"world\n")
             self.assertEqual(f.read(), b"")
+            f.seek(0)
+            data = byteslike(5)
+            self.assertEqual(f.readinto1(data), 5)
+            self.assertEqual(bytes(data), b"hello")
 
     LARGE = 2**31
 
@@ -361,6 +387,112 @@ class IOTest(unittest.TestCase):
             self.assertRaises(exc, fp.seek, 1, self.SEEK_CUR)
             self.assertRaises(exc, fp.seek, -1, self.SEEK_END)
 
+    def test_optional_abilities(self):
+        # Test for OSError when optional APIs are not supported
+        # The purpose of this test is to try fileno(), reading, writing and
+        # seeking operations with various objects that indicate they do not
+        # support these operations.
+
+        def pipe_reader():
+            [r, w] = os.pipe()
+            os.close(w)  # So that read() is harmless
+            return self.FileIO(r, "r")
+
+        def pipe_writer():
+            [r, w] = os.pipe()
+            self.addCleanup(os.close, r)
+            # Guarantee that we can write into the pipe without blocking
+            thread = threading.Thread(target=os.read, args=(r, 100))
+            thread.start()
+            self.addCleanup(thread.join)
+            return self.FileIO(w, "w")
+
+        def buffered_reader():
+            return self.BufferedReader(self.MockUnseekableIO())
+
+        def buffered_writer():
+            return self.BufferedWriter(self.MockUnseekableIO())
+
+        def buffered_random():
+            return self.BufferedRandom(self.BytesIO())
+
+        def buffered_rw_pair():
+            return self.BufferedRWPair(self.MockUnseekableIO(),
+                self.MockUnseekableIO())
+
+        def text_reader():
+            class UnseekableReader(self.MockUnseekableIO):
+                writable = self.BufferedIOBase.writable
+                write = self.BufferedIOBase.write
+            return self.TextIOWrapper(UnseekableReader(), "ascii")
+
+        def text_writer():
+            class UnseekableWriter(self.MockUnseekableIO):
+                readable = self.BufferedIOBase.readable
+                read = self.BufferedIOBase.read
+            return self.TextIOWrapper(UnseekableWriter(), "ascii")
+
+        tests = (
+            (pipe_reader, "fr"), (pipe_writer, "fw"),
+            (buffered_reader, "r"), (buffered_writer, "w"),
+            (buffered_random, "rws"), (buffered_rw_pair, "rw"),
+            (text_reader, "r"), (text_writer, "w"),
+            (self.BytesIO, "rws"), (self.StringIO, "rws"),
+        )
+        for [test, abilities] in tests:
+            if test is pipe_writer and not threading:
+                continue  # Skip subtest that uses a background thread
+            with self.subTest(test), test() as obj:
+                readable = "r" in abilities
+                self.assertEqual(obj.readable(), readable)
+                writable = "w" in abilities
+                self.assertEqual(obj.writable(), writable)
+
+                if isinstance(obj, self.TextIOBase):
+                    data = "3"
+                elif isinstance(obj, (self.BufferedIOBase, self.RawIOBase)):
+                    data = b"3"
+                else:
+                    self.fail("Unknown base class")
+
+                if "f" in abilities:
+                    obj.fileno()
+                else:
+                    self.assertRaises(OSError, obj.fileno)
+
+                if readable:
+                    obj.read(1)
+                    obj.read()
+                else:
+                    self.assertRaises(OSError, obj.read, 1)
+                    self.assertRaises(OSError, obj.read)
+
+                if writable:
+                    obj.write(data)
+                else:
+                    self.assertRaises(OSError, obj.write, data)
+
+                if sys.platform.startswith("win") and test in (
+                        pipe_reader, pipe_writer):
+                    # Pipes seem to appear as seekable on Windows
+                    continue
+                seekable = "s" in abilities
+                self.assertEqual(obj.seekable(), seekable)
+
+                if seekable:
+                    obj.tell()
+                    obj.seek(0)
+                else:
+                    self.assertRaises(OSError, obj.tell)
+                    self.assertRaises(OSError, obj.seek, 0)
+
+                if writable and seekable:
+                    obj.truncate()
+                    obj.truncate(0)
+                else:
+                    self.assertRaises(OSError, obj.truncate)
+                    self.assertRaises(OSError, obj.truncate, 0)
+
     def test_open_handles_NUL_chars(self):
         fn_with_NUL = 'foo\0bar'
         self.assertRaises(ValueError, self.open, fn_with_NUL, 'w')
@@ -528,10 +660,15 @@ class IOTest(unittest.TestCase):
     def test_array_writes(self):
         a = array.array('i', range(10))
         n = len(a.tobytes())
-        with self.open(support.TESTFN, "wb", 0) as f:
-            self.assertEqual(f.write(a), n)
-        with self.open(support.TESTFN, "wb") as f:
-            self.assertEqual(f.write(a), n)
+        def check(f):
+            with f:
+                self.assertEqual(f.write(a), n)
+                f.writelines((a,))
+        check(self.BytesIO())
+        check(self.FileIO(support.TESTFN, "w"))
+        check(self.BufferedWriter(self.MockRawIO()))
+        check(self.BufferedRandom(self.MockRawIO()))
+        check(self.BufferedRWPair(self.MockRawIO(), self.MockRawIO()))
 
     def test_closefd(self):
         self.assertRaises(ValueError, self.open, support.TESTFN, 'w',
@@ -668,6 +805,22 @@ class IOTest(unittest.TestCase):
         with self.open("non-existent", "r", opener=opener) as f:
             self.assertEqual(f.read(), "egg\n")
 
+    def test_bad_opener_negative_1(self):
+        # Issue #27066.
+        def badopener(fname, flags):
+            return -1
+        with self.assertRaises(ValueError) as cm:
+            open('non-existent', 'r', opener=badopener)
+        self.assertEqual(str(cm.exception), 'opener returned -1')
+
+    def test_bad_opener_other_negative(self):
+        # Issue #27066.
+        def badopener(fname, flags):
+            return -2
+        with self.assertRaises(ValueError) as cm:
+            open('non-existent', 'r', opener=badopener)
+        self.assertEqual(str(cm.exception), 'opener returned -2')
+
     def test_fileio_closefd(self):
         # Issue #4841
         with self.open(__file__, 'rb') as f1, \
@@ -681,18 +834,27 @@ class IOTest(unittest.TestCase):
             f2.readline()
 
     def test_nonbuffered_textio(self):
-        with warnings.catch_warnings(record=True) as recorded:
+        with support.check_no_resource_warning(self):
             with self.assertRaises(ValueError):
                 self.open(support.TESTFN, 'w', buffering=0)
-            support.gc_collect()
-        self.assertEqual(recorded, [])
 
     def test_invalid_newline(self):
-        with warnings.catch_warnings(record=True) as recorded:
+        with support.check_no_resource_warning(self):
             with self.assertRaises(ValueError):
                 self.open(support.TESTFN, 'w', newline='invalid')
-            support.gc_collect()
-        self.assertEqual(recorded, [])
+
+    def test_buffered_readinto_mixin(self):
+        # Test the implementation provided by BufferedIOBase
+        class Stream(self.BufferedIOBase):
+            def read(self, size):
+                return b"12345"
+            read1 = read
+        stream = Stream()
+        for method in ("readinto", "readinto1"):
+            with self.subTest(method):
+                buffer = byteslike(5)
+                self.assertEqual(getattr(stream, method)(buffer), 5)
+                self.assertEqual(bytes(buffer), b"12345")
 
 
 class CIOTest(IOTest):
@@ -751,12 +913,6 @@ class CommonBufferedTests:
 
         self.assertEqual(42, bufio.fileno())
 
-    @unittest.skip('test having existential crisis')
-    def test_no_fileno(self):
-        # XXX will we always have fileno() function? If so, kill
-        # this test. Else, write it.
-        pass
-
     def test_invalid_args(self):
         rawio = self.MockRawIO()
         bufio = self.tp(rawio)
@@ -784,13 +940,9 @@ class CommonBufferedTests:
                 super().flush()
         rawio = self.MockRawIO()
         bufio = MyBufferedIO(rawio)
-        writable = bufio.writable()
         del bufio
         support.gc_collect()
-        if writable:
-            self.assertEqual(record, [1, 2, 3])
-        else:
-            self.assertEqual(record, [1, 2])
+        self.assertEqual(record, [1, 2, 3])
 
     def test_context_manager(self):
         # Test usability as a context manager
@@ -1295,6 +1447,11 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests):
         bufio = self.tp(writer, 8)
         bufio.write(b"abc")
         self.assertFalse(writer._write_stack)
+        buffer = bytearray(b"def")
+        bufio.write(buffer)
+        buffer[:] = b"***"  # Overwrite our copy of the data
+        bufio.flush()
+        self.assertEqual(b"".join(writer._write_stack), b"abcdef")
 
     def test_write_overflow(self):
         writer = self.MockRawIO()
@@ -1621,11 +1778,13 @@ class BufferedRWPairTest(unittest.TestCase):
         self.assertEqual(pair.read1(3), b"abc")
 
     def test_readinto(self):
-        pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
+        for method in ("readinto", "readinto1"):
+            with self.subTest(method):
+                pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
 
-        data = bytearray(5)
-        self.assertEqual(pair.readinto(data), 5)
-        self.assertEqual(data, b"abcde")
+                data = byteslike(5)
+                self.assertEqual(getattr(pair, method)(data), 5)
+                self.assertEqual(bytes(data), b"abcde")
 
     def test_write(self):
         w = self.MockRawIO()
@@ -1633,7 +1792,9 @@ class BufferedRWPairTest(unittest.TestCase):
 
         pair.write(b"abc")
         pair.flush()
-        pair.write(b"def")
+        buffer = bytearray(b"def")
+        pair.write(buffer)
+        buffer[:] = b"***"  # Overwrite our copy of the data
         pair.flush()
         self.assertEqual(w._write_stack, [b"abc", b"def"])
 
@@ -3366,10 +3527,8 @@ class MiscIOTest(unittest.TestCase):
         # When using closefd=False, there's no warning
         r, w = os.pipe()
         fds += r, w
-        with warnings.catch_warnings(record=True) as recorded:
+        with support.check_no_resource_warning(self):
             open(r, *args, closefd=False, **kwargs)
-            support.gc_collect()
-        self.assertEqual(recorded, [])
 
     def test_warn_on_dealloc_fd(self):
         self._check_warn_on_dealloc_fd("rb", buffering=0)
index 39eb9a1..be62fad 100644 (file)
@@ -587,8 +587,16 @@ class ComparisonTests(unittest.TestCase):
     v4_objects = v4_addresses + [v4net]
     v6_addresses = [v6addr, v6intf]
     v6_objects = v6_addresses + [v6net]
+
     objects = v4_objects + v6_objects
 
+    v4addr2 = ipaddress.IPv4Address(2)
+    v4net2 = ipaddress.IPv4Network(2)
+    v4intf2 = ipaddress.IPv4Interface(2)
+    v6addr2 = ipaddress.IPv6Address(2)
+    v6net2 = ipaddress.IPv6Network(2)
+    v6intf2 = ipaddress.IPv6Interface(2)
+
     def test_foreign_type_equality(self):
         # __eq__ should never raise TypeError directly
         other = object()
@@ -607,6 +615,31 @@ class ComparisonTests(unittest.TestCase):
                     continue
                 self.assertNotEqual(lhs, rhs)
 
+    def test_same_type_equality(self):
+        for obj in self.objects:
+            self.assertEqual(obj, obj)
+            self.assertLessEqual(obj, obj)
+            self.assertGreaterEqual(obj, obj)
+
+    def test_same_type_ordering(self):
+        for lhs, rhs in (
+            (self.v4addr, self.v4addr2),
+            (self.v4net, self.v4net2),
+            (self.v4intf, self.v4intf2),
+            (self.v6addr, self.v6addr2),
+            (self.v6net, self.v6net2),
+            (self.v6intf, self.v6intf2),
+        ):
+            self.assertNotEqual(lhs, rhs)
+            self.assertLess(lhs, rhs)
+            self.assertLessEqual(lhs, rhs)
+            self.assertGreater(rhs, lhs)
+            self.assertGreaterEqual(rhs, lhs)
+            self.assertFalse(lhs > rhs)
+            self.assertFalse(rhs < lhs)
+            self.assertFalse(lhs >= rhs)
+            self.assertFalse(rhs <= lhs)
+
     def test_containment(self):
         for obj in self.v4_addresses:
             self.assertIn(obj, self.v4net)
@@ -1066,6 +1099,26 @@ class IpaddrUnitTest(unittest.TestCase):
              '2001:658:22a:cafe:8000::/66',
              '2001:658:22a:cafe:c000::/66'])
 
+    def testGetSubnets3(self):
+        subnets = [str(x) for x in self.ipv4_network.subnets(8)]
+        self.assertEqual(subnets[:3],
+            ['1.2.3.0/32', '1.2.3.1/32', '1.2.3.2/32'])
+        self.assertEqual(subnets[-3:],
+            ['1.2.3.253/32', '1.2.3.254/32', '1.2.3.255/32'])
+        self.assertEqual(len(subnets), 256)
+
+        ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/120')
+        subnets = [str(x) for x in ipv6_network.subnets(8)]
+        self.assertEqual(subnets[:3],
+            ['2001:658:22a:cafe::/128',
+             '2001:658:22a:cafe::1/128',
+             '2001:658:22a:cafe::2/128'])
+        self.assertEqual(subnets[-3:],
+            ['2001:658:22a:cafe::fd/128',
+             '2001:658:22a:cafe::fe/128',
+             '2001:658:22a:cafe::ff/128'])
+        self.assertEqual(len(subnets), 256)
+
     def testSubnetFailsForLargeCidrDiff(self):
         self.assertRaises(ValueError, list,
                           self.ipv4_interface.network.subnets(9))
@@ -1573,6 +1626,9 @@ class IpaddrUnitTest(unittest.TestCase):
         self.assertEqual(False,
                          ipaddress.ip_address('169.255.100.200').is_link_local)
 
+        self.assertTrue(ipaddress.ip_address('192.0.7.1').is_global)
+        self.assertFalse(ipaddress.ip_address('203.0.113.1').is_global)
+
         self.assertEqual(True,
                           ipaddress.ip_address('127.100.200.254').is_loopback)
         self.assertEqual(True, ipaddress.ip_address('127.42.0.0').is_loopback)
@@ -1670,6 +1726,7 @@ class IpaddrUnitTest(unittest.TestCase):
         addr3 = ipaddress.ip_network('10.2.1.0/24')
         addr4 = ipaddress.ip_address('10.1.1.0')
         addr5 = ipaddress.ip_network('2001:db8::0/32')
+        addr6 = ipaddress.ip_network('10.1.1.5/32')
         self.assertEqual(sorted(list(addr1.address_exclude(addr2))),
                          [ipaddress.ip_network('10.1.1.64/26'),
                           ipaddress.ip_network('10.1.1.128/25')])
@@ -1677,6 +1734,15 @@ class IpaddrUnitTest(unittest.TestCase):
         self.assertRaises(TypeError, list, addr1.address_exclude(addr4))
         self.assertRaises(TypeError, list, addr1.address_exclude(addr5))
         self.assertEqual(list(addr1.address_exclude(addr1)), [])
+        self.assertEqual(sorted(list(addr1.address_exclude(addr6))),
+                         [ipaddress.ip_network('10.1.1.0/30'),
+                          ipaddress.ip_network('10.1.1.4/32'),
+                          ipaddress.ip_network('10.1.1.6/31'),
+                          ipaddress.ip_network('10.1.1.8/29'),
+                          ipaddress.ip_network('10.1.1.16/28'),
+                          ipaddress.ip_network('10.1.1.32/27'),
+                          ipaddress.ip_network('10.1.1.64/26'),
+                          ipaddress.ip_network('10.1.1.128/25')])
 
     def testHash(self):
         self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')),
@@ -1740,7 +1806,6 @@ class IpaddrUnitTest(unittest.TestCase):
             '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128',
             '2001:0:0:4:5:6:7:8': '2001::4:5:6:7:8/128',
             '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
-            '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
             '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128',
             '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128',
             '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128',
index abc408f..a91670b 100644 (file)
@@ -3,6 +3,7 @@
 import sys
 import unittest
 from test.support import run_unittest, TESTFN, unlink, cpython_only
+from test.support import check_free_after_iterating
 import pickle
 import collections.abc
 
@@ -153,6 +154,53 @@ class TestCase(unittest.TestCase):
     def test_seq_class_iter(self):
         self.check_iterator(iter(SequenceClass(10)), list(range(10)))
 
+    def test_mutating_seq_class_iter_pickle(self):
+        orig = SequenceClass(5)
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            # initial iterator
+            itorig = iter(orig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, seq = pickle.loads(d)
+            seq.n = 7
+            self.assertIs(type(it), type(itorig))
+            self.assertEqual(list(it), list(range(7)))
+
+            # running iterator
+            next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, seq = pickle.loads(d)
+            seq.n = 7
+            self.assertIs(type(it), type(itorig))
+            self.assertEqual(list(it), list(range(1, 7)))
+
+            # empty iterator
+            for i in range(1, 5):
+                next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, seq = pickle.loads(d)
+            seq.n = 7
+            self.assertIs(type(it), type(itorig))
+            self.assertEqual(list(it), list(range(5, 7)))
+
+            # exhausted iterator
+            self.assertRaises(StopIteration, next, itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, seq = pickle.loads(d)
+            seq.n = 7
+            self.assertTrue(isinstance(it, collections.abc.Iterator))
+            self.assertEqual(list(it), [])
+
+    def test_mutating_seq_class_exhausted_iter(self):
+        a = SequenceClass(5)
+        exhit = iter(a)
+        empit = iter(a)
+        for x in exhit:  # exhaust the iterator
+            next(empit)  # not exhausted
+        a.n = 7
+        self.assertEqual(list(exhit), [])
+        self.assertEqual(list(empit), [5, 6])
+        self.assertEqual(list(a), [0, 1, 2, 3, 4, 5, 6])
+
     # Test a new_style class with __iter__ but no next() method
     def test_new_style_iter_class(self):
         class IterClass(object):
@@ -944,6 +992,9 @@ class TestCase(unittest.TestCase):
         self.assertEqual(next(it), 0)
         self.assertEqual(next(it), 1)
 
+    def test_free_after_iterating(self):
+        check_free_after_iterating(self, iter, SequenceClass, (0,))
+
 
 def test_main():
     run_unittest(TestCase)
index 5b3ba7e..f940852 100644 (file)
@@ -1398,6 +1398,16 @@ class TestExamples(unittest.TestCase):
         self.assertEqual(list(copy.deepcopy(it)), accumulated[1:])
         self.assertEqual(list(copy.copy(it)), accumulated[1:])
 
+    def test_accumulate_reducible_none(self):
+        # Issue #25718: total is None
+        it = accumulate([None, None, None], operator.is_)
+        self.assertEqual(next(it), None)
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            it_copy = pickle.loads(pickle.dumps(it, proto))
+            self.assertEqual(list(it_copy), [True, False])
+        self.assertEqual(list(copy.deepcopy(it)), [True, False])
+        self.assertEqual(list(copy.copy(it)), [True, False])
+
     def test_chain(self):
         self.assertEqual(''.join(chain('ABC', 'DEF')), 'ABCDEF')
 
@@ -2004,6 +2014,11 @@ Samuele
 ...     "Returns the nth item or a default value"
 ...     return next(islice(iterable, n, None), default)
 
+>>> def all_equal(iterable):
+...     "Returns True if all the elements are equal to each other"
+...     g = groupby(iterable)
+...     return next(g, True) and not next(g, False)
+
 >>> def quantify(iterable, pred=bool):
 ...     "Count how many times the predicate is true"
 ...     return sum(map(pred, iterable))
@@ -2117,6 +2132,9 @@ perform as purported.
 >>> nth('abcde', 9) is None
 True
 
+>>> [all_equal(s) for s in ('', 'A', 'AAAA', 'AAAB', 'AAABA')]
+[True, True, True, False, False]
+
 >>> quantify(range(99), lambda x: x%2==0)
 50
 
index 21ef738..47e2edd 100644 (file)
@@ -139,7 +139,7 @@ class LineCacheTests(unittest.TestCase):
         self.assertEqual(
             True, linecache.lazycache(NONEXISTENT_FILENAME, globals()))
         self.assertEqual(1, len(linecache.cache[NONEXISTENT_FILENAME]))
-        # Note here that we're looking up a non existant filename with no
+        # Note here that we're looking up a nonexistent filename with no
         # globals: this would error if the lazy value wasn't resolved.
         self.assertEqual(lines, linecache.getlines(NONEXISTENT_FILENAME))
 
index ae1be6e..8f82ab5 100644 (file)
@@ -1,6 +1,7 @@
 import sys
 from test import support, list_tests
 import pickle
+import unittest
 
 class ListTest(list_tests.CommonTest):
     type2test = list
@@ -71,34 +72,76 @@ class ListTest(list_tests.CommonTest):
         check(1000000)
 
     def test_iterator_pickle(self):
-        # Userlist iterators don't support pickling yet since
-        # they are based on generators.
-        data = self.type2test([4, 5, 6, 7])
+        orig = self.type2test([4, 5, 6, 7])
+        data = [10, 11, 12, 13, 14, 15]
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
-            it = itorg = iter(data)
-            d = pickle.dumps(it, proto)
-            it = pickle.loads(d)
-            self.assertEqual(type(itorg), type(it))
-            self.assertEqual(self.type2test(it), self.type2test(data))
-
-            it = pickle.loads(d)
-            next(it)
-            d = pickle.dumps(it, proto)
-            self.assertEqual(self.type2test(it), self.type2test(data)[1:])
+            # initial iterator
+            itorig = iter(orig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data)
+
+            # running iterator
+            next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data[1:])
+
+            # empty iterator
+            for i in range(1, len(orig)):
+                next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data[len(orig):])
+
+            # exhausted iterator
+            self.assertRaises(StopIteration, next, itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a[:] = data
+            self.assertEqual(list(it), [])
 
     def test_reversed_pickle(self):
-        data = self.type2test([4, 5, 6, 7])
+        orig = self.type2test([4, 5, 6, 7])
+        data = [10, 11, 12, 13, 14, 15]
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
-            it = itorg = reversed(data)
-            d = pickle.dumps(it, proto)
-            it = pickle.loads(d)
-            self.assertEqual(type(itorg), type(it))
-            self.assertEqual(self.type2test(it), self.type2test(reversed(data)))
-
-            it = pickle.loads(d)
-            next(it)
-            d = pickle.dumps(it, proto)
-            self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:])
+            # initial iterator
+            itorig = reversed(orig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data[len(orig)-1::-1])
+
+            # running iterator
+            next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), data[len(orig)-2::-1])
+
+            # empty iterator
+            for i in range(1, len(orig)):
+                next(itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a[:] = data
+            self.assertEqual(type(it), type(itorig))
+            self.assertEqual(list(it), [])
+
+            # exhausted iterator
+            self.assertRaises(StopIteration, next, itorig)
+            d = pickle.dumps((itorig, orig), proto)
+            it, a = pickle.loads(d)
+            a[:] = data
+            self.assertEqual(list(it), [])
 
     def test_no_comdat_folding(self):
         # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding
index 95575bf..84fd8b5 100644 (file)
@@ -1672,7 +1672,8 @@ class HTTPHandlerTest(BaseTest):
             secure_client = secure and sslctx
             self.h_hdlr = logging.handlers.HTTPHandler(host, '/frob',
                                                        secure=secure_client,
-                                                       context=context)
+                                                       context=context,
+                                                       credentials=('foo', 'bar'))
             self.log_data = None
             root_logger.addHandler(self.h_hdlr)
 
index 62e69a9..b2d008b 100644 (file)
@@ -1203,6 +1203,23 @@ class LongTest(unittest.TestCase):
         self.assertRaises(TypeError, myint.from_bytes, 0, 'big')
         self.assertRaises(TypeError, int.from_bytes, 0, 'big', True)
 
+        class myint2(int):
+            def __new__(cls, value):
+                return int.__new__(cls, value + 1)
+
+        i = myint2.from_bytes(b'\x01', 'big')
+        self.assertIs(type(i), myint2)
+        self.assertEqual(i, 2)
+
+        class myint3(int):
+            def __init__(self, value):
+                self.foo = 'bar'
+
+        i = myint3.from_bytes(b'\x01', 'big')
+        self.assertIs(type(i), myint3)
+        self.assertEqual(i, 1)
+        self.assertEqual(getattr(i, 'foo', 'none'), 'bar')
+
     def test_access_to_nonexistent_digit_0(self):
         # http://bugs.python.org/issue14630: A bug in _PyLong_Copy meant that
         # ob_digit[0] was being incorrectly accessed for instances of a
index 2d39099..6c698e2 100644 (file)
@@ -1211,7 +1211,7 @@ class OpenTestCase(unittest.TestCase):
                 self.assertEqual(f.read(), uncompressed)
 
     def test_encoding_error_handler(self):
-        # Test wih non-default encoding error handler.
+        # Test with non-default encoding error handler.
         with BytesIO(lzma.compress(b"foo\xffbar")) as bio:
             with lzma.open(bio, "rt", encoding="ascii", errors="ignore") as f:
                 self.assertEqual(f.read(), "foobar")
index 44d66c3..55b693e 100644 (file)
@@ -376,7 +376,7 @@ class MemoryTestMixin:
 
         # Pickle expects the class to be on the module level. Here we use a
         # little hack to allow the PickleTestMemIO class to derive from
-        # self.ioclass without having to define all combinations explictly on
+        # self.ioclass without having to define all combinations explicitly on
         # the module-level.
         import __main__
         PickleTestMemIO.__module__ = '__main__'
@@ -399,7 +399,16 @@ class MemoryTestMixin:
         del __main__.PickleTestMemIO
 
 
-class BytesIOMixin:
+class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
+    # Test _pyio.BytesIO; class also inherited for testing C implementation
+
+    UnsupportedOperation = pyio.UnsupportedOperation
+
+    @staticmethod
+    def buftype(s):
+        return s.encode("ascii")
+    ioclass = pyio.BytesIO
+    EOF = b""
 
     def test_getbuffer(self):
         memio = self.ioclass(b"1234567890")
@@ -426,18 +435,6 @@ class BytesIOMixin:
         memio.close()
         self.assertRaises(ValueError, memio.getbuffer)
 
-
-class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin,
-                    BytesIOMixin, unittest.TestCase):
-
-    UnsupportedOperation = pyio.UnsupportedOperation
-
-    @staticmethod
-    def buftype(s):
-        return s.encode("ascii")
-    ioclass = pyio.BytesIO
-    EOF = b""
-
     def test_read1(self):
         buf = self.buftype("1234567890")
         memio = self.ioclass(buf)
index d2bab38..ddd5b9a 100644 (file)
@@ -11,6 +11,8 @@ import gc
 import weakref
 import array
 import io
+import copy
+import pickle
 
 
 class AbstractMemoryTests:
@@ -519,6 +521,17 @@ class OtherTest(unittest.TestCase):
         m2 = m1[::-1]
         self.assertEqual(m2.hex(), '30' * 200000)
 
+    def test_copy(self):
+        m = memoryview(b'abc')
+        with self.assertRaises(TypeError):
+            copy.copy(m)
+
+    def test_pickle(self):
+        m = memoryview(b'abc')
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            with self.assertRaises(TypeError):
+                pickle.dumps(m, proto)
+
 
 if __name__ == "__main__":
     unittest.main()
index e8ca497..ee8c041 100644 (file)
@@ -1,5 +1,6 @@
 # test for xml.dom.minidom
 
+import copy
 import pickle
 from test.support import findfile
 import unittest
@@ -11,6 +12,13 @@ from xml.dom.minidom import getDOMImplementation
 
 
 tstfile = findfile("test.xml", subdir="xmltestdata")
+sample = ("<?xml version='1.0' encoding='us-ascii'?>\n"
+          "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
+          " 'http://xml.python.org/system' [\n"
+          "  <!ELEMENT e EMPTY>\n"
+          "  <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
+          "]><doc attr='value'> text\n"
+          "<?pi sample?> <!-- comment --> <e/> </doc>")
 
 # The tests of DocumentType importing use these helpers to construct
 # the documents to work with, since not all DOM builders actually
@@ -1481,52 +1489,54 @@ class MinidomTest(unittest.TestCase):
         self.confirm(e.isSameNode(doc.getElementById("w"))
                 and a2.isId)
 
+    def assert_recursive_equal(self, doc, doc2):
+        stack = [(doc, doc2)]
+        while stack:
+            n1, n2 = stack.pop()
+            self.assertEqual(n1.nodeType, n2.nodeType)
+            self.assertEqual(len(n1.childNodes), len(n2.childNodes))
+            self.assertEqual(n1.nodeName, n2.nodeName)
+            self.assertFalse(n1.isSameNode(n2))
+            self.assertFalse(n2.isSameNode(n1))
+            if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
+                len(n1.entities)
+                len(n2.entities)
+                len(n1.notations)
+                len(n2.notations)
+                self.assertEqual(len(n1.entities), len(n2.entities))
+                self.assertEqual(len(n1.notations), len(n2.notations))
+                for i in range(len(n1.notations)):
+                    # XXX this loop body doesn't seem to be executed?
+                    no1 = n1.notations.item(i)
+                    no2 = n1.notations.item(i)
+                    self.assertEqual(no1.name, no2.name)
+                    self.assertEqual(no1.publicId, no2.publicId)
+                    self.assertEqual(no1.systemId, no2.systemId)
+                    stack.append((no1, no2))
+                for i in range(len(n1.entities)):
+                    e1 = n1.entities.item(i)
+                    e2 = n2.entities.item(i)
+                    self.assertEqual(e1.notationName, e2.notationName)
+                    self.assertEqual(e1.publicId, e2.publicId)
+                    self.assertEqual(e1.systemId, e2.systemId)
+                    stack.append((e1, e2))
+            if n1.nodeType != Node.DOCUMENT_NODE:
+                self.assertTrue(n1.ownerDocument.isSameNode(doc))
+                self.assertTrue(n2.ownerDocument.isSameNode(doc2))
+            for i in range(len(n1.childNodes)):
+                stack.append((n1.childNodes[i], n2.childNodes[i]))
+
     def testPickledDocument(self):
-        doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
-                    "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
-                    " 'http://xml.python.org/system' [\n"
-                    "  <!ELEMENT e EMPTY>\n"
-                    "  <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
-                    "]><doc attr='value'> text\n"
-                    "<?pi sample?> <!-- comment --> <e/> </doc>")
+        doc = parseString(sample)
         for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
             s = pickle.dumps(doc, proto)
             doc2 = pickle.loads(s)
-            stack = [(doc, doc2)]
-            while stack:
-                n1, n2 = stack.pop()
-                self.confirm(n1.nodeType == n2.nodeType
-                        and len(n1.childNodes) == len(n2.childNodes)
-                        and n1.nodeName == n2.nodeName
-                        and not n1.isSameNode(n2)
-                        and not n2.isSameNode(n1))
-                if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
-                    len(n1.entities)
-                    len(n2.entities)
-                    len(n1.notations)
-                    len(n2.notations)
-                    self.confirm(len(n1.entities) == len(n2.entities)
-                            and len(n1.notations) == len(n2.notations))
-                    for i in range(len(n1.notations)):
-                        # XXX this loop body doesn't seem to be executed?
-                        no1 = n1.notations.item(i)
-                        no2 = n1.notations.item(i)
-                        self.confirm(no1.name == no2.name
-                                and no1.publicId == no2.publicId
-                                and no1.systemId == no2.systemId)
-                        stack.append((no1, no2))
-                    for i in range(len(n1.entities)):
-                        e1 = n1.entities.item(i)
-                        e2 = n2.entities.item(i)
-                        self.confirm(e1.notationName == e2.notationName
-                                and e1.publicId == e2.publicId
-                                and e1.systemId == e2.systemId)
-                        stack.append((e1, e2))
-                if n1.nodeType != Node.DOCUMENT_NODE:
-                    self.confirm(n1.ownerDocument.isSameNode(doc)
-                            and n2.ownerDocument.isSameNode(doc2))
-                for i in range(len(n1.childNodes)):
-                    stack.append((n1.childNodes[i], n2.childNodes[i]))
+            self.assert_recursive_equal(doc, doc2)
+
+    def testDeepcopiedDocument(self):
+        doc = parseString(sample)
+        doc2 = copy.deepcopy(doc)
+        self.assert_recursive_equal(doc, doc2)
 
     def testSerializeCommentNodeWithDoubleHyphen(self):
         doc = create_doc_without_doctype()
index 0f25742..b365d84 100644 (file)
@@ -730,7 +730,7 @@ class LargeMmapTests(unittest.TestCase):
             f.seek(num_zeroes)
             f.write(tail)
             f.flush()
-        except (OSError, OverflowError):
+        except (OSError, OverflowError, ValueError):
             try:
                 f.close()
             except (OSError, OverflowError):
index 48ab0b4..ea6e897 100644 (file)
@@ -30,7 +30,7 @@ class ModuleTests(unittest.TestCase):
             pass
         self.assertEqual(foo.__doc__, ModuleType.__doc__)
 
-    def test_unintialized_missing_getattr(self):
+    def test_uninitialized_missing_getattr(self):
         # Issue 8297
         # test the text in the AttributeError of an uninitialized module
         foo = ModuleType.__new__(ModuleType)
@@ -227,7 +227,7 @@ a = A(destroyed)"""
             b"len = len",
             b"shutil.rmtree = rmtree"})
 
-    def test_descriptor_errors_propogate(self):
+    def test_descriptor_errors_propagate(self):
         class Descr:
             def __get__(self, o, t):
                 raise RuntimeError
index 4c49e9a..e4df2a9 100644 (file)
@@ -319,6 +319,19 @@ class ModuleFinderTest(unittest.TestCase):
         expected = "co_filename %r changed to %r" % (old_path, new_path)
         self.assertIn(expected, output)
 
+    def test_extended_opargs(self):
+        extended_opargs_test = [
+            "a",
+            ["a", "b"],
+            [], [],
+            """\
+a.py
+                                %r
+                                import b
+b.py
+""" % list(range(2**16))]  # 2**16 constants
+        self._do_test(extended_opargs_test)
+
 
 if __name__ == "__main__":
     unittest.main()
index 2929f98..8d7a213 100644 (file)
@@ -67,7 +67,7 @@ class Test_MultibyteCodec(unittest.TestCase):
                           _multibytecodec.MultibyteStreamWriter, None)
 
     def test_decode_unicode(self):
-        # Trying to decode an unicode string should raise a TypeError
+        # Trying to decode a unicode string should raise a TypeError
         for enc in ALL_CJKENCODINGS:
             self.assertRaises(TypeError, codecs.getdecoder(enc), "")
 
@@ -160,7 +160,7 @@ class Test_IncrementalDecoder(unittest.TestCase):
         self.assertEqual(decoder.decode(b'B@$'), '\u4e16')
 
     def test_decode_unicode(self):
-        # Trying to decode an unicode string should raise a TypeError
+        # Trying to decode a unicode string should raise a TypeError
         for enc in ALL_CJKENCODINGS:
             decoder = codecs.getincrementaldecoder(enc)()
             self.assertRaises(TypeError, decoder.decode, "")
index ae3618f..994532b 100644 (file)
@@ -5,6 +5,7 @@ import textwrap
 import unittest
 import functools
 import contextlib
+import os.path
 from test import support
 from nntplib import NNTP, GroupInfo
 import nntplib
@@ -13,8 +14,13 @@ try:
     import ssl
 except ImportError:
     ssl = None
+try:
+    import threading
+except ImportError:
+    threading = None
 
 TIMEOUT = 30
+certfile = os.path.join(os.path.dirname(__file__), 'keycert3.pem')
 
 # TODO:
 # - test the `file` arg to more commands
@@ -202,24 +208,6 @@ class NetworkedNNTPTestsMixin:
         resp, caps = self.server.capabilities()
         _check_caps(caps)
 
-    @unittest.skipUnless(ssl, 'requires SSL support')
-    def test_starttls(self):
-        file = self.server.file
-        sock = self.server.sock
-        try:
-            self.server.starttls()
-        except nntplib.NNTPPermanentError:
-            self.skipTest("STARTTLS not supported by server.")
-        else:
-            # Check that the socket and internal pseudo-file really were
-            # changed.
-            self.assertNotEqual(file, self.server.file)
-            self.assertNotEqual(sock, self.server.sock)
-            # Check that the new socket really is an SSL one
-            self.assertIsInstance(self.server.sock, ssl.SSLSocket)
-            # Check that trying starttls when it's already active fails.
-            self.assertRaises(ValueError, self.server.starttls)
-
     def test_zlogin(self):
         # This test must be the penultimate because further commands will be
         # refused.
@@ -621,7 +609,7 @@ class NNTPv1Handler:
                     "\t\t6683\t16"
                     "\t"
                     "\n"
-                # An UTF-8 overview line from fr.comp.lang.python
+                # A UTF-8 overview line from fr.comp.lang.python
                 "59\tRe: Message d'erreur incompréhensible (par moi)"
                     "\tEric Brunel <eric.brunel@pragmadev.nospam.com>"
                     "\tWed, 15 Sep 2010 18:09:15 +0200"
@@ -1520,6 +1508,64 @@ class MockSslTests(MockSocketTests):
     def nntp_class(*pos, **kw):
         return nntplib.NNTP_SSL(*pos, ssl_context=bypass_context, **kw)
 
+@unittest.skipUnless(threading, 'requires multithreading')
+class LocalServerTests(unittest.TestCase):
+    def setUp(self):
+        sock = socket.socket()
+        port = support.bind_port(sock)
+        sock.listen()
+        self.background = threading.Thread(
+            target=self.run_server, args=(sock,))
+        self.background.start()
+        self.addCleanup(self.background.join)
+
+        self.nntp = NNTP(support.HOST, port, usenetrc=False).__enter__()
+        self.addCleanup(self.nntp.__exit__, None, None, None)
+
+    def run_server(self, sock):
+        # Could be generalized to handle more commands in separate methods
+        with sock:
+            [client, _] = sock.accept()
+        with contextlib.ExitStack() as cleanup:
+            cleanup.enter_context(client)
+            reader = cleanup.enter_context(client.makefile('rb'))
+            client.sendall(b'200 Server ready\r\n')
+            while True:
+                cmd = reader.readline()
+                if cmd == b'CAPABILITIES\r\n':
+                    client.sendall(
+                        b'101 Capability list:\r\n'
+                        b'VERSION 2\r\n'
+                        b'STARTTLS\r\n'
+                        b'.\r\n'
+                    )
+                elif cmd == b'STARTTLS\r\n':
+                    reader.close()
+                    client.sendall(b'382 Begin TLS negotiation now\r\n')
+                    client = ssl.wrap_socket(
+                        client, server_side=True, certfile=certfile)
+                    cleanup.enter_context(client)
+                    reader = cleanup.enter_context(client.makefile('rb'))
+                elif cmd == b'QUIT\r\n':
+                    client.sendall(b'205 Bye!\r\n')
+                    break
+                else:
+                    raise ValueError('Unexpected command {!r}'.format(cmd))
+
+    @unittest.skipUnless(ssl, 'requires SSL support')
+    def test_starttls(self):
+        file = self.nntp.file
+        sock = self.nntp.sock
+        self.nntp.starttls()
+        # Check that the socket and internal pseudo-file really were
+        # changed.
+        self.assertNotEqual(file, self.nntp.file)
+        self.assertNotEqual(sock, self.nntp.sock)
+        # Check that the new socket really is an SSL one
+        self.assertIsInstance(self.nntp.sock, ssl.SSLSocket)
+        # Check that trying starttls when it's already active fails.
+        self.assertRaises(ValueError, self.nntp.starttls)
+
 
 if __name__ == "__main__":
     unittest.main()
index da9c8ef..b5ba976 100644 (file)
@@ -318,6 +318,9 @@ class OperatorTestCase:
         a.name = 'arthur'
         f = operator.attrgetter('name')
         self.assertEqual(f(a), 'arthur')
+        self.assertRaises(TypeError, f)
+        self.assertRaises(TypeError, f, a, 'dent')
+        self.assertRaises(TypeError, f, a, surname='dent')
         f = operator.attrgetter('rank')
         self.assertRaises(AttributeError, f, a)
         self.assertRaises(TypeError, operator.attrgetter, 2)
@@ -365,6 +368,9 @@ class OperatorTestCase:
         a = 'ABCDE'
         f = operator.itemgetter(2)
         self.assertEqual(f(a), 'C')
+        self.assertRaises(TypeError, f)
+        self.assertRaises(TypeError, f, a, 3)
+        self.assertRaises(TypeError, f, a, size=3)
         f = operator.itemgetter(10)
         self.assertRaises(IndexError, f, a)
 
@@ -411,6 +417,9 @@ class OperatorTestCase:
         self.assertRaises(IndexError, f, a)
         f = operator.methodcaller('foo', 1, 2)
         self.assertEqual(f(a), 3)
+        self.assertRaises(TypeError, f)
+        self.assertRaises(TypeError, f, a, 3)
+        self.assertRaises(TypeError, f, a, spam=3)
         f = operator.methodcaller('bar')
         self.assertEqual(f(a), 42)
         self.assertRaises(TypeError, f, a, a)
diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py
new file mode 100644 (file)
index 0000000..901d4b2
--- /dev/null
@@ -0,0 +1,734 @@
+import contextlib
+import copy
+import gc
+import pickle
+from random import randrange, shuffle
+import struct
+import sys
+import unittest
+import weakref
+from collections.abc import MutableMapping
+from test import mapping_tests, support
+
+
+py_coll = support.import_fresh_module('collections', blocked=['_collections'])
+c_coll = support.import_fresh_module('collections', fresh=['_collections'])
+
+
+@contextlib.contextmanager
+def replaced_module(name, replacement):
+    original_module = sys.modules[name]
+    sys.modules[name] = replacement
+    try:
+        yield
+    finally:
+        sys.modules[name] = original_module
+
+
+class OrderedDictTests:
+
+    def test_init(self):
+        OrderedDict = self.OrderedDict
+        with self.assertRaises(TypeError):
+            OrderedDict([('a', 1), ('b', 2)], None)                                 # too many args
+        pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
+        self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs)           # dict input
+        self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs)         # kwds input
+        self.assertEqual(list(OrderedDict(pairs).items()), pairs)                   # pairs input
+        self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)],
+                                          c=3, e=5).items()), pairs)                # mixed input
+
+        # make sure no positional args conflict with possible kwdargs
+        self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)])
+        self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)])
+        self.assertRaises(TypeError, OrderedDict, 42)
+        self.assertRaises(TypeError, OrderedDict, (), ())
+        self.assertRaises(TypeError, OrderedDict.__init__)
+
+        # Make sure that direct calls to __init__ do not clear previous contents
+        d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
+        d.__init__([('e', 5), ('f', 6)], g=7, d=4)
+        self.assertEqual(list(d.items()),
+            [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
+
+    def test_update(self):
+        OrderedDict = self.OrderedDict
+        with self.assertRaises(TypeError):
+            OrderedDict().update([('a', 1), ('b', 2)], None)                        # too many args
+        pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
+        od = OrderedDict()
+        od.update(dict(pairs))
+        self.assertEqual(sorted(od.items()), pairs)                                 # dict input
+        od = OrderedDict()
+        od.update(**dict(pairs))
+        self.assertEqual(sorted(od.items()), pairs)                                 # kwds input
+        od = OrderedDict()
+        od.update(pairs)
+        self.assertEqual(list(od.items()), pairs)                                   # pairs input
+        od = OrderedDict()
+        od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5)
+        self.assertEqual(list(od.items()), pairs)                                   # mixed input
+
+        # Issue 9137: Named argument called 'other' or 'self'
+        # shouldn't be treated specially.
+        od = OrderedDict()
+        od.update(self=23)
+        self.assertEqual(list(od.items()), [('self', 23)])
+        od = OrderedDict()
+        od.update(other={})
+        self.assertEqual(list(od.items()), [('other', {})])
+        od = OrderedDict()
+        od.update(red=5, blue=6, other=7, self=8)
+        self.assertEqual(sorted(list(od.items())),
+                         [('blue', 6), ('other', 7), ('red', 5), ('self', 8)])
+
+        # Make sure that direct calls to update do not clear previous contents
+        # add that updates items are not moved to the end
+        d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
+        d.update([('e', 5), ('f', 6)], g=7, d=4)
+        self.assertEqual(list(d.items()),
+            [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
+
+        self.assertRaises(TypeError, OrderedDict().update, 42)
+        self.assertRaises(TypeError, OrderedDict().update, (), ())
+        self.assertRaises(TypeError, OrderedDict.update)
+
+        self.assertRaises(TypeError, OrderedDict().update, 42)
+        self.assertRaises(TypeError, OrderedDict().update, (), ())
+        self.assertRaises(TypeError, OrderedDict.update)
+
+    def test_fromkeys(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict.fromkeys('abc')
+        self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
+        od = OrderedDict.fromkeys('abc', value=None)
+        self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
+        od = OrderedDict.fromkeys('abc', value=0)
+        self.assertEqual(list(od.items()), [(c, 0) for c in 'abc'])
+
+    def test_abc(self):
+        OrderedDict = self.OrderedDict
+        self.assertIsInstance(OrderedDict(), MutableMapping)
+        self.assertTrue(issubclass(OrderedDict, MutableMapping))
+
+    def test_clear(self):
+        OrderedDict = self.OrderedDict
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        shuffle(pairs)
+        od = OrderedDict(pairs)
+        self.assertEqual(len(od), len(pairs))
+        od.clear()
+        self.assertEqual(len(od), 0)
+
+    def test_delitem(self):
+        OrderedDict = self.OrderedDict
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        od = OrderedDict(pairs)
+        del od['a']
+        self.assertNotIn('a', od)
+        with self.assertRaises(KeyError):
+            del od['a']
+        self.assertEqual(list(od.items()), pairs[:2] + pairs[3:])
+
+    def test_setitem(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)])
+        od['c'] = 10           # existing element
+        od['f'] = 20           # new element
+        self.assertEqual(list(od.items()),
+                         [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)])
+
+    def test_iterators(self):
+        OrderedDict = self.OrderedDict
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        shuffle(pairs)
+        od = OrderedDict(pairs)
+        self.assertEqual(list(od), [t[0] for t in pairs])
+        self.assertEqual(list(od.keys()), [t[0] for t in pairs])
+        self.assertEqual(list(od.values()), [t[1] for t in pairs])
+        self.assertEqual(list(od.items()), pairs)
+        self.assertEqual(list(reversed(od)),
+                         [t[0] for t in reversed(pairs)])
+        self.assertEqual(list(reversed(od.keys())),
+                         [t[0] for t in reversed(pairs)])
+        self.assertEqual(list(reversed(od.values())),
+                         [t[1] for t in reversed(pairs)])
+        self.assertEqual(list(reversed(od.items())), list(reversed(pairs)))
+
+    def test_detect_deletion_during_iteration(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict.fromkeys('abc')
+        it = iter(od)
+        key = next(it)
+        del od[key]
+        with self.assertRaises(Exception):
+            # Note, the exact exception raised is not guaranteed
+            # The only guarantee that the next() will not succeed
+            next(it)
+
+    def test_sorted_iterators(self):
+        OrderedDict = self.OrderedDict
+        with self.assertRaises(TypeError):
+            OrderedDict([('a', 1), ('b', 2)], None)
+        pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
+        od = OrderedDict(pairs)
+        self.assertEqual(sorted(od), [t[0] for t in pairs])
+        self.assertEqual(sorted(od.keys()), [t[0] for t in pairs])
+        self.assertEqual(sorted(od.values()), [t[1] for t in pairs])
+        self.assertEqual(sorted(od.items()), pairs)
+        self.assertEqual(sorted(reversed(od)),
+                         sorted([t[0] for t in reversed(pairs)]))
+
+    def test_iterators_empty(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        empty = []
+        self.assertEqual(list(od), empty)
+        self.assertEqual(list(od.keys()), empty)
+        self.assertEqual(list(od.values()), empty)
+        self.assertEqual(list(od.items()), empty)
+        self.assertEqual(list(reversed(od)), empty)
+        self.assertEqual(list(reversed(od.keys())), empty)
+        self.assertEqual(list(reversed(od.values())), empty)
+        self.assertEqual(list(reversed(od.items())), empty)
+
+    def test_popitem(self):
+        OrderedDict = self.OrderedDict
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        shuffle(pairs)
+        od = OrderedDict(pairs)
+        while pairs:
+            self.assertEqual(od.popitem(), pairs.pop())
+        with self.assertRaises(KeyError):
+            od.popitem()
+        self.assertEqual(len(od), 0)
+
+    def test_popitem_last(self):
+        OrderedDict = self.OrderedDict
+        pairs = [(i, i) for i in range(30)]
+
+        obj = OrderedDict(pairs)
+        for i in range(8):
+            obj.popitem(True)
+        obj.popitem(True)
+        obj.popitem(last=True)
+        self.assertEqual(len(obj), 20)
+
+    def test_pop(self):
+        OrderedDict = self.OrderedDict
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        shuffle(pairs)
+        od = OrderedDict(pairs)
+        shuffle(pairs)
+        while pairs:
+            k, v = pairs.pop()
+            self.assertEqual(od.pop(k), v)
+        with self.assertRaises(KeyError):
+            od.pop('xyz')
+        self.assertEqual(len(od), 0)
+        self.assertEqual(od.pop(k, 12345), 12345)
+
+        # make sure pop still works when __missing__ is defined
+        class Missing(OrderedDict):
+            def __missing__(self, key):
+                return 0
+        m = Missing(a=1)
+        self.assertEqual(m.pop('b', 5), 5)
+        self.assertEqual(m.pop('a', 6), 1)
+        self.assertEqual(m.pop('a', 6), 6)
+        self.assertEqual(m.pop('a', default=6), 6)
+        with self.assertRaises(KeyError):
+            m.pop('a')
+
+    def test_equality(self):
+        OrderedDict = self.OrderedDict
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        shuffle(pairs)
+        od1 = OrderedDict(pairs)
+        od2 = OrderedDict(pairs)
+        self.assertEqual(od1, od2)          # same order implies equality
+        pairs = pairs[2:] + pairs[:2]
+        od2 = OrderedDict(pairs)
+        self.assertNotEqual(od1, od2)       # different order implies inequality
+        # comparison to regular dict is not order sensitive
+        self.assertEqual(od1, dict(od2))
+        self.assertEqual(dict(od2), od1)
+        # different length implied inequality
+        self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
+
+    def test_copying(self):
+        OrderedDict = self.OrderedDict
+        # Check that ordered dicts are copyable, deepcopyable, picklable,
+        # and have a repr/eval round-trip
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        od = OrderedDict(pairs)
+        def check(dup):
+            msg = "\ncopy: %s\nod: %s" % (dup, od)
+            self.assertIsNot(dup, od, msg)
+            self.assertEqual(dup, od)
+            self.assertEqual(list(dup.items()), list(od.items()))
+            self.assertEqual(len(dup), len(od))
+            self.assertEqual(type(dup), type(od))
+        check(od.copy())
+        check(copy.copy(od))
+        check(copy.deepcopy(od))
+        # pickle directly pulls the module, so we have to fake it
+        with replaced_module('collections', self.module):
+            for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+                with self.subTest(proto=proto):
+                    check(pickle.loads(pickle.dumps(od, proto)))
+        check(eval(repr(od)))
+        update_test = OrderedDict()
+        update_test.update(od)
+        check(update_test)
+        check(OrderedDict(od))
+
+    def test_yaml_linkage(self):
+        OrderedDict = self.OrderedDict
+        # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
+        # In yaml, lists are native but tuples are not.
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        od = OrderedDict(pairs)
+        # yaml.dump(od) -->
+        # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n  - [b, 2]\n'
+        self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
+
+    def test_reduce_not_too_fat(self):
+        OrderedDict = self.OrderedDict
+        # do not save instance dictionary if not needed
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        od = OrderedDict(pairs)
+        self.assertIsNone(od.__reduce__()[2])
+        od.x = 10
+        self.assertIsNotNone(od.__reduce__()[2])
+
+    def test_pickle_recursive(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        od[1] = od
+
+        # pickle directly pulls the module, so we have to fake it
+        with replaced_module('collections', self.module):
+            for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1):
+                dup = pickle.loads(pickle.dumps(od, proto))
+                self.assertIsNot(dup, od)
+                self.assertEqual(list(dup.keys()), [1])
+                self.assertIs(dup[1], dup)
+
+    def test_repr(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
+        self.assertEqual(repr(od),
+            "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])")
+        self.assertEqual(eval(repr(od)), od)
+        self.assertEqual(repr(OrderedDict()), "OrderedDict()")
+
+    def test_repr_recursive(self):
+        OrderedDict = self.OrderedDict
+        # See issue #9826
+        od = OrderedDict.fromkeys('abc')
+        od['x'] = od
+        self.assertEqual(repr(od),
+            "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
+
+    def test_setdefault(self):
+        OrderedDict = self.OrderedDict
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        shuffle(pairs)
+        od = OrderedDict(pairs)
+        pair_order = list(od.items())
+        self.assertEqual(od.setdefault('a', 10), 3)
+        # make sure order didn't change
+        self.assertEqual(list(od.items()), pair_order)
+        self.assertEqual(od.setdefault('x', 10), 10)
+        # make sure 'x' is added to the end
+        self.assertEqual(list(od.items())[-1], ('x', 10))
+        self.assertEqual(od.setdefault('g', default=9), 9)
+
+        # make sure setdefault still works when __missing__ is defined
+        class Missing(OrderedDict):
+            def __missing__(self, key):
+                return 0
+        self.assertEqual(Missing().setdefault(5, 9), 9)
+
+    def test_reinsert(self):
+        OrderedDict = self.OrderedDict
+        # Given insert a, insert b, delete a, re-insert a,
+        # verify that a is now later than b.
+        od = OrderedDict()
+        od['a'] = 1
+        od['b'] = 2
+        del od['a']
+        self.assertEqual(list(od.items()), [('b', 2)])
+        od['a'] = 1
+        self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
+
+    def test_move_to_end(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict.fromkeys('abcde')
+        self.assertEqual(list(od), list('abcde'))
+        od.move_to_end('c')
+        self.assertEqual(list(od), list('abdec'))
+        od.move_to_end('c', 0)
+        self.assertEqual(list(od), list('cabde'))
+        od.move_to_end('c', 0)
+        self.assertEqual(list(od), list('cabde'))
+        od.move_to_end('e')
+        self.assertEqual(list(od), list('cabde'))
+        od.move_to_end('b', last=False)
+        self.assertEqual(list(od), list('bcade'))
+        with self.assertRaises(KeyError):
+            od.move_to_end('x')
+        with self.assertRaises(KeyError):
+            od.move_to_end('x', 0)
+
+    def test_move_to_end_issue25406(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict.fromkeys('abc')
+        od.move_to_end('c', last=False)
+        self.assertEqual(list(od), list('cab'))
+        od.move_to_end('a', last=False)
+        self.assertEqual(list(od), list('acb'))
+
+        od = OrderedDict.fromkeys('abc')
+        od.move_to_end('a')
+        self.assertEqual(list(od), list('bca'))
+        od.move_to_end('c')
+        self.assertEqual(list(od), list('bac'))
+
+    def test_sizeof(self):
+        OrderedDict = self.OrderedDict
+        # Wimpy test: Just verify the reported size is larger than a regular dict
+        d = dict(a=1)
+        od = OrderedDict(**d)
+        self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
+
+    def test_override_update(self):
+        OrderedDict = self.OrderedDict
+        # Verify that subclasses can override update() without breaking __init__()
+        class MyOD(OrderedDict):
+            def update(self, *args, **kwds):
+                raise Exception()
+        items = [('a', 1), ('c', 3), ('b', 2)]
+        self.assertEqual(list(MyOD(items).items()), items)
+
+    def test_highly_nested(self):
+        # Issue 25395: crashes during garbage collection
+        OrderedDict = self.OrderedDict
+        obj = None
+        for _ in range(1000):
+            obj = OrderedDict([(None, obj)])
+        del obj
+        support.gc_collect()
+
+    def test_highly_nested_subclass(self):
+        # Issue 25395: crashes during garbage collection
+        OrderedDict = self.OrderedDict
+        deleted = []
+        class MyOD(OrderedDict):
+            def __del__(self):
+                deleted.append(self.i)
+        obj = None
+        for i in range(100):
+            obj = MyOD([(None, obj)])
+            obj.i = i
+        del obj
+        support.gc_collect()
+        self.assertEqual(deleted, list(reversed(range(100))))
+
+    def test_delitem_hash_collision(self):
+        OrderedDict = self.OrderedDict
+
+        class Key:
+            def __init__(self, hash):
+                self._hash = hash
+                self.value = str(id(self))
+            def __hash__(self):
+                return self._hash
+            def __eq__(self, other):
+                try:
+                    return self.value == other.value
+                except AttributeError:
+                    return False
+            def __repr__(self):
+                return self.value
+
+        def blocking_hash(hash):
+            # See the collision-handling in lookdict (in Objects/dictobject.c).
+            MINSIZE = 8
+            i = (hash & MINSIZE-1)
+            return (i << 2) + i + hash + 1
+
+        COLLIDING = 1
+
+        key = Key(COLLIDING)
+        colliding = Key(COLLIDING)
+        blocking = Key(blocking_hash(COLLIDING))
+
+        od = OrderedDict()
+        od[key] = ...
+        od[blocking] = ...
+        od[colliding] = ...
+        od['after'] = ...
+
+        del od[blocking]
+        del od[colliding]
+        self.assertEqual(list(od.items()), [(key, ...), ('after', ...)])
+
+    def test_issue24347(self):
+        OrderedDict = self.OrderedDict
+
+        class Key:
+            def __hash__(self):
+                return randrange(100000)
+
+        od = OrderedDict()
+        for i in range(100):
+            key = Key()
+            od[key] = i
+
+        # These should not crash.
+        with self.assertRaises(KeyError):
+            list(od.values())
+        with self.assertRaises(KeyError):
+            list(od.items())
+        with self.assertRaises(KeyError):
+            repr(od)
+        with self.assertRaises(KeyError):
+            od.copy()
+
+    def test_issue24348(self):
+        OrderedDict = self.OrderedDict
+
+        class Key:
+            def __hash__(self):
+                return 1
+
+        od = OrderedDict()
+        od[Key()] = 0
+        # This should not crash.
+        od.popitem()
+
+    def test_issue24667(self):
+        """
+        dict resizes after a certain number of insertion operations,
+        whether or not there were deletions that freed up slots in the
+        hash table.  During fast node lookup, OrderedDict must correctly
+        respond to all resizes, even if the current "size" is the same
+        as the old one.  We verify that here by forcing a dict resize
+        on a sparse odict and then perform an operation that should
+        trigger an odict resize (e.g. popitem).  One key aspect here is
+        that we will keep the size of the odict the same at each popitem
+        call.  This verifies that we handled the dict resize properly.
+        """
+        OrderedDict = self.OrderedDict
+
+        od = OrderedDict()
+        for c0 in '0123456789ABCDEF':
+            for c1 in '0123456789ABCDEF':
+                if len(od) == 4:
+                    # This should not raise a KeyError.
+                    od.popitem(last=False)
+                key = c0 + c1
+                od[key] = key
+
+    # Direct use of dict methods
+
+    def test_dict_setitem(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        dict.__setitem__(od, 'spam', 1)
+        self.assertNotIn('NULL', repr(od))
+
+    def test_dict_delitem(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        od['spam'] = 1
+        od['ham'] = 2
+        dict.__delitem__(od, 'spam')
+        with self.assertRaises(KeyError):
+            repr(od)
+
+    def test_dict_clear(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        od['spam'] = 1
+        od['ham'] = 2
+        dict.clear(od)
+        self.assertNotIn('NULL', repr(od))
+
+    def test_dict_pop(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        od['spam'] = 1
+        od['ham'] = 2
+        dict.pop(od, 'spam')
+        with self.assertRaises(KeyError):
+            repr(od)
+
+    def test_dict_popitem(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        od['spam'] = 1
+        od['ham'] = 2
+        dict.popitem(od)
+        with self.assertRaises(KeyError):
+            repr(od)
+
+    def test_dict_setdefault(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        dict.setdefault(od, 'spam', 1)
+        self.assertNotIn('NULL', repr(od))
+
+    def test_dict_update(self):
+        OrderedDict = self.OrderedDict
+        od = OrderedDict()
+        dict.update(od, [('spam', 1)])
+        self.assertNotIn('NULL', repr(od))
+
+    def test_reference_loop(self):
+        # Issue 25935
+        OrderedDict = self.OrderedDict
+        class A:
+            od = OrderedDict()
+        A.od[A] = None
+        r = weakref.ref(A)
+        del A
+        gc.collect()
+        self.assertIsNone(r())
+
+    def test_free_after_iterating(self):
+        support.check_free_after_iterating(self, iter, self.OrderedDict)
+        support.check_free_after_iterating(self, lambda d: iter(d.keys()), self.OrderedDict)
+        support.check_free_after_iterating(self, lambda d: iter(d.values()), self.OrderedDict)
+        support.check_free_after_iterating(self, lambda d: iter(d.items()), self.OrderedDict)
+
+
+class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
+
+    module = py_coll
+    OrderedDict = py_coll.OrderedDict
+
+
+@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
+class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
+
+    module = c_coll
+    OrderedDict = c_coll.OrderedDict
+    check_sizeof = support.check_sizeof
+
+    @support.cpython_only
+    def test_sizeof_exact(self):
+        OrderedDict = self.OrderedDict
+        calcsize = struct.calcsize
+        size = support.calcobjsize
+        check = self.check_sizeof
+
+        basicsize = size('n2P' + '3PnPn2P') + calcsize('2nPn')
+        entrysize = calcsize('n2P') + calcsize('P')
+        nodesize = calcsize('Pn2P')
+
+        od = OrderedDict()
+        check(od, basicsize + 8*entrysize)
+        od.x = 1
+        check(od, basicsize + 8*entrysize)
+        od.update([(i, i) for i in range(3)])
+        check(od, basicsize + 8*entrysize + 3*nodesize)
+        od.update([(i, i) for i in range(3, 10)])
+        check(od, basicsize + 16*entrysize + 10*nodesize)
+
+        check(od.keys(), size('P'))
+        check(od.items(), size('P'))
+        check(od.values(), size('P'))
+
+        itersize = size('iP2n2P')
+        check(iter(od), itersize)
+        check(iter(od.keys()), itersize)
+        check(iter(od.items()), itersize)
+        check(iter(od.values()), itersize)
+
+    def test_key_change_during_iteration(self):
+        OrderedDict = self.OrderedDict
+
+        od = OrderedDict.fromkeys('abcde')
+        self.assertEqual(list(od), list('abcde'))
+        with self.assertRaises(RuntimeError):
+            for i, k in enumerate(od):
+                od.move_to_end(k)
+                self.assertLess(i, 5)
+        with self.assertRaises(RuntimeError):
+            for k in od:
+                od['f'] = None
+        with self.assertRaises(RuntimeError):
+            for k in od:
+                del od['c']
+        self.assertEqual(list(od), list('bdeaf'))
+
+
+class PurePythonOrderedDictSubclassTests(PurePythonOrderedDictTests):
+
+    module = py_coll
+    class OrderedDict(py_coll.OrderedDict):
+        pass
+
+
+class CPythonOrderedDictSubclassTests(CPythonOrderedDictTests):
+
+    module = c_coll
+    class OrderedDict(c_coll.OrderedDict):
+        pass
+
+
+class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.type2test = py_coll.OrderedDict
+
+    def test_popitem(self):
+        d = self._empty_mapping()
+        self.assertRaises(KeyError, d.popitem)
+
+
+@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
+class CPythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.type2test = c_coll.OrderedDict
+
+    def test_popitem(self):
+        d = self._empty_mapping()
+        self.assertRaises(KeyError, d.popitem)
+
+
+class PurePythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
+
+    @classmethod
+    def setUpClass(cls):
+        class MyOrderedDict(py_coll.OrderedDict):
+            pass
+        cls.type2test = MyOrderedDict
+
+    def test_popitem(self):
+        d = self._empty_mapping()
+        self.assertRaises(KeyError, d.popitem)
+
+
+@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
+class CPythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
+
+    @classmethod
+    def setUpClass(cls):
+        class MyOrderedDict(c_coll.OrderedDict):
+            pass
+        cls.type2test = MyOrderedDict
+
+    def test_popitem(self):
+        d = self._empty_mapping()
+        self.assertRaises(KeyError, d.popitem)
+
+
+if __name__ == "__main__":
+    unittest.main()
index 618c18a..874f9e4 100644 (file)
@@ -791,12 +791,10 @@ class WalkTests(unittest.TestCase):
 
     # Wrapper to hide minor differences between os.walk and os.fwalk
     # to tests both functions with the same code base
-    def walk(self, directory, topdown=True, follow_symlinks=False):
-        walk_it = os.walk(directory,
-                          topdown=topdown,
-                          followlinks=follow_symlinks)
-        for root, dirs, files in walk_it:
-            yield (root, dirs, files)
+    def walk(self, top, **kwargs):
+        if 'follow_symlinks' in kwargs:
+            kwargs['followlinks'] = kwargs.pop('follow_symlinks')
+        return os.walk(top, **kwargs)
 
     def setUp(self):
         join = os.path.join
@@ -845,7 +843,7 @@ class WalkTests(unittest.TestCase):
 
     def test_walk_topdown(self):
         # Walk top-down.
-        all = list(os.walk(self.walk_path))
+        all = list(self.walk(self.walk_path))
 
         self.assertEqual(len(all), 4)
         # We can't know which order SUB1 and SUB2 will appear in.
@@ -926,19 +924,31 @@ class WalkTests(unittest.TestCase):
                     os.remove(dirname)
         os.rmdir(support.TESTFN)
 
+    def test_walk_bad_dir(self):
+        # Walk top-down.
+        errors = []
+        walk_it = self.walk(self.walk_path, onerror=errors.append)
+        root, dirs, files = next(walk_it)
+        self.assertFalse(errors)
+        dir1 = dirs[0]
+        dir1new = dir1 + '.new'
+        os.rename(os.path.join(root, dir1), os.path.join(root, dir1new))
+        roots = [r for r, d, f in walk_it]
+        self.assertTrue(errors)
+        self.assertNotIn(os.path.join(root, dir1), roots)
+        self.assertNotIn(os.path.join(root, dir1new), roots)
+        for dir2 in dirs[1:]:
+            self.assertIn(os.path.join(root, dir2), roots)
+
 
 @unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()")
 class FwalkTests(WalkTests):
     """Tests for os.fwalk()."""
 
-    def walk(self, directory, topdown=True, follow_symlinks=False):
-        walk_it = os.fwalk(directory,
-                           topdown=topdown,
-                           follow_symlinks=follow_symlinks)
-        for root, dirs, files, root_fd in walk_it:
+    def walk(self, top, **kwargs):
+        for root, dirs, files, root_fd in os.fwalk(top, **kwargs):
             yield (root, dirs, files)
 
-
     def _compare_to_walk(self, walk_kwargs, fwalk_kwargs):
         """
         compare with walk() results.
@@ -1009,6 +1019,30 @@ class FwalkTests(WalkTests):
                     os.unlink(name, dir_fd=rootfd)
         os.rmdir(support.TESTFN)
 
+class BytesWalkTests(WalkTests):
+    """Tests for os.walk() with bytes."""
+    def setUp(self):
+        super().setUp()
+        self.stack = contextlib.ExitStack()
+        if os.name == 'nt':
+            self.stack.enter_context(warnings.catch_warnings())
+            warnings.simplefilter("ignore", DeprecationWarning)
+
+    def tearDown(self):
+        self.stack.close()
+        super().tearDown()
+
+    def walk(self, top, **kwargs):
+        if 'follow_symlinks' in kwargs:
+            kwargs['followlinks'] = kwargs.pop('follow_symlinks')
+        for broot, bdirs, bfiles in os.walk(os.fsencode(top), **kwargs):
+            root = os.fsdecode(broot)
+            dirs = list(map(os.fsdecode, bdirs))
+            files = list(map(os.fsdecode, bfiles))
+            yield (root, dirs, files)
+            bdirs[:] = list(map(os.fsencode, dirs))
+            bfiles[:] = list(map(os.fsencode, files))
+
 
 class MakedirTests(unittest.TestCase):
     def setUp(self):
index 1c53ab7..fa96d9f 100644 (file)
@@ -200,7 +200,7 @@ class _BasePurePathTest(object):
 
     def _check_str_subclass(self, *args):
         # Issue #21127: it should be possible to construct a PurePath object
-        # from an str subclass instance, and it then gets converted to
+        # from a str subclass instance, and it then gets converted to
         # a pure str object.
         class StrSubclass(str):
             pass
@@ -1129,7 +1129,6 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
         # UNC paths are never reserved
         self.assertIs(False, P('//my/share/nul/con/aux').is_reserved())
 
-
 class PurePathTest(_BasePurePathTest, unittest.TestCase):
     cls = pathlib.PurePath
 
@@ -1193,32 +1192,49 @@ class PosixPathAsPureTest(PurePosixPathTest):
 class WindowsPathAsPureTest(PureWindowsPathTest):
     cls = pathlib.WindowsPath
 
+    def test_owner(self):
+        P = self.cls
+        with self.assertRaises(NotImplementedError):
+            P('c:/').owner()
+
+    def test_group(self):
+        P = self.cls
+        with self.assertRaises(NotImplementedError):
+            P('c:/').group()
+
 
 class _BasePathTest(object):
     """Tests for the FS-accessing functionalities of the Path classes."""
 
     # (BASE)
     #  |
-    #  |-- dirA/
-    #       |-- linkC -> "../dirB"
-    #  |-- dirB/
-    #  |    |-- fileB
-    #       |-- linkD -> "../dirB"
-    #  |-- dirC/
-    #  |    |-- fileC
-    #  |    |-- fileD
+    #  |-- brokenLink -> non-existing
+    #  |-- dirA
+    #  |   `-- linkC -> ../dirB
+    #  |-- dirB
+    #  |   |-- fileB
+    #  |   `-- linkD -> ../dirB
+    #  |-- dirC
+    #  |   |-- dirD
+    #  |   |   `-- fileD
+    #  |   `-- fileC
+    #  |-- dirE  # No permissions
     #  |-- fileA
-    #  |-- linkA -> "fileA"
-    #  |-- linkB -> "dirB"
+    #  |-- linkA -> fileA
+    #  `-- linkB -> dirB
     #
 
     def setUp(self):
+        def cleanup():
+            os.chmod(join('dirE'), 0o777)
+            support.rmtree(BASE)
+        self.addCleanup(cleanup)
         os.mkdir(BASE)
-        self.addCleanup(support.rmtree, BASE)
         os.mkdir(join('dirA'))
         os.mkdir(join('dirB'))
         os.mkdir(join('dirC'))
         os.mkdir(join('dirC', 'dirD'))
+        os.mkdir(join('dirE'))
         with open(join('fileA'), 'wb') as f:
             f.write(b"this is file A\n")
         with open(join('dirB', 'fileB'), 'wb') as f:
@@ -1227,13 +1243,14 @@ class _BasePathTest(object):
             f.write(b"this is file C\n")
         with open(join('dirC', 'dirD', 'fileD'), 'wb') as f:
             f.write(b"this is file D\n")
+        os.chmod(join('dirE'), 0)
         if not symlink_skip_reason:
             # Relative symlinks
             os.symlink('fileA', join('linkA'))
             os.symlink('non-existing', join('brokenLink'))
             self.dirlink('dirB', join('linkB'))
             self.dirlink(os.path.join('..', 'dirB'), join('dirA', 'linkC'))
-            # This one goes upwards but doesn't create a loop
+            # This one goes upwards, creating a loop
             self.dirlink(os.path.join('..', 'dirB'), join('dirB', 'linkD'))
 
     if os.name == 'nt':
@@ -1363,7 +1380,7 @@ class _BasePathTest(object):
         p = P(BASE)
         it = p.iterdir()
         paths = set(it)
-        expected = ['dirA', 'dirB', 'dirC', 'fileA']
+        expected = ['dirA', 'dirB', 'dirC', 'dirE', 'fileA']
         if not symlink_skip_reason:
             expected += ['linkA', 'linkB', 'brokenLink']
         self.assertEqual(paths, { P(BASE, q) for q in expected })
@@ -1418,17 +1435,37 @@ class _BasePathTest(object):
         p = P(BASE)
         it = p.rglob("fileA")
         self.assertIsInstance(it, collections.Iterator)
-        # XXX cannot test because of symlink loops in the test setup
-        #_check(it, ["fileA"])
-        #_check(p.rglob("fileB"), ["dirB/fileB"])
-        #_check(p.rglob("*/fileA"), [""])
-        #_check(p.rglob("*/fileB"), ["dirB/fileB"])
-        #_check(p.rglob("file*"), ["fileA", "dirB/fileB"])
-        # No symlink loops here
+        _check(it, ["fileA"])
+        _check(p.rglob("fileB"), ["dirB/fileB"])
+        _check(p.rglob("*/fileA"), [])
+        if symlink_skip_reason:
+            _check(p.rglob("*/fileB"), ["dirB/fileB"])
+        else:
+            _check(p.rglob("*/fileB"), ["dirB/fileB", "dirB/linkD/fileB",
+                                        "linkB/fileB", "dirA/linkC/fileB"])
+        _check(p.rglob("file*"), ["fileA", "dirB/fileB",
+                                  "dirC/fileC", "dirC/dirD/fileD"])
         p = P(BASE, "dirC")
         _check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"])
         _check(p.rglob("*/*"), ["dirC/dirD/fileD"])
 
+    @with_symlinks
+    def test_rglob_symlink_loop(self):
+        # Don't get fooled by symlink loops (Issue #26012)
+        P = self.cls
+        p = P(BASE)
+        given = set(p.rglob('*'))
+        expect = {'brokenLink',
+                  'dirA', 'dirA/linkC',
+                  'dirB', 'dirB/fileB', 'dirB/linkD',
+                  'dirC', 'dirC/dirD', 'dirC/dirD/fileD', 'dirC/fileC',
+                  'dirE',
+                  'fileA',
+                  'linkA',
+                  'linkB',
+                  }
+        self.assertEqual(given, {p / x for x in expect})
+
     def test_glob_dotdot(self):
         # ".." is not special in globs
         P = self.cls
@@ -1914,6 +1951,11 @@ class PathTest(_BasePathTest, unittest.TestCase):
         else:
             self.assertRaises(NotImplementedError, pathlib.WindowsPath)
 
+    def test_glob_empty_pattern(self):
+        p = self.cls()
+        with self.assertRaisesRegex(ValueError, 'Unacceptable pattern'):
+            list(p.glob(''))
+
 
 @only_posix
 class PosixPathTest(_BasePathTest, unittest.TestCase):
@@ -1993,7 +2035,7 @@ class PosixPathTest(_BasePathTest, unittest.TestCase):
         import pwd
         pwdent = pwd.getpwuid(os.getuid())
         username = pwdent.pw_name
-        userhome = pwdent.pw_dir.rstrip('/')
+        userhome = pwdent.pw_dir.rstrip('/') or '/'
         # find arbitrary different user (if exists)
         for pwdent in pwd.getpwall():
             othername = pwdent.pw_name
index 35044ad..45ba5a9 100644 (file)
@@ -824,7 +824,7 @@ def test_pdb_until_command_for_generator():
     """
 
 def test_pdb_next_command_in_generator_for_loop():
-    """The next command on returning from a generator controled by a for loop.
+    """The next command on returning from a generator controlled by a for loop.
 
     >>> def test_gen():
     ...     yield 0
diff --git a/Lib/test/test_pep292.py b/Lib/test/test_pep292.py
deleted file mode 100644 (file)
index 1e5e227..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-# Copyright (C) 2004 Python Software Foundation
-# Author: barry@python.org (Barry Warsaw)
-# License: http://www.opensource.org/licenses/PythonSoftFoundation.php
-
-import unittest
-from string import Template
-
-
-class Bag:
-    pass
-
-class Mapping:
-    def __getitem__(self, name):
-        obj = self
-        for part in name.split('.'):
-            try:
-                obj = getattr(obj, part)
-            except AttributeError:
-                raise KeyError(name)
-        return obj
-
-
-class TestTemplate(unittest.TestCase):
-    def test_regular_templates(self):
-        s = Template('$who likes to eat a bag of $what worth $$100')
-        self.assertEqual(s.substitute(dict(who='tim', what='ham')),
-                         'tim likes to eat a bag of ham worth $100')
-        self.assertRaises(KeyError, s.substitute, dict(who='tim'))
-        self.assertRaises(TypeError, Template.substitute)
-
-    def test_regular_templates_with_braces(self):
-        s = Template('$who likes ${what} for ${meal}')
-        d = dict(who='tim', what='ham', meal='dinner')
-        self.assertEqual(s.substitute(d), 'tim likes ham for dinner')
-        self.assertRaises(KeyError, s.substitute,
-                          dict(who='tim', what='ham'))
-
-    def test_escapes(self):
-        eq = self.assertEqual
-        s = Template('$who likes to eat a bag of $$what worth $$100')
-        eq(s.substitute(dict(who='tim', what='ham')),
-           'tim likes to eat a bag of $what worth $100')
-        s = Template('$who likes $$')
-        eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $')
-
-    def test_percents(self):
-        eq = self.assertEqual
-        s = Template('%(foo)s $foo ${foo}')
-        d = dict(foo='baz')
-        eq(s.substitute(d), '%(foo)s baz baz')
-        eq(s.safe_substitute(d), '%(foo)s baz baz')
-
-    def test_stringification(self):
-        eq = self.assertEqual
-        s = Template('tim has eaten $count bags of ham today')
-        d = dict(count=7)
-        eq(s.substitute(d), 'tim has eaten 7 bags of ham today')
-        eq(s.safe_substitute(d), 'tim has eaten 7 bags of ham today')
-        s = Template('tim has eaten ${count} bags of ham today')
-        eq(s.substitute(d), 'tim has eaten 7 bags of ham today')
-
-    def test_tupleargs(self):
-        eq = self.assertEqual
-        s = Template('$who ate ${meal}')
-        d = dict(who=('tim', 'fred'), meal=('ham', 'kung pao'))
-        eq(s.substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')")
-        eq(s.safe_substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')")
-
-    def test_SafeTemplate(self):
-        eq = self.assertEqual
-        s = Template('$who likes ${what} for ${meal}')
-        eq(s.safe_substitute(dict(who='tim')), 'tim likes ${what} for ${meal}')
-        eq(s.safe_substitute(dict(what='ham')), '$who likes ham for ${meal}')
-        eq(s.safe_substitute(dict(what='ham', meal='dinner')),
-           '$who likes ham for dinner')
-        eq(s.safe_substitute(dict(who='tim', what='ham')),
-           'tim likes ham for ${meal}')
-        eq(s.safe_substitute(dict(who='tim', what='ham', meal='dinner')),
-           'tim likes ham for dinner')
-
-    def test_invalid_placeholders(self):
-        raises = self.assertRaises
-        s = Template('$who likes $')
-        raises(ValueError, s.substitute, dict(who='tim'))
-        s = Template('$who likes ${what)')
-        raises(ValueError, s.substitute, dict(who='tim'))
-        s = Template('$who likes $100')
-        raises(ValueError, s.substitute, dict(who='tim'))
-
-    def test_idpattern_override(self):
-        class PathPattern(Template):
-            idpattern = r'[_a-z][._a-z0-9]*'
-        m = Mapping()
-        m.bag = Bag()
-        m.bag.foo = Bag()
-        m.bag.foo.who = 'tim'
-        m.bag.what = 'ham'
-        s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what')
-        self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
-
-    def test_pattern_override(self):
-        class MyPattern(Template):
-            pattern = r"""
-            (?P<escaped>@{2})                   |
-            @(?P<named>[_a-z][._a-z0-9]*)       |
-            @{(?P<braced>[_a-z][._a-z0-9]*)}    |
-            (?P<invalid>@)
-            """
-        m = Mapping()
-        m.bag = Bag()
-        m.bag.foo = Bag()
-        m.bag.foo.who = 'tim'
-        m.bag.what = 'ham'
-        s = MyPattern('@bag.foo.who likes to eat a bag of @bag.what')
-        self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
-
-        class BadPattern(Template):
-            pattern = r"""
-            (?P<badname>.*)                     |
-            (?P<escaped>@{2})                   |
-            @(?P<named>[_a-z][._a-z0-9]*)       |
-            @{(?P<braced>[_a-z][._a-z0-9]*)}    |
-            (?P<invalid>@)                      |
-            """
-        s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what')
-        self.assertRaises(ValueError, s.substitute, {})
-        self.assertRaises(ValueError, s.safe_substitute, {})
-
-    def test_braced_override(self):
-        class MyTemplate(Template):
-            pattern = r"""
-            \$(?:
-              (?P<escaped>$)                     |
-              (?P<named>[_a-z][_a-z0-9]*)        |
-              @@(?P<braced>[_a-z][_a-z0-9]*)@@   |
-              (?P<invalid>)                      |
-           )
-           """
-
-        tmpl = 'PyCon in $@@location@@'
-        t = MyTemplate(tmpl)
-        self.assertRaises(KeyError, t.substitute, {})
-        val = t.substitute({'location': 'Cleveland'})
-        self.assertEqual(val, 'PyCon in Cleveland')
-
-    def test_braced_override_safe(self):
-        class MyTemplate(Template):
-            pattern = r"""
-            \$(?:
-              (?P<escaped>$)                     |
-              (?P<named>[_a-z][_a-z0-9]*)        |
-              @@(?P<braced>[_a-z][_a-z0-9]*)@@   |
-              (?P<invalid>)                      |
-           )
-           """
-
-        tmpl = 'PyCon in $@@location@@'
-        t = MyTemplate(tmpl)
-        self.assertEqual(t.safe_substitute(), tmpl)
-        val = t.safe_substitute({'location': 'Cleveland'})
-        self.assertEqual(val, 'PyCon in Cleveland')
-
-    def test_invalid_with_no_lines(self):
-        # The error formatting for invalid templates
-        # has a special case for no data that the default
-        # pattern can't trigger (always has at least '$')
-        # So we craft a pattern that is always invalid
-        # with no leading data.
-        class MyTemplate(Template):
-            pattern = r"""
-              (?P<invalid>) |
-              unreachable(
-                (?P<named>)   |
-                (?P<braced>)  |
-                (?P<escaped>)
-              )
-            """
-        s = MyTemplate('')
-        with self.assertRaises(ValueError) as err:
-            s.substitute({})
-        self.assertIn('line 1, col 1', str(err.exception))
-
-    def test_unicode_values(self):
-        s = Template('$who likes $what')
-        d = dict(who='t\xffm', what='f\xfe\fed')
-        self.assertEqual(s.substitute(d), 't\xffm likes f\xfe\x0ced')
-
-    def test_keyword_arguments(self):
-        eq = self.assertEqual
-        s = Template('$who likes $what')
-        eq(s.substitute(who='tim', what='ham'), 'tim likes ham')
-        eq(s.substitute(dict(who='tim'), what='ham'), 'tim likes ham')
-        eq(s.substitute(dict(who='fred', what='kung pao'),
-                        who='tim', what='ham'),
-           'tim likes ham')
-        s = Template('the mapping is $mapping')
-        eq(s.substitute(dict(foo='none'), mapping='bozo'),
-           'the mapping is bozo')
-        eq(s.substitute(dict(mapping='one'), mapping='two'),
-           'the mapping is two')
-
-        s = Template('the self is $self')
-        eq(s.substitute(self='bozo'), 'the self is bozo')
-
-    def test_keyword_arguments_safe(self):
-        eq = self.assertEqual
-        raises = self.assertRaises
-        s = Template('$who likes $what')
-        eq(s.safe_substitute(who='tim', what='ham'), 'tim likes ham')
-        eq(s.safe_substitute(dict(who='tim'), what='ham'), 'tim likes ham')
-        eq(s.safe_substitute(dict(who='fred', what='kung pao'),
-                        who='tim', what='ham'),
-           'tim likes ham')
-        s = Template('the mapping is $mapping')
-        eq(s.safe_substitute(dict(foo='none'), mapping='bozo'),
-           'the mapping is bozo')
-        eq(s.safe_substitute(dict(mapping='one'), mapping='two'),
-           'the mapping is two')
-        d = dict(mapping='one')
-        raises(TypeError, s.substitute, d, {})
-        raises(TypeError, s.safe_substitute, d, {})
-
-        s = Template('the self is $self')
-        eq(s.safe_substitute(self='bozo'), 'the self is bozo')
-
-    def test_delimiter_override(self):
-        eq = self.assertEqual
-        raises = self.assertRaises
-        class AmpersandTemplate(Template):
-            delimiter = '&'
-        s = AmpersandTemplate('this &gift is for &{who} &&')
-        eq(s.substitute(gift='bud', who='you'), 'this bud is for you &')
-        raises(KeyError, s.substitute)
-        eq(s.safe_substitute(gift='bud', who='you'), 'this bud is for you &')
-        eq(s.safe_substitute(), 'this &gift is for &{who} &')
-        s = AmpersandTemplate('this &gift is for &{who} &')
-        raises(ValueError, s.substitute, dict(gift='bud', who='you'))
-        eq(s.safe_substitute(), 'this &gift is for &{who} &')
-
-        class PieDelims(Template):
-            delimiter = '@'
-        s = PieDelims('@who likes to eat a bag of @{what} worth $100')
-        self.assertEqual(s.substitute(dict(who='tim', what='ham')),
-                         'tim likes to eat a bag of ham worth $100')
-
-
-if __name__ == '__main__':
-    unittest.main()
index 8d560cd..7b0d465 100644 (file)
@@ -164,7 +164,7 @@ class ExplicitSubclassingTest(unittest.TestCase):
         e = SubOSError(EEXIST, "Bad file descriptor")
         self.assertIs(type(e), SubOSError)
 
-    def test_init_overriden(self):
+    def test_init_overridden(self):
         e = SubOSErrorWithInit("some message", "baz")
         self.assertEqual(e.bar, "baz")
         self.assertEqual(e.args, ("some message",))
@@ -174,7 +174,7 @@ class ExplicitSubclassingTest(unittest.TestCase):
         self.assertEqual(e.bar, "baz")
         self.assertEqual(e.args, ("some message",))
 
-    def test_new_overriden(self):
+    def test_new_overridden(self):
         e = SubOSErrorWithNew("some message", "baz")
         self.assertEqual(e.baz, "baz")
         self.assertEqual(e.args, ("some message",))
@@ -184,7 +184,7 @@ class ExplicitSubclassingTest(unittest.TestCase):
         self.assertEqual(e.baz, "baz")
         self.assertEqual(e.args, ("some message",))
 
-    def test_init_new_overriden(self):
+    def test_init_new_overridden(self):
         e = SubOSErrorCombinedInitFirst("some message", "baz")
         self.assertEqual(e.bar, "baz")
         self.assertEqual(e.baz, "baz")
index 0429941..ee7a667 100644 (file)
@@ -32,6 +32,12 @@ class PickleTests(AbstractPickleModuleTests):
 class PyUnpicklerTests(AbstractUnpickleTests):
 
     unpickler = pickle._Unpickler
+    bad_stack_errors = (IndexError,)
+    bad_mark_errors = (IndexError, pickle.UnpicklingError,
+                       TypeError, AttributeError, EOFError)
+    truncated_errors = (pickle.UnpicklingError, EOFError,
+                        AttributeError, ValueError,
+                        struct.error, IndexError, ImportError)
 
     def loads(self, buf, **kwds):
         f = io.BytesIO(buf)
@@ -62,6 +68,12 @@ class InMemoryPickleTests(AbstractPickleTests, AbstractUnpickleTests,
 
     pickler = pickle._Pickler
     unpickler = pickle._Unpickler
+    bad_stack_errors = (pickle.UnpicklingError, IndexError)
+    bad_mark_errors = (pickle.UnpicklingError, IndexError,
+                       TypeError, AttributeError, EOFError)
+    truncated_errors = (pickle.UnpicklingError, EOFError,
+                        AttributeError, ValueError,
+                        struct.error, IndexError, ImportError)
 
     def dumps(self, arg, protocol=None):
         return pickle.dumps(arg, protocol)
@@ -119,6 +131,10 @@ class PyChainDispatchTableTests(AbstractDispatchTableTests):
 if has_c_implementation:
     class CUnpicklerTests(PyUnpicklerTests):
         unpickler = _pickle.Unpickler
+        bad_stack_errors = (pickle.UnpicklingError,)
+        bad_mark_errors = (EOFError,)
+        truncated_errors = (pickle.UnpicklingError, EOFError,
+                            AttributeError, ValueError)
 
     class CPicklerTests(PyPicklerTests):
         pickler = _pickle.Pickler
@@ -228,6 +244,8 @@ if has_c_implementation:
 ALT_IMPORT_MAPPING = {
     ('_elementtree', 'xml.etree.ElementTree'),
     ('cPickle', 'pickle'),
+    ('StringIO', 'io'),
+    ('cStringIO', 'io'),
 }
 
 ALT_NAME_MAPPING = {
index 57ebf1f..9d20354 100644 (file)
@@ -7,7 +7,6 @@ import pkgutil
 import os
 import os.path
 import tempfile
-import types
 import shutil
 import zipfile
 
@@ -101,6 +100,83 @@ class PkgutilTests(unittest.TestCase):
         for t in pkgutil.walk_packages(path=[self.dirname]):
             self.fail("unexpected package found")
 
+    def test_walkpackages_filesys(self):
+        pkg1 = 'test_walkpackages_filesys'
+        pkg1_dir = os.path.join(self.dirname, pkg1)
+        os.mkdir(pkg1_dir)
+        f = open(os.path.join(pkg1_dir, '__init__.py'), "wb")
+        f.close()
+        os.mkdir(os.path.join(pkg1_dir, 'sub'))
+        f = open(os.path.join(pkg1_dir, 'sub', '__init__.py'), "wb")
+        f.close()
+        f = open(os.path.join(pkg1_dir, 'sub', 'mod.py'), "wb")
+        f.close()
+
+        # Now, to juice it up, let's add the opposite packages, too.
+        pkg2 = 'sub'
+        pkg2_dir = os.path.join(self.dirname, pkg2)
+        os.mkdir(pkg2_dir)
+        f = open(os.path.join(pkg2_dir, '__init__.py'), "wb")
+        f.close()
+        os.mkdir(os.path.join(pkg2_dir, 'test_walkpackages_filesys'))
+        f = open(os.path.join(pkg2_dir, 'test_walkpackages_filesys', '__init__.py'), "wb")
+        f.close()
+        f = open(os.path.join(pkg2_dir, 'test_walkpackages_filesys', 'mod.py'), "wb")
+        f.close()
+
+        expected = [
+            'sub',
+            'sub.test_walkpackages_filesys',
+            'sub.test_walkpackages_filesys.mod',
+            'test_walkpackages_filesys',
+            'test_walkpackages_filesys.sub',
+            'test_walkpackages_filesys.sub.mod',
+        ]
+        actual= [e[1] for e in pkgutil.walk_packages([self.dirname])]
+        self.assertEqual(actual, expected)
+
+        for pkg in expected:
+            if pkg.endswith('mod'):
+                continue
+            del sys.modules[pkg]
+
+    def test_walkpackages_zipfile(self):
+        """Tests the same as test_walkpackages_filesys, only with a zip file."""
+
+        zip = 'test_walkpackages_zipfile.zip'
+        pkg1 = 'test_walkpackages_zipfile'
+        pkg2 = 'sub'
+
+        zip_file = os.path.join(self.dirname, zip)
+        z = zipfile.ZipFile(zip_file, 'w')
+        z.writestr(pkg2 + '/__init__.py', "")
+        z.writestr(pkg2 + '/' + pkg1 + '/__init__.py', "")
+        z.writestr(pkg2 + '/' + pkg1 + '/mod.py', "")
+        z.writestr(pkg1 + '/__init__.py', "")
+        z.writestr(pkg1 + '/' + pkg2 + '/__init__.py', "")
+        z.writestr(pkg1 + '/' + pkg2 + '/mod.py', "")
+        z.close()
+
+        sys.path.insert(0, zip_file)
+        expected = [
+            'sub',
+            'sub.test_walkpackages_zipfile',
+            'sub.test_walkpackages_zipfile.mod',
+            'test_walkpackages_zipfile',
+            'test_walkpackages_zipfile.sub',
+            'test_walkpackages_zipfile.sub.mod',
+        ]
+        actual= [e[1] for e in pkgutil.walk_packages([zip_file])]
+        self.assertEqual(actual, expected)
+        del sys.path[0]
+
+        for pkg in expected:
+            if pkg.endswith('mod'):
+                continue
+            del sys.modules[pkg]
+
+
+
 class PkgutilPEP302Tests(unittest.TestCase):
 
     class MyTestLoader(object):
@@ -324,11 +400,11 @@ class ImportlibMigrationTests(unittest.TestCase):
 
     def test_importer_deprecated(self):
         with self.check_deprecated():
-            x = pkgutil.ImpImporter("")
+            pkgutil.ImpImporter("")
 
     def test_loader_deprecated(self):
         with self.check_deprecated():
-            x = pkgutil.ImpLoader("", "", "", "")
+            pkgutil.ImpLoader("", "", "", "")
 
     def test_get_loader_avoids_emulation(self):
         with check_warnings() as w:
index 3ea71f1..ed18773 100644 (file)
@@ -76,6 +76,22 @@ class PlatformTest(unittest.TestCase):
              ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')),
             ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42',
              ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')),
+            ('2.4.3 (truncation, date, t) \n[GCC]',
+             ('CPython', '2.4.3', '', '', 'truncation', 'date t', 'GCC')),
+            ('2.4.3 (truncation, date, ) \n[GCC]',
+             ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
+            ('2.4.3 (truncation, date,) \n[GCC]',
+             ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
+            ('2.4.3 (truncation, date) \n[GCC]',
+             ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
+            ('2.4.3 (truncation, d) \n[GCC]',
+             ('CPython', '2.4.3', '', '', 'truncation', 'd', 'GCC')),
+            ('2.4.3 (truncation, ) \n[GCC]',
+             ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
+            ('2.4.3 (truncation,) \n[GCC]',
+             ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
+            ('2.4.3 (truncation) \n[GCC]',
+             ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
             ):
             # branch and revision are not "parsed", but fetched
             # from sys._mercurial.  Ignore them
@@ -333,16 +349,14 @@ class DeprecationTest(unittest.TestCase):
             platform.dist()
         self.assertEqual(str(cm.warning),
                          'dist() and linux_distribution() functions are '
-                         'deprecated in Python 3.5 and will be removed in '
-                         'Python 3.7')
+                         'deprecated in Python 3.5')
 
     def test_linux_distribution_deprecation(self):
         with self.assertWarns(PendingDeprecationWarning) as cm:
             platform.linux_distribution()
         self.assertEqual(str(cm.warning),
                          'dist() and linux_distribution() functions are '
-                         'deprecated in Python 3.5 and will be removed in '
-                         'Python 3.7')
+                         'deprecated in Python 3.5')
 
 if __name__ == '__main__':
     unittest.main()
index fef9f39..16114f9 100644 (file)
@@ -428,6 +428,15 @@ class TestPlistlib(unittest.TestCase):
                 b'\x00\x00\x00\x00\x00\x00\x00\x13')
         self.assertEqual(plistlib.loads(data), {'a': 'b'})
 
+    def test_large_timestamp(self):
+        # Issue #26709: 32-bit timestamp out of range
+        for ts in -2**31-1, 2**31:
+            with self.subTest(ts=ts):
+                d = (datetime.datetime.utcfromtimestamp(0) +
+                     datetime.timedelta(seconds=ts))
+                data = plistlib.dumps(d, fmt=plistlib.FMT_BINARY)
+                self.assertEqual(plistlib.loads(data), d)
+
 
 class TestPlistlibDeprecated(unittest.TestCase):
     def test_io_deprecated(self):
@@ -506,15 +515,15 @@ class TestPlistlibDeprecated(unittest.TestCase):
 
         cur = plistlib.loads(buf)
         self.assertEqual(cur, out_data)
-        self.assertNotEqual(cur, in_data)
+        self.assertEqual(cur, in_data)
 
         cur = plistlib.loads(buf, use_builtin_types=False)
-        self.assertNotEqual(cur, out_data)
+        self.assertEqual(cur, out_data)
         self.assertEqual(cur, in_data)
 
         with self.assertWarns(DeprecationWarning):
             cur = plistlib.readPlistFromBytes(buf)
-        self.assertNotEqual(cur, out_data)
+        self.assertEqual(cur, out_data)
         self.assertEqual(cur, in_data)
 
 
index 9d20471..acf1102 100644 (file)
@@ -216,6 +216,13 @@ class PosixPathTest(unittest.TestCase):
     def test_expanduser(self):
         self.assertEqual(posixpath.expanduser("foo"), "foo")
         self.assertEqual(posixpath.expanduser(b"foo"), b"foo")
+        with support.EnvironmentVarGuard() as env:
+            for home in '/', '', '//', '///':
+                with self.subTest(home=home):
+                    env['HOME'] = home
+                    self.assertEqual(posixpath.expanduser("~"), "/")
+                    self.assertEqual(posixpath.expanduser("~/"), "/")
+                    self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
         try:
             import pwd
         except ImportError:
@@ -239,14 +246,12 @@ class PosixPathTest(unittest.TestCase):
             self.assertIsInstance(posixpath.expanduser(b"~foo/"), bytes)
 
             with support.EnvironmentVarGuard() as env:
-                env['HOME'] = '/'
-                self.assertEqual(posixpath.expanduser("~"), "/")
-                self.assertEqual(posixpath.expanduser("~/foo"), "/foo")
                 # expanduser should fall back to using the password database
                 del env['HOME']
                 home = pwd.getpwuid(os.getuid()).pw_dir
                 # $HOME can end with a trailing /, so strip it (see #17809)
-                self.assertEqual(posixpath.expanduser("~"), home.rstrip("/"))
+                home = home.rstrip("/") or '/'
+                self.assertEqual(posixpath.expanduser("~"), home)
 
     def test_normpath(self):
         self.assertEqual(posixpath.normpath(""), ".")
index 5addd36..26b7d52 100644 (file)
@@ -76,13 +76,6 @@ class PropertyNewGetter(object):
         """new docstring"""
         return 8
 
-class PropertyWritableDoc(object):
-
-    @property
-    def spam(self):
-        """Eggs"""
-        return "eggs"
-
 class PropertyTests(unittest.TestCase):
     def test_property_decorator_baseclass(self):
         # see #1620
@@ -168,6 +161,13 @@ class PropertyTests(unittest.TestCase):
     @unittest.skipIf(sys.flags.optimize >= 2,
                      "Docstrings are omitted with -O2 and above")
     def test_property_decorator_doc_writable(self):
+        class PropertyWritableDoc(object):
+
+            @property
+            def spam(self):
+                """Eggs"""
+                return "eggs"
+
         sub = PropertyWritableDoc()
         self.assertEqual(sub.__class__.spam.__doc__, 'Eggs')
         sub.__class__.spam.__doc__ = 'Spam'
index cab430b..6ffbbbd 100644 (file)
@@ -5,7 +5,7 @@
 import sys
 from types import FunctionType, MethodType, BuiltinFunctionType
 import pyclbr
-from unittest import TestCase
+from unittest import TestCase, main as unittest_main
 
 StaticMethodType = type(staticmethod(lambda: None))
 ClassMethodType = type(classmethod(lambda c: None))
@@ -173,4 +173,4 @@ class PyclbrTest(TestCase):
 
 
 if __name__ == "__main__":
-    unittest.main()
+    unittest_main()
index 8ad5706..59aa715 100644 (file)
@@ -18,6 +18,7 @@ import types
 import unittest
 import urllib.parse
 import xml.etree
+import xml.etree.ElementTree
 import textwrap
 from io import StringIO
 from collections import namedtuple
@@ -352,6 +353,14 @@ def get_pydoc_html(module):
         loc = "<br><a href=\"" + loc + "\">Module Docs</a>"
     return output.strip(), loc
 
+def get_pydoc_link(module):
+    "Returns a documentation web link of a module"
+    dirname = os.path.dirname
+    basedir = os.path.join(dirname(dirname(__file__)))
+    doc = pydoc.TextDoc()
+    loc = doc.getdocloc(module, basedir=basedir)
+    return loc
+
 def get_pydoc_text(module):
     "Returns pydoc generated output as text"
     doc = pydoc.TextDoc()
@@ -443,6 +452,11 @@ class PydocDocTest(unittest.TestCase):
         doc = pydoc.render_doc(BinaryInteger)
         self.assertIn('<BinaryInteger.zero: 0>', doc)
 
+    def test_mixed_case_module_names_are_lower_cased(self):
+        # issue16484
+        doc_link = get_pydoc_link(xml.etree.ElementTree)
+        self.assertIn('xml.etree.elementtree', doc_link)
+
     def test_issue8225(self):
         # Test issue8225 to ensure no doc link appears for xml.etree
         result, doc_loc = get_pydoc_text(xml.etree)
@@ -734,7 +748,7 @@ class PydocImportTest(PydocBaseTest):
             finally:
                 sys.path[:] = saved_paths
 
-    @unittest.skip('causes undesireable side-effects (#20128)')
+    @unittest.skip('causes undesirable side-effects (#20128)')
     def test_modules(self):
         # See Helper.listmodules().
         num_header_lines = 2
@@ -750,7 +764,7 @@ class PydocImportTest(PydocBaseTest):
 
         self.assertGreaterEqual(num_lines, expected)
 
-    @unittest.skip('causes undesireable side-effects (#20128)')
+    @unittest.skip('causes undesirable side-effects (#20128)')
     def test_modules_search(self):
         # See Helper.listmodules().
         expected = 'pydoc - '
index 550aebf..0b68bfa 100644 (file)
@@ -42,12 +42,6 @@ class SetAttributeTest(unittest.TestCase):
             self.parser.specified_attributes = x
             self.assertIs(self.parser.specified_attributes, bool(x))
 
-    def test_specified_attributes(self):
-        self.assertIs(self.parser.specified_attributes, False)
-        for x in 0, 1, 2, 0:
-            self.parser.specified_attributes = x
-            self.assertIs(self.parser.specified_attributes, bool(x))
-
     def test_invalid_attributes(self):
         with self.assertRaises(AttributeError):
             self.parser.returns_unicode = 1
index 4b5232f..5393431 100644 (file)
@@ -494,7 +494,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
             self.assertTrue(2**k > n > 2**(k-1))   # note the stronger assertion
 
     @unittest.mock.patch('random.Random.random')
-    def test_randbelow_overriden_random(self, random_mock):
+    def test_randbelow_overridden_random(self, random_mock):
         # Random._randbelow() can only use random() when the built-in one
         # has been overridden but no new getrandbits() method was supplied.
         random_mock.side_effect = random.SystemRandom().random
index a51c4d7..4bf9194 100644 (file)
@@ -374,6 +374,13 @@ class MyContainer2(MyContainer):
     def __repr__(self):
         return '<' + ', '.join(map(str, self.values)) + '>'
 
+class MyContainer3:
+    def __repr__(self):
+        'Test document content'
+        pass
+    wrapped = __repr__
+    wrapper = recursive_repr()(wrapped)
+
 class TestRecursiveRepr(unittest.TestCase):
     def test_recursive_repr(self):
         m = MyContainer(list('abcde'))
@@ -387,5 +394,12 @@ class TestRecursiveRepr(unittest.TestCase):
         m.append(m)
         self.assertEqual(repr(m), '<a, b, c, d, e, +++, x, +++>')
 
+    def test_assigned_attributes(self):
+        from functools import WRAPPER_ASSIGNMENTS as assigned
+        wrapped = MyContainer3.wrapped
+        wrapper = MyContainer3.wrapper
+        for name in assigned:
+            self.assertIs(getattr(wrapper, name), getattr(wrapped, name))
+
 if __name__ == "__main__":
     unittest.main()
index 2022ed6..853e773 100644 (file)
@@ -1,4 +1,5 @@
 import unittest
+import unittest.mock
 import builtins
 import rlcompleter
 
@@ -77,6 +78,7 @@ class TestRlcompleter(unittest.TestCase):
         self.assertEqual(completer.complete('f.b', 0), 'f.bar')
         self.assertEqual(f.calls, 1)
 
+    @unittest.mock.patch('rlcompleter._readline_available', False)
     def test_complete(self):
         completer = rlcompleter.Completer()
         self.assertEqual(completer.complete('', 0), '\t')
@@ -85,5 +87,26 @@ class TestRlcompleter(unittest.TestCase):
         self.assertEqual(completer.complete('as', 2), 'assert')
         self.assertEqual(completer.complete('an', 0), 'and')
 
+    def test_duplicate_globals(self):
+        namespace = {
+            'False': None,  # Keyword vs builtin vs namespace
+            'assert': None,  # Keyword vs namespace
+            'try': lambda: None,  # Keyword vs callable
+            'memoryview': None,  # Callable builtin vs non-callable
+            'Ellipsis': lambda: None,  # Non-callable builtin vs callable
+        }
+        completer = rlcompleter.Completer(namespace)
+        self.assertEqual(completer.complete('False', 0), 'False')
+        self.assertIsNone(completer.complete('False', 1))  # No duplicates
+        self.assertEqual(completer.complete('assert', 0), 'assert')
+        self.assertIsNone(completer.complete('assert', 1))
+        self.assertEqual(completer.complete('try', 0), 'try')
+        self.assertIsNone(completer.complete('try', 1))
+        # No opening bracket "(" because we overrode the built-in class
+        self.assertEqual(completer.complete('memoryview', 0), 'memoryview')
+        self.assertIsNone(completer.complete('memoryview', 1))
+        self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(')
+        self.assertIsNone(completer.complete('Ellipsis', 1))
+
 if __name__ == '__main__':
     unittest.main()
index 4bae949..87c83ec 100644 (file)
@@ -197,8 +197,11 @@ class RunModuleTestCase(unittest.TestCase, CodeExecutionMixin):
         self.expect_import_error("sys.imp.eric")
         self.expect_import_error("os.path.half")
         self.expect_import_error("a.bee")
+        # Relative names not allowed
         self.expect_import_error(".howard")
         self.expect_import_error("..eaten")
+        self.expect_import_error(".test_runpy")
+        self.expect_import_error(".unittest")
         # Package without __main__.py
         self.expect_import_error("multiprocessing")
 
@@ -439,6 +442,34 @@ from ..uncle.cousin import nephew
             if verbose > 1: print("Testing package depth:", depth)
             self._check_package(depth)
 
+    def test_run_package_init_exceptions(self):
+        # These were previously wrapped in an ImportError; see Issue 14285
+        result = self._make_pkg("", 1, "__main__")
+        pkg_dir, _, mod_name, _ = result
+        mod_name = mod_name.replace(".__main__", "")
+        self.addCleanup(self._del_pkg, pkg_dir, 1, mod_name)
+        init = os.path.join(pkg_dir, "__runpy_pkg__", "__init__.py")
+
+        exceptions = (ImportError, AttributeError, TypeError, ValueError)
+        for exception in exceptions:
+            name = exception.__name__
+            with self.subTest(name):
+                source = "raise {0}('{0} in __init__.py.')".format(name)
+                with open(init, "wt", encoding="ascii") as mod_file:
+                    mod_file.write(source)
+                try:
+                    run_module(mod_name)
+                except exception as err:
+                    self.assertNotIn("finding spec", format(err))
+                else:
+                    self.fail("Nothing raised; expected {}".format(name))
+                try:
+                    run_module(mod_name + ".submodule")
+                except exception as err:
+                    self.assertNotIn("finding spec", format(err))
+                else:
+                    self.fail("Nothing raised; expected {}".format(name))
+
     def test_run_package_in_namespace_package(self):
         for depth in range(1, 4):
             if verbose > 1: print("Testing package depth:", depth)
index 54de508..1a49edf 100644 (file)
@@ -362,6 +362,9 @@ class TestJointOps:
         gc.collect()
         self.assertTrue(ref() is None, "Cycle was not collected")
 
+    def test_free_after_iterating(self):
+        support.check_free_after_iterating(self, iter, self.thetype)
+
 class TestSet(TestJointOps, unittest.TestCase):
     thetype = set
     basetype = set
@@ -1833,7 +1836,7 @@ class TestGraphs(unittest.TestCase):
 
         # http://en.wikipedia.org/wiki/Cuboctahedron
         # 8 triangular faces and 6 square faces
-        # 12 indentical vertices each connecting a triangle and square
+        # 12 identical vertices each connecting a triangle and square
 
         g = cube(3)
         cuboctahedron = linegraph(g)            # V( --> {V1, V2, V3, V4}
index 62036dd..13b30b9 100644 (file)
@@ -1105,6 +1105,29 @@ class TestShutil(unittest.TestCase):
             names2 = zf.namelist()
         self.assertEqual(sorted(names), sorted(names2))
 
+    @requires_zlib
+    @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
+    @unittest.skipUnless(shutil.which('unzip'),
+                         'Need the unzip command to run')
+    def test_unzip_zipfile(self):
+        root_dir, base_dir = self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
+        archive = make_archive(base_name, 'zip', root_dir, base_dir)
+
+        # check if ZIP file  was created
+        self.assertEqual(archive, base_name + '.zip')
+        self.assertTrue(os.path.isfile(archive))
+
+        # now check the ZIP file using `unzip -t`
+        zip_cmd = ['unzip', '-t', archive]
+        with support.change_cwd(root_dir):
+            try:
+                subprocess.check_output(zip_cmd, stderr=subprocess.STDOUT)
+            except subprocess.CalledProcessError as exc:
+                details = exc.output.decode(errors="replace")
+                msg = "{}\n\n**Unzip Output**\n{}"
+                self.fail(msg.format(exc, details))
+
     def test_make_archive(self):
         tmpdir = self.mkdtemp()
         base_name = os.path.join(tmpdir, 'archive')
@@ -1805,15 +1828,27 @@ class TermsizeTests(unittest.TestCase):
 
         with support.EnvironmentVarGuard() as env:
             env['COLUMNS'] = '777'
+            del env['LINES']
             size = shutil.get_terminal_size()
         self.assertEqual(size.columns, 777)
 
         with support.EnvironmentVarGuard() as env:
+            del env['COLUMNS']
             env['LINES'] = '888'
             size = shutil.get_terminal_size()
         self.assertEqual(size.lines, 888)
 
+    def test_bad_environ(self):
+        with support.EnvironmentVarGuard() as env:
+            env['COLUMNS'] = 'xxx'
+            env['LINES'] = 'yyy'
+            size = shutil.get_terminal_size()
+        self.assertGreaterEqual(size.columns, 0)
+        self.assertGreaterEqual(size.lines, 0)
+
     @unittest.skipUnless(os.isatty(sys.__stdout__.fileno()), "not on tty")
+    @unittest.skipUnless(hasattr(os, 'get_terminal_size'),
+                         'need os.get_terminal_size()')
     def test_stty_match(self):
         """Check if stty returns the same results ignoring env
 
@@ -1834,6 +1869,25 @@ class TermsizeTests(unittest.TestCase):
 
         self.assertEqual(expected, actual)
 
+    def test_fallback(self):
+        with support.EnvironmentVarGuard() as env:
+            del env['LINES']
+            del env['COLUMNS']
+
+            # sys.__stdout__ has no fileno()
+            with support.swap_attr(sys, '__stdout__', None):
+                size = shutil.get_terminal_size(fallback=(10, 20))
+            self.assertEqual(size.columns, 10)
+            self.assertEqual(size.lines, 20)
+
+            # sys.__stdout__ is not a terminal on Unix
+            # or fileno() not in (0, 1, 2) on Windows
+            with open(os.devnull, 'w') as f, \
+                 support.swap_attr(sys, '__stdout__', f):
+                size = shutil.get_terminal_size(fallback=(30, 40))
+            self.assertEqual(size.columns, 30)
+            self.assertEqual(size.lines, 40)
+
 
 class PublicAPITests(unittest.TestCase):
     """Ensures that the correct values are exposed in the public API."""
index 6615080..da20a3d 100644 (file)
@@ -28,8 +28,13 @@ import site
 
 if site.ENABLE_USER_SITE and not os.path.isdir(site.USER_SITE):
     # need to add user site directory for tests
-    os.makedirs(site.USER_SITE)
-    site.addsitedir(site.USER_SITE)
+    try:
+        os.makedirs(site.USER_SITE)
+        site.addsitedir(site.USER_SITE)
+    except PermissionError as exc:
+        raise unittest.SkipTest('unable to create user site directory (%r): %s'
+                                % (site.USER_SITE, exc))
+
 
 class HelperFunctionsTests(unittest.TestCase):
     """Tests for helper functions.
index 8c4e670..4ae4142 100644 (file)
@@ -1,11 +1,13 @@
 # tests for slice objects; in particular the indices method.
 
-import unittest
-from pickle import loads, dumps
-
 import itertools
 import operator
 import sys
+import unittest
+import weakref
+
+from pickle import loads, dumps
+from test import support
 
 
 def evaluate_slice_index(arg):
@@ -240,5 +242,14 @@ class SliceTest(unittest.TestCase):
             self.assertEqual(s.indices(15), t.indices(15))
             self.assertNotEqual(id(s), id(t))
 
+    def test_cycle(self):
+        class myobj(): pass
+        o = myobj()
+        o.s = slice(o)
+        w = weakref.ref(o)
+        o = None
+        support.gc_collect()
+        self.assertIsNone(w())
+
 if __name__ == "__main__":
     unittest.main()
index 1e355ea..c151a50 100644 (file)
@@ -199,7 +199,7 @@ class ThreadableTest:
         clientTearDown ()
 
     Any new test functions within the class must then define
-    tests in pairs, where the test name is preceeded with a
+    tests in pairs, where the test name is preceded with a
     '_' to indicate the client portion of the test. Ex:
 
         def testFoo(self):
@@ -1304,7 +1304,7 @@ class GeneralModuleTests(unittest.TestCase):
         # socket.gethostbyaddr('испытание.python.org')
 
     def check_sendall_interrupted(self, with_timeout):
-        # socketpair() is not stricly required, but it makes things easier.
+        # socketpair() is not strictly required, but it makes things easier.
         if not hasattr(signal, 'alarm') or not hasattr(socket, 'socketpair'):
             self.skipTest("signal.alarm and socket.socketpair required for this test")
         # Our signal handlers clobber the C errno by calling a math function
@@ -1374,6 +1374,20 @@ class GeneralModuleTests(unittest.TestCase):
             self.assertRaises(ValueError, fp.writable)
             self.assertRaises(ValueError, fp.seekable)
 
+    def test_makefile_mode(self):
+        for mode in 'r', 'rb', 'rw', 'w', 'wb':
+            with self.subTest(mode=mode):
+                with socket.socket() as sock:
+                    with sock.makefile(mode) as fp:
+                        self.assertEqual(fp.mode, mode)
+
+    def test_makefile_invalid_mode(self):
+        for mode in 'rt', 'x', '+', 'a':
+            with self.subTest(mode=mode):
+                with socket.socket() as sock:
+                    with self.assertRaisesRegex(ValueError, 'invalid mode'):
+                        sock.makefile(mode)
+
     def test_pickle(self):
         sock = socket.socket()
         with sock:
@@ -4733,7 +4747,7 @@ class TIPCThreadableTest(unittest.TestCase, ThreadableTest):
         self.addCleanup(self.conn.close)
 
     def clientSetUp(self):
-        # The is a hittable race between serverExplicitReady() and the
+        # There is a hittable race between serverExplicitReady() and the
         # accept() call; sleep a little while to avoid it, otherwise
         # we could get an exception
         time.sleep(0.1)
@@ -4974,7 +4988,7 @@ class TestSocketSharing(SocketTCPTest):
 
     def compareSockets(self, org, other):
         # socket sharing is expected to work only for blocking socket
-        # since the internal python timout value isn't transfered.
+        # since the internal python timeout value isn't transferred.
         self.assertEqual(org.gettimeout(), None)
         self.assertEqual(org.gettimeout(), other.gettimeout())
 
index 1ea66a6..0d0f86f 100644 (file)
@@ -160,6 +160,8 @@ class SocketServerTest(unittest.TestCase):
 
     def dgram_examine(self, proto, addr):
         s = socket.socket(proto, socket.SOCK_DGRAM)
+        if HAVE_UNIX_SOCKETS and proto == socket.AF_UNIX:
+            s.bind(self.pickaddr(proto))
         s.sendto(TEST_STR, addr)
         buf = data = receive(s, 100)
         while data and b'\n' not in buf:
@@ -222,27 +224,24 @@ class SocketServerTest(unittest.TestCase):
                             socketserver.DatagramRequestHandler,
                             self.dgram_examine)
 
-    # Alas, on Linux (at least) recvfrom() doesn't return a meaningful
-    # client address so this cannot work:
-
-    # @requires_unix_sockets
-    # def test_UnixDatagramServer(self):
-    #     self.run_server(socketserver.UnixDatagramServer,
-    #                     socketserver.DatagramRequestHandler,
-    #                     self.dgram_examine)
-    #
-    # @requires_unix_sockets
-    # def test_ThreadingUnixDatagramServer(self):
-    #     self.run_server(socketserver.ThreadingUnixDatagramServer,
-    #                     socketserver.DatagramRequestHandler,
-    #                     self.dgram_examine)
-    #
-    # @requires_unix_sockets
-    # @requires_forking
-    # def test_ForkingUnixDatagramServer(self):
-    #     self.run_server(socketserver.ForkingUnixDatagramServer,
-    #                     socketserver.DatagramRequestHandler,
-    #                     self.dgram_examine)
+    @requires_unix_sockets
+    def test_UnixDatagramServer(self):
+        self.run_server(socketserver.UnixDatagramServer,
+                        socketserver.DatagramRequestHandler,
+                        self.dgram_examine)
+
+    @requires_unix_sockets
+    def test_ThreadingUnixDatagramServer(self):
+        self.run_server(socketserver.ThreadingUnixDatagramServer,
+                        socketserver.DatagramRequestHandler,
+                        self.dgram_examine)
+
+    @requires_unix_sockets
+    @requires_forking
+    def test_ForkingUnixDatagramServer(self):
+        self.run_server(ForkingUnixDatagramServer,
+                        socketserver.DatagramRequestHandler,
+                        self.dgram_examine)
 
     @reap_threads
     def test_shutdown(self):
@@ -293,6 +292,27 @@ class MiscTestCase(unittest.TestCase):
                     expected.append(name)
         self.assertCountEqual(socketserver.__all__, expected)
 
+    def test_shutdown_request_called_if_verify_request_false(self):
+        # Issue #26309: BaseServer should call shutdown_request even if
+        # verify_request is False
+
+        class MyServer(socketserver.TCPServer):
+            def verify_request(self, request, client_address):
+                return False
+
+            shutdown_called = 0
+            def shutdown_request(self, request):
+                self.shutdown_called += 1
+                socketserver.TCPServer.shutdown_request(self, request)
+
+        server = MyServer((HOST, 0), socketserver.StreamRequestHandler)
+        s = socket.socket(server.address_family, socket.SOCK_STREAM)
+        s.connect(server.server_address)
+        s.close()
+        server.handle_request()
+        self.assertEqual(server.shutdown_called, 1)
+        server.server_close()
+
 
 if __name__ == "__main__":
     unittest.main()
index 39a7c56..3873400 100644 (file)
@@ -1,13 +1,14 @@
 # -*- coding: koi8-r -*-
 
 import unittest
-from test.support import TESTFN, unlink, unload, rmtree
+from test.support import TESTFN, unlink, unload, rmtree, script_helper, captured_stdout
 import importlib
 import os
 import sys
 import subprocess
+import tempfile
 
-class SourceEncodingTest(unittest.TestCase):
+class MiscSourceEncodingTest(unittest.TestCase):
 
     def test_pep263(self):
         self.assertEqual(
@@ -142,5 +143,83 @@ class SourceEncodingTest(unittest.TestCase):
                         msg=c.exception.args[0])
 
 
+class AbstractSourceEncodingTest:
+
+    def test_default_coding(self):
+        src = (b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xe4'")
+
+    def test_first_coding_line(self):
+        src = (b'#coding:iso8859-15\n'
+               b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xc3\u20ac'")
+
+    def test_second_coding_line(self):
+        src = (b'#\n'
+               b'#coding:iso8859-15\n'
+               b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xc3\u20ac'")
+
+    def test_third_coding_line(self):
+        # Only first two lines are tested for a magic comment.
+        src = (b'#\n'
+               b'#\n'
+               b'#coding:iso8859-15\n'
+               b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xe4'")
+
+    def test_double_coding_line(self):
+        # If the first line matches the second line is ignored.
+        src = (b'#coding:iso8859-15\n'
+               b'#coding:latin1\n'
+               b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xc3\u20ac'")
+
+    def test_double_coding_same_line(self):
+        src = (b'#coding:iso8859-15 coding:latin1\n'
+               b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xc3\u20ac'")
+
+    def test_first_non_utf8_coding_line(self):
+        src = (b'#coding:iso-8859-15 \xa4\n'
+               b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xc3\u20ac'")
+
+    def test_second_non_utf8_coding_line(self):
+        src = (b'\n'
+               b'#coding:iso-8859-15 \xa4\n'
+               b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xc3\u20ac'")
+
+    def test_utf8_bom(self):
+        src = (b'\xef\xbb\xbfprint(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xe4'")
+
+    def test_utf8_bom_and_utf8_coding_line(self):
+        src = (b'\xef\xbb\xbf#coding:utf-8\n'
+               b'print(ascii("\xc3\xa4"))\n')
+        self.check_script_output(src, br"'\xe4'")
+
+
+class BytesSourceEncodingTest(AbstractSourceEncodingTest, unittest.TestCase):
+
+    def check_script_output(self, src, expected):
+        with captured_stdout() as stdout:
+            exec(src)
+        out = stdout.getvalue().encode('latin1')
+        self.assertEqual(out.rstrip(), expected)
+
+
+class FileSourceEncodingTest(AbstractSourceEncodingTest, unittest.TestCase):
+
+    def check_script_output(self, src, expected):
+        with tempfile.TemporaryDirectory() as tmpd:
+            fn = os.path.join(tmpd, 'test.py')
+            with open(fn, 'wb') as fp:
+                fp.write(src)
+            res = script_helper.assert_python_ok(fn)
+        self.assertEqual(res.out.rstrip(), expected)
+
+
 if __name__ == "__main__":
     unittest.main()
index 548feeb..d2fc36d 100644 (file)
@@ -55,11 +55,12 @@ SIGNED_CERTFILE = data_file("keycert3.pem")
 SIGNED_CERTFILE2 = data_file("keycert4.pem")
 SIGNING_CA = data_file("pycacert.pem")
 
-SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
+REMOTE_HOST = "self-signed.pythontest.net"
+REMOTE_ROOT_CERT = data_file("selfsigned_pythontestdotnet.pem")
 
 EMPTYCERT = data_file("nullcert.pem")
 BADCERT = data_file("badcert.pem")
-WRONGCERT = data_file("XXXnonexisting.pem")
+NONEXISTINGCERT = data_file("XXXnonexisting.pem")
 BADKEY = data_file("badkey.pem")
 NOKIACERT = data_file("nokia.pem")
 NULLBYTECERT = data_file("nullbytecert.pem")
@@ -276,7 +277,7 @@ class BasicSocketTests(unittest.TestCase):
         self.assertEqual(p['subjectAltName'], san)
 
     def test_DER_to_PEM(self):
-        with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
+        with open(CAFILE_CACERT, 'r') as f:
             pem = f.read()
         d1 = ssl.PEM_cert_to_DER_cert(pem)
         p2 = ssl.DER_cert_to_PEM_cert(d1)
@@ -366,17 +367,42 @@ class BasicSocketTests(unittest.TestCase):
                                     s.connect, (HOST, 8080))
         with self.assertRaises(OSError) as cm:
             with socket.socket() as sock:
-                ssl.wrap_socket(sock, certfile=WRONGCERT)
+                ssl.wrap_socket(sock, certfile=NONEXISTINGCERT)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
         with self.assertRaises(OSError) as cm:
             with socket.socket() as sock:
-                ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
+                ssl.wrap_socket(sock,
+                    certfile=CERTFILE, keyfile=NONEXISTINGCERT)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
         with self.assertRaises(OSError) as cm:
             with socket.socket() as sock:
-                ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
+                ssl.wrap_socket(sock,
+                    certfile=NONEXISTINGCERT, keyfile=NONEXISTINGCERT)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
 
+    def bad_cert_test(self, certfile):
+        """Check that trying to use the given client certificate fails"""
+        certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
+                                   certfile)
+        sock = socket.socket()
+        self.addCleanup(sock.close)
+        with self.assertRaises(ssl.SSLError):
+            ssl.wrap_socket(sock,
+                            certfile=certfile,
+                            ssl_version=ssl.PROTOCOL_TLSv1)
+
+    def test_empty_cert(self):
+        """Wrapping with an empty cert file"""
+        self.bad_cert_test("nullcert.pem")
+
+    def test_malformed_cert(self):
+        """Wrapping with a badly formatted certificate (syntax error)"""
+        self.bad_cert_test("badcert.pem")
+
+    def test_malformed_key(self):
+        """Wrapping with a badly formatted key (syntax error)"""
+        self.bad_cert_test("badkey.pem")
+
     def test_match_hostname(self):
         def ok(cert, hostname):
             ssl.match_hostname(cert, hostname)
@@ -795,7 +821,8 @@ class ContextTests(unittest.TestCase):
             self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
                              ctx.options)
             ctx.options = 0
-            self.assertEqual(0, ctx.options)
+            # Ubuntu has OP_NO_SSLv3 forced on by default
+            self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
         else:
             with self.assertRaises(ValueError):
                 ctx.options = 0
@@ -842,7 +869,7 @@ class ContextTests(unittest.TestCase):
         ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
         self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
         with self.assertRaises(OSError) as cm:
-            ctx.load_cert_chain(WRONGCERT)
+            ctx.load_cert_chain(NONEXISTINGCERT)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
         with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
             ctx.load_cert_chain(BADCERT)
@@ -862,7 +889,7 @@ class ContextTests(unittest.TestCase):
         # Mismatching key and cert
         ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
         with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
-            ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
+            ctx.load_cert_chain(CAFILE_CACERT, ONLYKEY)
         # Password protected key and cert
         ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
         ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
@@ -927,7 +954,7 @@ class ContextTests(unittest.TestCase):
         self.assertRaises(TypeError, ctx.load_verify_locations)
         self.assertRaises(TypeError, ctx.load_verify_locations, None, None, None)
         with self.assertRaises(OSError) as cm:
-            ctx.load_verify_locations(WRONGCERT)
+            ctx.load_verify_locations(NONEXISTINGCERT)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
         with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
             ctx.load_verify_locations(BADCERT)
@@ -1003,7 +1030,7 @@ class ContextTests(unittest.TestCase):
         self.assertRaises(TypeError, ctx.load_dh_params)
         self.assertRaises(TypeError, ctx.load_dh_params, None)
         with self.assertRaises(FileNotFoundError) as cm:
-            ctx.load_dh_params(WRONGCERT)
+            ctx.load_dh_params(NONEXISTINGCERT)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
         with self.assertRaises(ssl.SSLError) as cm:
             ctx.load_dh_params(CERTFILE)
@@ -1080,7 +1107,7 @@ class ContextTests(unittest.TestCase):
         ctx.load_verify_locations(CERTFILE)
         self.assertEqual(ctx.cert_store_stats(),
             {'x509_ca': 0, 'crl': 0, 'x509': 1})
-        ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
+        ctx.load_verify_locations(CAFILE_CACERT)
         self.assertEqual(ctx.cert_store_stats(),
             {'x509_ca': 1, 'crl': 0, 'x509': 2})
 
@@ -1090,8 +1117,8 @@ class ContextTests(unittest.TestCase):
         # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
         ctx.load_verify_locations(CERTFILE)
         self.assertEqual(ctx.get_ca_certs(), [])
-        # but SVN_PYTHON_ORG_ROOT_CERT is a CA cert
-        ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
+        # but CAFILE_CACERT is a CA cert
+        ctx.load_verify_locations(CAFILE_CACERT)
         self.assertEqual(ctx.get_ca_certs(),
             [{'issuer': ((('organizationName', 'Root CA'),),
                          (('organizationalUnitName', 'http://www.cacert.org'),),
@@ -1107,7 +1134,7 @@ class ContextTests(unittest.TestCase):
                           (('emailAddress', 'support@cacert.org'),)),
               'version': 3}])
 
-        with open(SVN_PYTHON_ORG_ROOT_CERT) as f:
+        with open(CAFILE_CACERT) as f:
             pem = f.read()
         der = ssl.PEM_cert_to_DER_cert(pem)
         self.assertEqual(ctx.get_ca_certs(True), [der])
@@ -1345,11 +1372,11 @@ class MemoryBIOTests(unittest.TestCase):
 class NetworkedTests(unittest.TestCase):
 
     def test_connect(self):
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             s = ssl.wrap_socket(socket.socket(socket.AF_INET),
                                 cert_reqs=ssl.CERT_NONE)
             try:
-                s.connect(("svn.python.org", 443))
+                s.connect((REMOTE_HOST, 443))
                 self.assertEqual({}, s.getpeercert())
             finally:
                 s.close()
@@ -1358,27 +1385,27 @@ class NetworkedTests(unittest.TestCase):
             s = ssl.wrap_socket(socket.socket(socket.AF_INET),
                                 cert_reqs=ssl.CERT_REQUIRED)
             self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
-                                   s.connect, ("svn.python.org", 443))
+                                   s.connect, (REMOTE_HOST, 443))
             s.close()
 
             # this should succeed because we specify the root cert
             s = ssl.wrap_socket(socket.socket(socket.AF_INET),
                                 cert_reqs=ssl.CERT_REQUIRED,
-                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+                                ca_certs=REMOTE_ROOT_CERT)
             try:
-                s.connect(("svn.python.org", 443))
+                s.connect((REMOTE_HOST, 443))
                 self.assertTrue(s.getpeercert())
             finally:
                 s.close()
 
     def test_connect_ex(self):
         # Issue #11326: check connect_ex() implementation
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             s = ssl.wrap_socket(socket.socket(socket.AF_INET),
                                 cert_reqs=ssl.CERT_REQUIRED,
-                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+                                ca_certs=REMOTE_ROOT_CERT)
             try:
-                self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
+                self.assertEqual(0, s.connect_ex((REMOTE_HOST, 443)))
                 self.assertTrue(s.getpeercert())
             finally:
                 s.close()
@@ -1386,14 +1413,14 @@ class NetworkedTests(unittest.TestCase):
     def test_non_blocking_connect_ex(self):
         # Issue #11326: non-blocking connect_ex() should allow handshake
         # to proceed after the socket gets ready.
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             s = ssl.wrap_socket(socket.socket(socket.AF_INET),
                                 cert_reqs=ssl.CERT_REQUIRED,
-                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
+                                ca_certs=REMOTE_ROOT_CERT,
                                 do_handshake_on_connect=False)
             try:
                 s.setblocking(False)
-                rc = s.connect_ex(('svn.python.org', 443))
+                rc = s.connect_ex((REMOTE_HOST, 443))
                 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
                 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
                 # Wait for connect to finish
@@ -1415,58 +1442,62 @@ class NetworkedTests(unittest.TestCase):
     def test_timeout_connect_ex(self):
         # Issue #12065: on a timeout, connect_ex() should return the original
         # errno (mimicking the behaviour of non-SSL sockets).
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             s = ssl.wrap_socket(socket.socket(socket.AF_INET),
                                 cert_reqs=ssl.CERT_REQUIRED,
-                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
+                                ca_certs=REMOTE_ROOT_CERT,
                                 do_handshake_on_connect=False)
             try:
                 s.settimeout(0.0000001)
-                rc = s.connect_ex(('svn.python.org', 443))
+                rc = s.connect_ex((REMOTE_HOST, 443))
                 if rc == 0:
-                    self.skipTest("svn.python.org responded too quickly")
+                    self.skipTest("REMOTE_HOST responded too quickly")
                 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
             finally:
                 s.close()
 
     def test_connect_ex_error(self):
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             s = ssl.wrap_socket(socket.socket(socket.AF_INET),
                                 cert_reqs=ssl.CERT_REQUIRED,
-                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+                                ca_certs=REMOTE_ROOT_CERT)
             try:
-                rc = s.connect_ex(("svn.python.org", 444))
+                rc = s.connect_ex((REMOTE_HOST, 444))
                 # Issue #19919: Windows machines or VMs hosted on Windows
                 # machines sometimes return EWOULDBLOCK.
-                self.assertIn(rc, (errno.ECONNREFUSED, errno.EWOULDBLOCK))
+                errors = (
+                    errno.ECONNREFUSED, errno.EHOSTUNREACH, errno.ETIMEDOUT,
+                    errno.EWOULDBLOCK,
+                )
+                self.assertIn(rc, errors)
             finally:
                 s.close()
 
     def test_connect_with_context(self):
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             # Same as test_connect, but with a separately created context
             ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
             s = ctx.wrap_socket(socket.socket(socket.AF_INET))
-            s.connect(("svn.python.org", 443))
+            s.connect((REMOTE_HOST, 443))
             try:
                 self.assertEqual({}, s.getpeercert())
             finally:
                 s.close()
             # Same with a server hostname
             s = ctx.wrap_socket(socket.socket(socket.AF_INET),
-                                server_hostname="svn.python.org")
-            s.connect(("svn.python.org", 443))
+                                server_hostname=REMOTE_HOST)
+            s.connect((REMOTE_HOST, 443))
             s.close()
             # This should fail because we have no verification certs
             ctx.verify_mode = ssl.CERT_REQUIRED
             s = ctx.wrap_socket(socket.socket(socket.AF_INET))
             self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
-                                    s.connect, ("svn.python.org", 443))
+                                    s.connect, (REMOTE_HOST, 443))
             s.close()
             # This should succeed because we specify the root cert
-            ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
+            ctx.load_verify_locations(REMOTE_ROOT_CERT)
             s = ctx.wrap_socket(socket.socket(socket.AF_INET))
-            s.connect(("svn.python.org", 443))
+            s.connect((REMOTE_HOST, 443))
             try:
                 cert = s.getpeercert()
                 self.assertTrue(cert)
@@ -1479,12 +1510,12 @@ class NetworkedTests(unittest.TestCase):
         # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
         # contain both versions of each certificate (same content, different
         # filename) for this test to be portable across OpenSSL releases.
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
             ctx.verify_mode = ssl.CERT_REQUIRED
             ctx.load_verify_locations(capath=CAPATH)
             s = ctx.wrap_socket(socket.socket(socket.AF_INET))
-            s.connect(("svn.python.org", 443))
+            s.connect((REMOTE_HOST, 443))
             try:
                 cert = s.getpeercert()
                 self.assertTrue(cert)
@@ -1495,7 +1526,7 @@ class NetworkedTests(unittest.TestCase):
             ctx.verify_mode = ssl.CERT_REQUIRED
             ctx.load_verify_locations(capath=BYTES_CAPATH)
             s = ctx.wrap_socket(socket.socket(socket.AF_INET))
-            s.connect(("svn.python.org", 443))
+            s.connect((REMOTE_HOST, 443))
             try:
                 cert = s.getpeercert()
                 self.assertTrue(cert)
@@ -1503,15 +1534,15 @@ class NetworkedTests(unittest.TestCase):
                 s.close()
 
     def test_connect_cadata(self):
-        with open(CAFILE_CACERT) as f:
+        with open(REMOTE_ROOT_CERT) as f:
             pem = f.read()
         der = ssl.PEM_cert_to_DER_cert(pem)
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
             ctx.verify_mode = ssl.CERT_REQUIRED
             ctx.load_verify_locations(cadata=pem)
             with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
-                s.connect(("svn.python.org", 443))
+                s.connect((REMOTE_HOST, 443))
                 cert = s.getpeercert()
                 self.assertTrue(cert)
 
@@ -1520,7 +1551,7 @@ class NetworkedTests(unittest.TestCase):
             ctx.verify_mode = ssl.CERT_REQUIRED
             ctx.load_verify_locations(cadata=der)
             with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
-                s.connect(("svn.python.org", 443))
+                s.connect((REMOTE_HOST, 443))
                 cert = s.getpeercert()
                 self.assertTrue(cert)
 
@@ -1529,9 +1560,9 @@ class NetworkedTests(unittest.TestCase):
         # Issue #5238: creating a file-like object with makefile() shouldn't
         # delay closing the underlying "real socket" (here tested with its
         # file descriptor, hence skipping the test under Windows).
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
-            ss.connect(("svn.python.org", 443))
+            ss.connect((REMOTE_HOST, 443))
             fd = ss.fileno()
             f = ss.makefile()
             f.close()
@@ -1545,9 +1576,9 @@ class NetworkedTests(unittest.TestCase):
             self.assertEqual(e.exception.errno, errno.EBADF)
 
     def test_non_blocking_handshake(self):
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             s = socket.socket(socket.AF_INET)
-            s.connect(("svn.python.org", 443))
+            s.connect((REMOTE_HOST, 443))
             s.setblocking(False)
             s = ssl.wrap_socket(s,
                                 cert_reqs=ssl.CERT_NONE,
@@ -1590,12 +1621,12 @@ class NetworkedTests(unittest.TestCase):
                 if support.verbose:
                     sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
 
-        _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
+        _test_get_server_certificate(REMOTE_HOST, 443, REMOTE_ROOT_CERT)
         if support.IPV6_ENABLED:
             _test_get_server_certificate('ipv6.google.com', 443)
 
     def test_ciphers(self):
-        remote = ("svn.python.org", 443)
+        remote = (REMOTE_HOST, 443)
         with support.transient_internet(remote[0]):
             with ssl.wrap_socket(socket.socket(socket.AF_INET),
                                  cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
@@ -1640,13 +1671,13 @@ class NetworkedTests(unittest.TestCase):
 
     def test_get_ca_certs_capath(self):
         # capath certs are loaded on request
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
             ctx.verify_mode = ssl.CERT_REQUIRED
             ctx.load_verify_locations(capath=CAPATH)
             self.assertEqual(ctx.get_ca_certs(), [])
             s = ctx.wrap_socket(socket.socket(socket.AF_INET))
-            s.connect(("svn.python.org", 443))
+            s.connect((REMOTE_HOST, 443))
             try:
                 cert = s.getpeercert()
                 self.assertTrue(cert)
@@ -1657,12 +1688,12 @@ class NetworkedTests(unittest.TestCase):
     @needs_sni
     def test_context_setget(self):
         # Check that the context of a connected socket can be replaced.
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
             ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
             s = socket.socket(socket.AF_INET)
             with ctx1.wrap_socket(s) as ss:
-                ss.connect(("svn.python.org", 443))
+                ss.connect((REMOTE_HOST, 443))
                 self.assertIs(ss.context, ctx1)
                 self.assertIs(ss._sslobj.context, ctx1)
                 ss.context = ctx2
@@ -1683,13 +1714,8 @@ class NetworkedBIOTests(unittest.TestCase):
             try:
                 ret = func(*args)
             except ssl.SSLError as e:
-                # Note that we get a spurious -1/SSL_ERROR_SYSCALL for
-                # non-blocking IO. The SSL_shutdown manpage hints at this.
-                # It *should* be safe to just ignore SYS_ERROR_SYSCALL because
-                # with a Memory BIO there's no syscalls (for IO at least).
                 if e.errno not in (ssl.SSL_ERROR_WANT_READ,
-                                   ssl.SSL_ERROR_WANT_WRITE,
-                                   ssl.SSL_ERROR_SYSCALL):
+                                   ssl.SSL_ERROR_WANT_WRITE):
                     raise
                 errno = e.errno
             # Get any data from the outgoing BIO irrespective of any error, and
@@ -1712,16 +1738,16 @@ class NetworkedBIOTests(unittest.TestCase):
         return ret
 
     def test_handshake(self):
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             sock = socket.socket(socket.AF_INET)
-            sock.connect(("svn.python.org", 443))
+            sock.connect((REMOTE_HOST, 443))
             incoming = ssl.MemoryBIO()
             outgoing = ssl.MemoryBIO()
             ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
             ctx.verify_mode = ssl.CERT_REQUIRED
-            ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
+            ctx.load_verify_locations(REMOTE_ROOT_CERT)
             ctx.check_hostname = True
-            sslobj = ctx.wrap_bio(incoming, outgoing, False, 'svn.python.org')
+            sslobj = ctx.wrap_bio(incoming, outgoing, False, REMOTE_HOST)
             self.assertIs(sslobj._sslobj.owner, sslobj)
             self.assertIsNone(sslobj.cipher())
             self.assertIsNone(sslobj.shared_ciphers())
@@ -1734,14 +1760,20 @@ class NetworkedBIOTests(unittest.TestCase):
             self.assertTrue(sslobj.getpeercert())
             if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
                 self.assertTrue(sslobj.get_channel_binding('tls-unique'))
-            self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
+            try:
+                self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
+            except ssl.SSLSyscallError:
+                # self-signed.pythontest.net probably shuts down the TCP
+                # connection without sending a secure shutdown message, and
+                # this is reported as SSL_ERROR_SYSCALL
+                pass
             self.assertRaises(ssl.SSLError, sslobj.write, b'foo')
             sock.close()
 
     def test_read_write_data(self):
-        with support.transient_internet("svn.python.org"):
+        with support.transient_internet(REMOTE_HOST):
             sock = socket.socket(socket.AF_INET)
-            sock.connect(("svn.python.org", 443))
+            sock.connect((REMOTE_HOST, 443))
             incoming = ssl.MemoryBIO()
             outgoing = ssl.MemoryBIO()
             ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
@@ -2084,36 +2116,6 @@ else:
             self.active = False
             self.server.close()
 
-    def bad_cert_test(certfile):
-        """
-        Launch a server with CERT_REQUIRED, and check that trying to
-        connect to it with the given client certificate fails.
-        """
-        server = ThreadedEchoServer(CERTFILE,
-                                    certreqs=ssl.CERT_REQUIRED,
-                                    cacerts=CERTFILE, chatty=False,
-                                    connectionchatty=False)
-        with server:
-            try:
-                with socket.socket() as sock:
-                    s = ssl.wrap_socket(sock,
-                                        certfile=certfile,
-                                        ssl_version=ssl.PROTOCOL_TLSv1)
-                    s.connect((HOST, server.port))
-            except ssl.SSLError as x:
-                if support.verbose:
-                    sys.stdout.write("\nSSLError is %s\n" % x.args[1])
-            except OSError as x:
-                if support.verbose:
-                    sys.stdout.write("\nOSError is %s\n" % x.args[1])
-            except OSError as x:
-                if x.errno != errno.ENOENT:
-                    raise
-                if support.verbose:
-                    sys.stdout.write("\OSError is %s\n" % str(x))
-            else:
-                raise AssertionError("Use of invalid cert should have failed!")
-
     def server_params_test(client_context, server_context, indata=b"FOO\n",
                            chatty=True, connectionchatty=False, sni_name=None):
         """
@@ -2354,22 +2356,38 @@ else:
                                                 "check_hostname requires server_hostname"):
                         context.wrap_socket(s)
 
-        def test_empty_cert(self):
-            """Connecting with an empty cert file"""
-            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
-                                      "nullcert.pem"))
-        def test_malformed_cert(self):
-            """Connecting with a badly formatted certificate (syntax error)"""
-            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
-                                       "badcert.pem"))
-        def test_nonexisting_cert(self):
-            """Connecting with a non-existing cert file"""
-            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
-                                       "wrongcert.pem"))
-        def test_malformed_key(self):
-            """Connecting with a badly formatted key (syntax error)"""
-            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
-                                       "badkey.pem"))
+        def test_wrong_cert(self):
+            """Connecting when the server rejects the client's certificate
+
+            Launch a server with CERT_REQUIRED, and check that trying to
+            connect to it with a wrong client certificate fails.
+            """
+            certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
+                                       "wrongcert.pem")
+            server = ThreadedEchoServer(CERTFILE,
+                                        certreqs=ssl.CERT_REQUIRED,
+                                        cacerts=CERTFILE, chatty=False,
+                                        connectionchatty=False)
+            with server, \
+                    socket.socket() as sock, \
+                    ssl.wrap_socket(sock,
+                                        certfile=certfile,
+                                        ssl_version=ssl.PROTOCOL_TLSv1) as s:
+                try:
+                    # Expect either an SSL error about the server rejecting
+                    # the connection, or a low-level connection reset (which
+                    # sometimes happens on Windows)
+                    s.connect((HOST, server.port))
+                except ssl.SSLError as e:
+                    if support.verbose:
+                        sys.stdout.write("\nSSLError is %r\n" % e)
+                except OSError as e:
+                    if e.errno != errno.ECONNRESET:
+                        raise
+                    if support.verbose:
+                        sys.stdout.write("\nsocket.error is %r\n" % e)
+                else:
+                    self.fail("Use of invalid cert should have failed!")
 
         def test_rude_shutdown(self):
             """A brutal shutdown of an SSL server should raise an OSError
@@ -2775,6 +2793,20 @@ else:
                         # consume data
                         s.read()
 
+                data = b"data"
+
+                # read(-1, buffer) is supported, even though read(-1) is not
+                s.send(data)
+                buffer = bytearray(len(data))
+                self.assertEqual(s.read(-1, buffer), len(data))
+                self.assertEqual(buffer, data)
+
+                # recv/read(0) should return no data
+                s.send(data)
+                self.assertEqual(s.recv(0), b"")
+                self.assertEqual(s.read(0), b"")
+                self.assertEqual(s.read(), data)
+
                 # Make sure sendmsg et al are disallowed to avoid
                 # inadvertent disclosure of data and/or corruption
                 # of the encrypted data stream
@@ -2784,6 +2816,10 @@ else:
                                   s.recvmsg_into, bytearray(100))
 
                 s.write(b"over\n")
+
+                self.assertRaises(ValueError, s.recv, -1)
+                self.assertRaises(ValueError, s.read, -1)
+
                 s.close()
 
         def test_nonblocking_send(self):
@@ -3325,7 +3361,7 @@ def test_main(verbose=False):
             pass
 
     for filename in [
-        CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
+        CERTFILE, REMOTE_ROOT_CERT, BYTES_CERTFILE,
         ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
         SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
         BADCERT, BADKEY, EMPTYCERT]:
index 758a481..0089ae8 100644 (file)
@@ -21,6 +21,37 @@ import statistics
 
 # === Helper functions and class ===
 
+def _nan_equal(a, b):
+    """Return True if a and b are both the same kind of NAN.
+
+    >>> _nan_equal(Decimal('NAN'), Decimal('NAN'))
+    True
+    >>> _nan_equal(Decimal('sNAN'), Decimal('sNAN'))
+    True
+    >>> _nan_equal(Decimal('NAN'), Decimal('sNAN'))
+    False
+    >>> _nan_equal(Decimal(42), Decimal('NAN'))
+    False
+
+    >>> _nan_equal(float('NAN'), float('NAN'))
+    True
+    >>> _nan_equal(float('NAN'), 0.5)
+    False
+
+    >>> _nan_equal(float('NAN'), Decimal('NAN'))
+    False
+
+    NAN payloads are not compared.
+    """
+    if type(a) is not type(b):
+        return False
+    if isinstance(a, float):
+        return math.isnan(a) and math.isnan(b)
+    aexp = a.as_tuple()[2]
+    bexp = b.as_tuple()[2]
+    return (aexp == bexp) and (aexp in ('n', 'N'))  # Both NAN or both sNAN.
+
+
 def _calc_errors(actual, expected):
     """Return the absolute and relative errors between two numbers.
 
@@ -675,15 +706,60 @@ class ExactRatioTest(unittest.TestCase):
         self.assertEqual(_exact_ratio(D("12.345")), (12345, 1000))
         self.assertEqual(_exact_ratio(D("-1.98")), (-198, 100))
 
+    def test_inf(self):
+        INF = float("INF")
+        class MyFloat(float):
+            pass
+        class MyDecimal(Decimal):
+            pass
+        for inf in (INF, -INF):
+            for type_ in (float, MyFloat, Decimal, MyDecimal):
+                x = type_(inf)
+                ratio = statistics._exact_ratio(x)
+                self.assertEqual(ratio, (x, None))
+                self.assertEqual(type(ratio[0]), type_)
+                self.assertTrue(math.isinf(ratio[0]))
+
+    def test_float_nan(self):
+        NAN = float("NAN")
+        class MyFloat(float):
+            pass
+        for nan in (NAN, MyFloat(NAN)):
+            ratio = statistics._exact_ratio(nan)
+            self.assertTrue(math.isnan(ratio[0]))
+            self.assertIs(ratio[1], None)
+            self.assertEqual(type(ratio[0]), type(nan))
+
+    def test_decimal_nan(self):
+        NAN = Decimal("NAN")
+        sNAN = Decimal("sNAN")
+        class MyDecimal(Decimal):
+            pass
+        for nan in (NAN, MyDecimal(NAN), sNAN, MyDecimal(sNAN)):
+            ratio = statistics._exact_ratio(nan)
+            self.assertTrue(_nan_equal(ratio[0], nan))
+            self.assertIs(ratio[1], None)
+            self.assertEqual(type(ratio[0]), type(nan))
+
 
 class DecimalToRatioTest(unittest.TestCase):
     # Test _decimal_to_ratio private function.
 
-    def testSpecialsRaise(self):
-        # Test that NANs and INFs raise ValueError.
-        # Non-special values are covered by _exact_ratio above.
-        for d in (Decimal('NAN'), Decimal('sNAN'), Decimal('INF')):
-            self.assertRaises(ValueError, statistics._decimal_to_ratio, d)
+    def test_infinity(self):
+        # Test that INFs are handled correctly.
+        inf = Decimal('INF')
+        self.assertEqual(statistics._decimal_to_ratio(inf), (inf, None))
+        self.assertEqual(statistics._decimal_to_ratio(-inf), (-inf, None))
+
+    def test_nan(self):
+        # Test that NANs are handled correctly.
+        for nan in (Decimal('NAN'), Decimal('sNAN')):
+            num, den = statistics._decimal_to_ratio(nan)
+            # Because NANs always compare non-equal, we cannot use assertEqual.
+            # Nor can we use an identity test, as we don't guarantee anything
+            # about the object identity.
+            self.assertTrue(_nan_equal(num, nan))
+            self.assertIs(den, None)
 
     def test_sign(self):
         # Test sign is calculated correctly.
@@ -718,25 +794,181 @@ class DecimalToRatioTest(unittest.TestCase):
         self.assertEqual(t, (147000, 1))
 
 
-class CheckTypeTest(unittest.TestCase):
-    # Test _check_type private function.
+class IsFiniteTest(unittest.TestCase):
+    # Test _isfinite private function.
+
+    def test_finite(self):
+        # Test that finite numbers are recognised as finite.
+        for x in (5, Fraction(1, 3), 2.5, Decimal("5.5")):
+            self.assertTrue(statistics._isfinite(x))
 
-    def test_allowed(self):
-        # Test that a type which should be allowed is allowed.
-        allowed = set([int, float])
-        statistics._check_type(int, allowed)
-        statistics._check_type(float, allowed)
+    def test_infinity(self):
+        # Test that INFs are not recognised as finite.
+        for x in (float("inf"), Decimal("inf")):
+            self.assertFalse(statistics._isfinite(x))
+
+    def test_nan(self):
+        # Test that NANs are not recognised as finite.
+        for x in (float("nan"), Decimal("NAN"), Decimal("sNAN")):
+            self.assertFalse(statistics._isfinite(x))
+
+
+class CoerceTest(unittest.TestCase):
+    # Test that private function _coerce correctly deals with types.
+
+    # The coercion rules are currently an implementation detail, although at
+    # some point that should change. The tests and comments here define the
+    # correct implementation.
+
+    # Pre-conditions of _coerce:
+    #
+    #   - The first time _sum calls _coerce, the
+    #   - coerce(T, S) will never be called with bool as the first argument;
+    #     this is a pre-condition, guarded with an assertion.
+
+    #
+    #   - coerce(T, T) will always return T; we assume T is a valid numeric
+    #     type. Violate this assumption at your own risk.
+    #
+    #   - Apart from as above, bool is treated as if it were actually int.
+    #
+    #   - coerce(int, X) and coerce(X, int) return X.
+    #   -
+    def test_bool(self):
+        # bool is somewhat special, due to the pre-condition that it is
+        # never given as the first argument to _coerce, and that it cannot
+        # be subclassed. So we test it specially.
+        for T in (int, float, Fraction, Decimal):
+            self.assertIs(statistics._coerce(T, bool), T)
+            class MyClass(T): pass
+            self.assertIs(statistics._coerce(MyClass, bool), MyClass)
+
+    def assertCoerceTo(self, A, B):
+        """Assert that type A coerces to B."""
+        self.assertIs(statistics._coerce(A, B), B)
+        self.assertIs(statistics._coerce(B, A), B)
+
+    def check_coerce_to(self, A, B):
+        """Checks that type A coerces to B, including subclasses."""
+        # Assert that type A is coerced to B.
+        self.assertCoerceTo(A, B)
+        # Subclasses of A are also coerced to B.
+        class SubclassOfA(A): pass
+        self.assertCoerceTo(SubclassOfA, B)
+        # A, and subclasses of A, are coerced to subclasses of B.
+        class SubclassOfB(B): pass
+        self.assertCoerceTo(A, SubclassOfB)
+        self.assertCoerceTo(SubclassOfA, SubclassOfB)
+
+    def assertCoerceRaises(self, A, B):
+        """Assert that coercing A to B, or vice versa, raises TypeError."""
+        self.assertRaises(TypeError, statistics._coerce, (A, B))
+        self.assertRaises(TypeError, statistics._coerce, (B, A))
+
+    def check_type_coercions(self, T):
+        """Check that type T coerces correctly with subclasses of itself."""
+        assert T is not bool
+        # Coercing a type with itself returns the same type.
+        self.assertIs(statistics._coerce(T, T), T)
+        # Coercing a type with a subclass of itself returns the subclass.
+        class U(T): pass
+        class V(T): pass
+        class W(U): pass
+        for typ in (U, V, W):
+            self.assertCoerceTo(T, typ)
+        self.assertCoerceTo(U, W)
+        # Coercing two subclasses that aren't parent/child is an error.
+        self.assertCoerceRaises(U, V)
+        self.assertCoerceRaises(V, W)
 
-    def test_not_allowed(self):
-        # Test that a type which should not be allowed raises.
-        allowed = set([int, float])
-        self.assertRaises(TypeError, statistics._check_type, Decimal, allowed)
+    def test_int(self):
+        # Check that int coerces correctly.
+        self.check_type_coercions(int)
+        for typ in (float, Fraction, Decimal):
+            self.check_coerce_to(int, typ)
 
-    def test_add_to_allowed(self):
-        # Test that a second type will be added to the allowed set.
-        allowed = set([int])
-        statistics._check_type(float, allowed)
-        self.assertEqual(allowed, set([int, float]))
+    def test_fraction(self):
+        # Check that Fraction coerces correctly.
+        self.check_type_coercions(Fraction)
+        self.check_coerce_to(Fraction, float)
+
+    def test_decimal(self):
+        # Check that Decimal coerces correctly.
+        self.check_type_coercions(Decimal)
+
+    def test_float(self):
+        # Check that float coerces correctly.
+        self.check_type_coercions(float)
+
+    def test_non_numeric_types(self):
+        for bad_type in (str, list, type(None), tuple, dict):
+            for good_type in (int, float, Fraction, Decimal):
+                self.assertCoerceRaises(good_type, bad_type)
+
+    def test_incompatible_types(self):
+        # Test that incompatible types raise.
+        for T in (float, Fraction):
+            class MySubclass(T): pass
+            self.assertCoerceRaises(T, Decimal)
+            self.assertCoerceRaises(MySubclass, Decimal)
+
+
+class ConvertTest(unittest.TestCase):
+    # Test private _convert function.
+
+    def check_exact_equal(self, x, y):
+        """Check that x equals y, and has the same type as well."""
+        self.assertEqual(x, y)
+        self.assertIs(type(x), type(y))
+
+    def test_int(self):
+        # Test conversions to int.
+        x = statistics._convert(Fraction(71), int)
+        self.check_exact_equal(x, 71)
+        class MyInt(int): pass
+        x = statistics._convert(Fraction(17), MyInt)
+        self.check_exact_equal(x, MyInt(17))
+
+    def test_fraction(self):
+        # Test conversions to Fraction.
+        x = statistics._convert(Fraction(95, 99), Fraction)
+        self.check_exact_equal(x, Fraction(95, 99))
+        class MyFraction(Fraction):
+            def __truediv__(self, other):
+                return self.__class__(super().__truediv__(other))
+        x = statistics._convert(Fraction(71, 13), MyFraction)
+        self.check_exact_equal(x, MyFraction(71, 13))
+
+    def test_float(self):
+        # Test conversions to float.
+        x = statistics._convert(Fraction(-1, 2), float)
+        self.check_exact_equal(x, -0.5)
+        class MyFloat(float):
+            def __truediv__(self, other):
+                return self.__class__(super().__truediv__(other))
+        x = statistics._convert(Fraction(9, 8), MyFloat)
+        self.check_exact_equal(x, MyFloat(1.125))
+
+    def test_decimal(self):
+        # Test conversions to Decimal.
+        x = statistics._convert(Fraction(1, 40), Decimal)
+        self.check_exact_equal(x, Decimal("0.025"))
+        class MyDecimal(Decimal):
+            def __truediv__(self, other):
+                return self.__class__(super().__truediv__(other))
+        x = statistics._convert(Fraction(-15, 16), MyDecimal)
+        self.check_exact_equal(x, MyDecimal("-0.9375"))
+
+    def test_inf(self):
+        for INF in (float('inf'), Decimal('inf')):
+            for inf in (INF, -INF):
+                x = statistics._convert(inf, type(inf))
+                self.check_exact_equal(x, inf)
+
+    def test_nan(self):
+        for nan in (float('nan'), Decimal('NAN'), Decimal('sNAN')):
+            x = statistics._convert(nan, type(nan))
+            self.assertTrue(_nan_equal(x, nan))
 
 
 # === Tests for public functions ===
@@ -874,52 +1106,71 @@ class UnivariateTypeMixin:
             self.assertIs(type(result), kind)
 
 
-class TestSum(NumericTestCase, UnivariateCommonMixin, UnivariateTypeMixin):
+class TestSumCommon(UnivariateCommonMixin, UnivariateTypeMixin):
+    # Common test cases for statistics._sum() function.
+
+    # This test suite looks only at the numeric value returned by _sum,
+    # after conversion to the appropriate type.
+    def setUp(self):
+        def simplified_sum(*args):
+            T, value, n = statistics._sum(*args)
+            return statistics._coerce(value, T)
+        self.func = simplified_sum
+
+
+class TestSum(NumericTestCase):
     # Test cases for statistics._sum() function.
 
+    # These tests look at the entire three value tuple returned by _sum.
+
     def setUp(self):
         self.func = statistics._sum
 
     def test_empty_data(self):
         # Override test for empty data.
         for data in ([], (), iter([])):
-            self.assertEqual(self.func(data), 0)
-            self.assertEqual(self.func(data, 23), 23)
-            self.assertEqual(self.func(data, 2.3), 2.3)
+            self.assertEqual(self.func(data), (int, Fraction(0), 0))
+            self.assertEqual(self.func(data, 23), (int, Fraction(23), 0))
+            self.assertEqual(self.func(data, 2.3), (float, Fraction(2.3), 0))
 
     def test_ints(self):
-        self.assertEqual(self.func([1, 5, 3, -4, -8, 20, 42, 1]), 60)
-        self.assertEqual(self.func([4, 2, 3, -8, 7], 1000), 1008)
+        self.assertEqual(self.func([1, 5, 3, -4, -8, 20, 42, 1]),
+                         (int, Fraction(60), 8))
+        self.assertEqual(self.func([4, 2, 3, -8, 7], 1000),
+                         (int, Fraction(1008), 5))
 
     def test_floats(self):
-        self.assertEqual(self.func([0.25]*20), 5.0)
-        self.assertEqual(self.func([0.125, 0.25, 0.5, 0.75], 1.5), 3.125)
+        self.assertEqual(self.func([0.25]*20),
+                         (float, Fraction(5.0), 20))
+        self.assertEqual(self.func([0.125, 0.25, 0.5, 0.75], 1.5),
+                         (float, Fraction(3.125), 4))
 
     def test_fractions(self):
-        F = Fraction
-        self.assertEqual(self.func([Fraction(1, 1000)]*500), Fraction(1, 2))
+        self.assertEqual(self.func([Fraction(1, 1000)]*500),
+                         (Fraction, Fraction(1, 2), 500))
 
     def test_decimals(self):
         D = Decimal
         data = [D("0.001"), D("5.246"), D("1.702"), D("-0.025"),
                 D("3.974"), D("2.328"), D("4.617"), D("2.843"),
                 ]
-        self.assertEqual(self.func(data), Decimal("20.686"))
+        self.assertEqual(self.func(data),
+                         (Decimal, Decimal("20.686"), 8))
 
     def test_compare_with_math_fsum(self):
         # Compare with the math.fsum function.
         # Ideally we ought to get the exact same result, but sometimes
         # we differ by a very slight amount :-(
         data = [random.uniform(-100, 1000) for _ in range(1000)]
-        self.assertApproxEqual(self.func(data), math.fsum(data), rel=2e-16)
+        self.assertApproxEqual(float(self.func(data)[1]), math.fsum(data), rel=2e-16)
 
     def test_start_argument(self):
         # Test that the optional start argument works correctly.
         data = [random.uniform(1, 1000) for _ in range(100)]
-        t = self.func(data)
-        self.assertEqual(t+42, self.func(data, 42))
-        self.assertEqual(t-23, self.func(data, -23))
-        self.assertEqual(t+1e20, self.func(data, 1e20))
+        t = self.func(data)[1]
+        self.assertEqual(t+42, self.func(data, 42)[1])
+        self.assertEqual(t-23, self.func(data, -23)[1])
+        self.assertEqual(t+Fraction(1e20), self.func(data, 1e20)[1])
 
     def test_strings_fail(self):
         # Sum of strings should fail.
@@ -934,7 +1185,7 @@ class TestSum(NumericTestCase, UnivariateCommonMixin, UnivariateTypeMixin):
     def test_mixed_sum(self):
         # Mixed input types are not (currently) allowed.
         # Check that mixed data types fail.
-        self.assertRaises(TypeError, self.func, [1, 2.0, Fraction(1, 2)])
+        self.assertRaises(TypeError, self.func, [1, 2.0, Decimal(1)])
         # And so does mixed start argument.
         self.assertRaises(TypeError, self.func, [1, 2.0], Decimal(1))
 
@@ -942,11 +1193,14 @@ class TestSum(NumericTestCase, UnivariateCommonMixin, UnivariateTypeMixin):
 class SumTortureTest(NumericTestCase):
     def test_torture(self):
         # Tim Peters' torture test for sum, and variants of same.
-        self.assertEqual(statistics._sum([1, 1e100, 1, -1e100]*10000), 20000.0)
-        self.assertEqual(statistics._sum([1e100, 1, 1, -1e100]*10000), 20000.0)
-        self.assertApproxEqual(
-            statistics._sum([1e-100, 1, 1e-100, -1]*10000), 2.0e-96, rel=5e-16
-            )
+        self.assertEqual(statistics._sum([1, 1e100, 1, -1e100]*10000),
+                         (float, Fraction(20000.0), 40000))
+        self.assertEqual(statistics._sum([1e100, 1, 1, -1e100]*10000),
+                         (float, Fraction(20000.0), 40000))
+        T, num, count = statistics._sum([1e-100, 1, 1e-100, -1]*10000)
+        self.assertIs(T, float)
+        self.assertEqual(count, 40000)
+        self.assertApproxEqual(float(num), 2.0e-96, rel=5e-16)
 
 
 class SumSpecialValues(NumericTestCase):
@@ -955,7 +1209,7 @@ class SumSpecialValues(NumericTestCase):
     def test_nan(self):
         for type_ in (float, Decimal):
             nan = type_('nan')
-            result = statistics._sum([1, nan, 2])
+            result = statistics._sum([1, nan, 2])[1]
             self.assertIs(type(result), type_)
             self.assertTrue(math.isnan(result))
 
@@ -968,10 +1222,10 @@ class SumSpecialValues(NumericTestCase):
 
     def do_test_inf(self, inf):
         # Adding a single infinity gives infinity.
-        result = statistics._sum([1, 2, inf, 3])
+        result = statistics._sum([1, 2, inf, 3])[1]
         self.check_infinity(result, inf)
         # Adding two infinities of the same sign also gives infinity.
-        result = statistics._sum([1, 2, inf, 3, inf, 4])
+        result = statistics._sum([1, 2, inf, 3, inf, 4])[1]
         self.check_infinity(result, inf)
 
     def test_float_inf(self):
@@ -987,7 +1241,7 @@ class SumSpecialValues(NumericTestCase):
     def test_float_mismatched_infs(self):
         # Test that adding two infinities of opposite sign gives a NAN.
         inf = float('inf')
-        result = statistics._sum([1, 2, inf, 3, -inf, 4])
+        result = statistics._sum([1, 2, inf, 3, -inf, 4])[1]
         self.assertTrue(math.isnan(result))
 
     def test_decimal_extendedcontext_mismatched_infs_to_nan(self):
@@ -995,7 +1249,7 @@ class SumSpecialValues(NumericTestCase):
         inf = Decimal('inf')
         data = [1, 2, inf, 3, -inf, 4]
         with decimal.localcontext(decimal.ExtendedContext):
-            self.assertTrue(math.isnan(statistics._sum(data)))
+            self.assertTrue(math.isnan(statistics._sum(data)[1]))
 
     def test_decimal_basiccontext_mismatched_infs_to_nan(self):
         # Test adding Decimal INFs with opposite sign raises InvalidOperation.
@@ -1111,6 +1365,19 @@ class TestMean(NumericTestCase, AverageMixin, UnivariateTypeMixin):
         d = Decimal('1e4')
         self.assertEqual(statistics.mean([d]), d)
 
+    def test_regression_25177(self):
+        # Regression test for issue 25177.
+        # Ensure very big and very small floats don't overflow.
+        # See http://bugs.python.org/issue25177.
+        self.assertEqual(statistics.mean(
+            [8.988465674311579e+307, 8.98846567431158e+307]),
+            8.98846567431158e+307)
+        big = 8.98846567431158e+307
+        tiny = 5e-324
+        for n in (2, 3, 5, 200):
+            self.assertEqual(statistics.mean([big]*n), big)
+            self.assertEqual(statistics.mean([tiny]*n), tiny)
+
 
 class TestMedian(NumericTestCase, AverageMixin):
     # Common tests for median and all median.* functions.
index 0cd2b86..70439f8 100644 (file)
@@ -1,4 +1,6 @@
-import unittest, string
+import unittest
+import string
+from string import Template
 
 
 class ModuleTest(unittest.TestCase):
@@ -187,5 +189,245 @@ class ModuleTest(unittest.TestCase):
         self.assertIn("recursion", str(err.exception))
 
 
-if __name__ == "__main__":
+# Template tests (formerly housed in test_pep292.py)
+
+class Bag:
+    pass
+
+class Mapping:
+    def __getitem__(self, name):
+        obj = self
+        for part in name.split('.'):
+            try:
+                obj = getattr(obj, part)
+            except AttributeError:
+                raise KeyError(name)
+        return obj
+
+
+class TestTemplate(unittest.TestCase):
+    def test_regular_templates(self):
+        s = Template('$who likes to eat a bag of $what worth $$100')
+        self.assertEqual(s.substitute(dict(who='tim', what='ham')),
+                         'tim likes to eat a bag of ham worth $100')
+        self.assertRaises(KeyError, s.substitute, dict(who='tim'))
+        self.assertRaises(TypeError, Template.substitute)
+
+    def test_regular_templates_with_braces(self):
+        s = Template('$who likes ${what} for ${meal}')
+        d = dict(who='tim', what='ham', meal='dinner')
+        self.assertEqual(s.substitute(d), 'tim likes ham for dinner')
+        self.assertRaises(KeyError, s.substitute,
+                          dict(who='tim', what='ham'))
+
+    def test_escapes(self):
+        eq = self.assertEqual
+        s = Template('$who likes to eat a bag of $$what worth $$100')
+        eq(s.substitute(dict(who='tim', what='ham')),
+           'tim likes to eat a bag of $what worth $100')
+        s = Template('$who likes $$')
+        eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $')
+
+    def test_percents(self):
+        eq = self.assertEqual
+        s = Template('%(foo)s $foo ${foo}')
+        d = dict(foo='baz')
+        eq(s.substitute(d), '%(foo)s baz baz')
+        eq(s.safe_substitute(d), '%(foo)s baz baz')
+
+    def test_stringification(self):
+        eq = self.assertEqual
+        s = Template('tim has eaten $count bags of ham today')
+        d = dict(count=7)
+        eq(s.substitute(d), 'tim has eaten 7 bags of ham today')
+        eq(s.safe_substitute(d), 'tim has eaten 7 bags of ham today')
+        s = Template('tim has eaten ${count} bags of ham today')
+        eq(s.substitute(d), 'tim has eaten 7 bags of ham today')
+
+    def test_tupleargs(self):
+        eq = self.assertEqual
+        s = Template('$who ate ${meal}')
+        d = dict(who=('tim', 'fred'), meal=('ham', 'kung pao'))
+        eq(s.substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')")
+        eq(s.safe_substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')")
+
+    def test_SafeTemplate(self):
+        eq = self.assertEqual
+        s = Template('$who likes ${what} for ${meal}')
+        eq(s.safe_substitute(dict(who='tim')), 'tim likes ${what} for ${meal}')
+        eq(s.safe_substitute(dict(what='ham')), '$who likes ham for ${meal}')
+        eq(s.safe_substitute(dict(what='ham', meal='dinner')),
+           '$who likes ham for dinner')
+        eq(s.safe_substitute(dict(who='tim', what='ham')),
+           'tim likes ham for ${meal}')
+        eq(s.safe_substitute(dict(who='tim', what='ham', meal='dinner')),
+           'tim likes ham for dinner')
+
+    def test_invalid_placeholders(self):
+        raises = self.assertRaises
+        s = Template('$who likes $')
+        raises(ValueError, s.substitute, dict(who='tim'))
+        s = Template('$who likes ${what)')
+        raises(ValueError, s.substitute, dict(who='tim'))
+        s = Template('$who likes $100')
+        raises(ValueError, s.substitute, dict(who='tim'))
+
+    def test_idpattern_override(self):
+        class PathPattern(Template):
+            idpattern = r'[_a-z][._a-z0-9]*'
+        m = Mapping()
+        m.bag = Bag()
+        m.bag.foo = Bag()
+        m.bag.foo.who = 'tim'
+        m.bag.what = 'ham'
+        s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what')
+        self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
+
+    def test_pattern_override(self):
+        class MyPattern(Template):
+            pattern = r"""
+            (?P<escaped>@{2})                   |
+            @(?P<named>[_a-z][._a-z0-9]*)       |
+            @{(?P<braced>[_a-z][._a-z0-9]*)}    |
+            (?P<invalid>@)
+            """
+        m = Mapping()
+        m.bag = Bag()
+        m.bag.foo = Bag()
+        m.bag.foo.who = 'tim'
+        m.bag.what = 'ham'
+        s = MyPattern('@bag.foo.who likes to eat a bag of @bag.what')
+        self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
+
+        class BadPattern(Template):
+            pattern = r"""
+            (?P<badname>.*)                     |
+            (?P<escaped>@{2})                   |
+            @(?P<named>[_a-z][._a-z0-9]*)       |
+            @{(?P<braced>[_a-z][._a-z0-9]*)}    |
+            (?P<invalid>@)                      |
+            """
+        s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what')
+        self.assertRaises(ValueError, s.substitute, {})
+        self.assertRaises(ValueError, s.safe_substitute, {})
+
+    def test_braced_override(self):
+        class MyTemplate(Template):
+            pattern = r"""
+            \$(?:
+              (?P<escaped>$)                     |
+              (?P<named>[_a-z][_a-z0-9]*)        |
+              @@(?P<braced>[_a-z][_a-z0-9]*)@@   |
+              (?P<invalid>)                      |
+           )
+           """
+
+        tmpl = 'PyCon in $@@location@@'
+        t = MyTemplate(tmpl)
+        self.assertRaises(KeyError, t.substitute, {})
+        val = t.substitute({'location': 'Cleveland'})
+        self.assertEqual(val, 'PyCon in Cleveland')
+
+    def test_braced_override_safe(self):
+        class MyTemplate(Template):
+            pattern = r"""
+            \$(?:
+              (?P<escaped>$)                     |
+              (?P<named>[_a-z][_a-z0-9]*)        |
+              @@(?P<braced>[_a-z][_a-z0-9]*)@@   |
+              (?P<invalid>)                      |
+           )
+           """
+
+        tmpl = 'PyCon in $@@location@@'
+        t = MyTemplate(tmpl)
+        self.assertEqual(t.safe_substitute(), tmpl)
+        val = t.safe_substitute({'location': 'Cleveland'})
+        self.assertEqual(val, 'PyCon in Cleveland')
+
+    def test_invalid_with_no_lines(self):
+        # The error formatting for invalid templates
+        # has a special case for no data that the default
+        # pattern can't trigger (always has at least '$')
+        # So we craft a pattern that is always invalid
+        # with no leading data.
+        class MyTemplate(Template):
+            pattern = r"""
+              (?P<invalid>) |
+              unreachable(
+                (?P<named>)   |
+                (?P<braced>)  |
+                (?P<escaped>)
+              )
+            """
+        s = MyTemplate('')
+        with self.assertRaises(ValueError) as err:
+            s.substitute({})
+        self.assertIn('line 1, col 1', str(err.exception))
+
+    def test_unicode_values(self):
+        s = Template('$who likes $what')
+        d = dict(who='t\xffm', what='f\xfe\fed')
+        self.assertEqual(s.substitute(d), 't\xffm likes f\xfe\x0ced')
+
+    def test_keyword_arguments(self):
+        eq = self.assertEqual
+        s = Template('$who likes $what')
+        eq(s.substitute(who='tim', what='ham'), 'tim likes ham')
+        eq(s.substitute(dict(who='tim'), what='ham'), 'tim likes ham')
+        eq(s.substitute(dict(who='fred', what='kung pao'),
+                        who='tim', what='ham'),
+           'tim likes ham')
+        s = Template('the mapping is $mapping')
+        eq(s.substitute(dict(foo='none'), mapping='bozo'),
+           'the mapping is bozo')
+        eq(s.substitute(dict(mapping='one'), mapping='two'),
+           'the mapping is two')
+
+        s = Template('the self is $self')
+        eq(s.substitute(self='bozo'), 'the self is bozo')
+
+    def test_keyword_arguments_safe(self):
+        eq = self.assertEqual
+        raises = self.assertRaises
+        s = Template('$who likes $what')
+        eq(s.safe_substitute(who='tim', what='ham'), 'tim likes ham')
+        eq(s.safe_substitute(dict(who='tim'), what='ham'), 'tim likes ham')
+        eq(s.safe_substitute(dict(who='fred', what='kung pao'),
+                        who='tim', what='ham'),
+           'tim likes ham')
+        s = Template('the mapping is $mapping')
+        eq(s.safe_substitute(dict(foo='none'), mapping='bozo'),
+           'the mapping is bozo')
+        eq(s.safe_substitute(dict(mapping='one'), mapping='two'),
+           'the mapping is two')
+        d = dict(mapping='one')
+        raises(TypeError, s.substitute, d, {})
+        raises(TypeError, s.safe_substitute, d, {})
+
+        s = Template('the self is $self')
+        eq(s.safe_substitute(self='bozo'), 'the self is bozo')
+
+    def test_delimiter_override(self):
+        eq = self.assertEqual
+        raises = self.assertRaises
+        class AmpersandTemplate(Template):
+            delimiter = '&'
+        s = AmpersandTemplate('this &gift is for &{who} &&')
+        eq(s.substitute(gift='bud', who='you'), 'this bud is for you &')
+        raises(KeyError, s.substitute)
+        eq(s.safe_substitute(gift='bud', who='you'), 'this bud is for you &')
+        eq(s.safe_substitute(), 'this &gift is for &{who} &')
+        s = AmpersandTemplate('this &gift is for &{who} &')
+        raises(ValueError, s.substitute, dict(gift='bud', who='you'))
+        eq(s.safe_substitute(), 'this &gift is for &{who} &')
+
+        class PieDelims(Template):
+            delimiter = '@'
+        s = PieDelims('@who likes to eat a bag of @{what} worth $100')
+        self.assertEqual(s.substitute(dict(who='tim', what='ham')),
+                         'tim likes to eat a bag of ham worth $100')
+
+
+if __name__ == '__main__':
     unittest.main()
index 346e2c6..85126e6 100644 (file)
@@ -4,6 +4,7 @@ import unittest
 import time
 import locale
 import re
+import os
 import sys
 from test import support
 from datetime import date as datetime_date
@@ -189,7 +190,7 @@ class TimeRETests(unittest.TestCase):
 
     def test_whitespace_substitution(self):
         # When pattern contains whitespace, make sure it is taken into account
-        # so as to not allow to subpatterns to end up next to each other and
+        # so as to not allow subpatterns to end up next to each other and
         # "steal" characters from each other.
         pattern = self.time_re.pattern('%j %H')
         self.assertFalse(re.match(pattern, "180"))
@@ -324,9 +325,10 @@ class StrptimeTests(unittest.TestCase):
         tz_name = time.tzname[0]
         if tz_name.upper() in ("UTC", "GMT"):
             self.skipTest('need non-UTC/GMT timezone')
-        try:
-            original_tzname = time.tzname
-            original_daylight = time.daylight
+
+        with support.swap_attr(time, 'tzname', (tz_name, tz_name)), \
+             support.swap_attr(time, 'daylight', 1), \
+             support.swap_attr(time, 'tzset', lambda: None):
             time.tzname = (tz_name, tz_name)
             time.daylight = 1
             tz_value = _strptime._strptime_time(tz_name, "%Z")[8]
@@ -334,9 +336,6 @@ class StrptimeTests(unittest.TestCase):
                     "%s lead to a timezone value of %s instead of -1 when "
                     "time.daylight set to %s and passing in %s" %
                     (time.tzname, tz_value, time.daylight, tz_name))
-        finally:
-            time.tzname = original_tzname
-            time.daylight = original_daylight
 
     def test_date_time(self):
         # Test %c directive
@@ -497,14 +496,14 @@ class CalculationTests(unittest.TestCase):
     def test_week_0(self):
         def check(value, format, *expected):
             self.assertEqual(_strptime._strptime_time(value, format)[:-1], expected)
-        check('2015 0 0', '%Y %U %w', 2014, 12, 28, 0, 0, 0, 6, -3)
+        check('2015 0 0', '%Y %U %w', 2014, 12, 28, 0, 0, 0, 6, 362)
         check('2015 0 0', '%Y %W %w', 2015, 1, 4, 0, 0, 0, 6, 4)
-        check('2015 0 1', '%Y %U %w', 2014, 12, 29, 0, 0, 0, 0, -2)
-        check('2015 0 1', '%Y %W %w', 2014, 12, 29, 0, 0, 0, 0, -2)
-        check('2015 0 2', '%Y %U %w', 2014, 12, 30, 0, 0, 0, 1, -1)
-        check('2015 0 2', '%Y %W %w', 2014, 12, 30, 0, 0, 0, 1, -1)
-        check('2015 0 3', '%Y %U %w', 2014, 12, 31, 0, 0, 0, 2, 0)
-        check('2015 0 3', '%Y %W %w', 2014, 12, 31, 0, 0, 0, 2, 0)
+        check('2015 0 1', '%Y %U %w', 2014, 12, 29, 0, 0, 0, 0, 363)
+        check('2015 0 1', '%Y %W %w', 2014, 12, 29, 0, 0, 0, 0, 363)
+        check('2015 0 2', '%Y %U %w', 2014, 12, 30, 0, 0, 0, 1, 364)
+        check('2015 0 2', '%Y %W %w', 2014, 12, 30, 0, 0, 0, 1, 364)
+        check('2015 0 3', '%Y %U %w', 2014, 12, 31, 0, 0, 0, 2, 365)
+        check('2015 0 3', '%Y %W %w', 2014, 12, 31, 0, 0, 0, 2, 365)
         check('2015 0 4', '%Y %U %w', 2015, 1, 1, 0, 0, 0, 3, 1)
         check('2015 0 4', '%Y %W %w', 2015, 1, 1, 0, 0, 0, 3, 1)
         check('2015 0 5', '%Y %U %w', 2015, 1, 2, 0, 0, 0, 4, 2)
@@ -512,6 +511,20 @@ class CalculationTests(unittest.TestCase):
         check('2015 0 6', '%Y %U %w', 2015, 1, 3, 0, 0, 0, 5, 3)
         check('2015 0 6', '%Y %W %w', 2015, 1, 3, 0, 0, 0, 5, 3)
 
+        check('2009 0 0', '%Y %U %w', 2008, 12, 28, 0, 0, 0, 6, 363)
+        check('2009 0 0', '%Y %W %w', 2009, 1, 4, 0, 0, 0, 6, 4)
+        check('2009 0 1', '%Y %U %w', 2008, 12, 29, 0, 0, 0, 0, 364)
+        check('2009 0 1', '%Y %W %w', 2008, 12, 29, 0, 0, 0, 0, 364)
+        check('2009 0 2', '%Y %U %w', 2008, 12, 30, 0, 0, 0, 1, 365)
+        check('2009 0 2', '%Y %W %w', 2008, 12, 30, 0, 0, 0, 1, 365)
+        check('2009 0 3', '%Y %U %w', 2008, 12, 31, 0, 0, 0, 2, 366)
+        check('2009 0 3', '%Y %W %w', 2008, 12, 31, 0, 0, 0, 2, 366)
+        check('2009 0 4', '%Y %U %w', 2009, 1, 1, 0, 0, 0, 3, 1)
+        check('2009 0 4', '%Y %W %w', 2009, 1, 1, 0, 0, 0, 3, 1)
+        check('2009 0 5', '%Y %U %w', 2009, 1, 2, 0, 0, 0, 4, 2)
+        check('2009 0 5', '%Y %W %w', 2009, 1, 2, 0, 0, 0, 4, 2)
+        check('2009 0 6', '%Y %U %w', 2009, 1, 3, 0, 0, 0, 5, 3)
+        check('2009 0 6', '%Y %W %w', 2009, 1, 3, 0, 0, 0, 5, 3)
 
 class CacheTests(unittest.TestCase):
     """Test that caching works properly."""
@@ -548,7 +561,7 @@ class CacheTests(unittest.TestCase):
         _strptime._strptime_time("10", "%d")
         self.assertIsNot(locale_time_id, _strptime._TimeRE_cache.locale_time)
 
-    def test_TimeRE_recreation(self):
+    def test_TimeRE_recreation_locale(self):
         # The TimeRE instance should be recreated upon changing the locale.
         locale_info = locale.getlocale(locale.LC_TIME)
         try:
@@ -577,6 +590,33 @@ class CacheTests(unittest.TestCase):
         finally:
             locale.setlocale(locale.LC_TIME, locale_info)
 
+    @support.run_with_tz('STD-1DST')
+    def test_TimeRE_recreation_timezone(self):
+        # The TimeRE instance should be recreated upon changing the timezone.
+        oldtzname = time.tzname
+        tm = _strptime._strptime_time(time.tzname[0], '%Z')
+        self.assertEqual(tm.tm_isdst, 0)
+        tm = _strptime._strptime_time(time.tzname[1], '%Z')
+        self.assertEqual(tm.tm_isdst, 1)
+        # Get id of current cache object.
+        first_time_re = _strptime._TimeRE_cache
+        # Change the timezone and force a recreation of the cache.
+        os.environ['TZ'] = 'EST+05EDT,M3.2.0,M11.1.0'
+        time.tzset()
+        tm = _strptime._strptime_time(time.tzname[0], '%Z')
+        self.assertEqual(tm.tm_isdst, 0)
+        tm = _strptime._strptime_time(time.tzname[1], '%Z')
+        self.assertEqual(tm.tm_isdst, 1)
+        # Get the new cache object's id.
+        second_time_re = _strptime._TimeRE_cache
+        # They should not be equal.
+        self.assertIsNot(first_time_re, second_time_re)
+        # Make sure old names no longer accepted.
+        with self.assertRaises(ValueError):
+            _strptime._strptime_time(oldtzname[0], '%Z')
+        with self.assertRaises(ValueError):
+            _strptime._strptime_time(oldtzname[1], '%Z')
+
 
 if __name__ == '__main__':
     unittest.main()
index e06beed..4704d49 100644 (file)
@@ -1,4 +1,5 @@
 import unittest
+from unittest import mock
 from test.support import script_helper
 from test import support
 import subprocess
@@ -504,6 +505,27 @@ class ProcessTestCase(BaseTestCase):
         tf.seek(0)
         self.assertStderrEqual(tf.read(), b"strawberry")
 
+    def test_stderr_redirect_with_no_stdout_redirect(self):
+        # test stderr=STDOUT while stdout=None (not set)
+
+        # - grandchild prints to stderr
+        # - child redirects grandchild's stderr to its stdout
+        # - the parent should get grandchild's stderr in child's stdout
+        p = subprocess.Popen([sys.executable, "-c",
+                              'import sys, subprocess;'
+                              'rc = subprocess.call([sys.executable, "-c",'
+                              '    "import sys;"'
+                              '    "sys.stderr.write(\'42\')"],'
+                              '    stderr=subprocess.STDOUT);'
+                              'sys.exit(rc)'],
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        stdout, stderr = p.communicate()
+        #NOTE: stdout should get stderr from grandchild
+        self.assertStderrEqual(stdout, b'42')
+        self.assertStderrEqual(stderr, b'') # should be empty
+        self.assertEqual(p.returncode, 0)
+
     def test_stdout_stderr_pipe(self):
         # capture stdout and stderr to the same pipe
         p = subprocess.Popen([sys.executable, "-c",
@@ -1512,6 +1534,28 @@ class POSIXProcessTestCase(BaseTestCase):
             if not enabled:
                 gc.disable()
 
+    @unittest.skipIf(
+        sys.platform == 'darwin', 'setrlimit() seems to fail on OS X')
+    def test_preexec_fork_failure(self):
+        # The internal code did not preserve the previous exception when
+        # re-enabling garbage collection
+        try:
+            from resource import getrlimit, setrlimit, RLIMIT_NPROC
+        except ImportError as err:
+            self.skipTest(err)  # RLIMIT_NPROC is specific to Linux and BSD
+        limits = getrlimit(RLIMIT_NPROC)
+        [_, hard] = limits
+        setrlimit(RLIMIT_NPROC, (0, hard))
+        self.addCleanup(setrlimit, RLIMIT_NPROC, limits)
+        try:
+            subprocess.call([sys.executable, '-c', ''],
+                            preexec_fn=lambda: None)
+        except BlockingIOError:
+            # Forking should raise EAGAIN, translated to BlockingIOError
+            pass
+        else:
+            self.skipTest('RLIMIT_NPROC had no effect; probably superuser')
+
     def test_args_string(self):
         # args is a string
         fd, fname = tempfile.mkstemp()
@@ -2358,6 +2402,52 @@ class POSIXProcessTestCase(BaseTestCase):
             if not gc_enabled:
                 gc.disable()
 
+    def test_communicate_BrokenPipeError_stdin_close(self):
+        # By not setting stdout or stderr or a timeout we force the fast path
+        # that just calls _stdin_write() internally due to our mock.
+        proc = subprocess.Popen([sys.executable, '-c', 'pass'])
+        with proc, mock.patch.object(proc, 'stdin') as mock_proc_stdin:
+            mock_proc_stdin.close.side_effect = BrokenPipeError
+            proc.communicate()  # Should swallow BrokenPipeError from close.
+            mock_proc_stdin.close.assert_called_with()
+
+    def test_communicate_BrokenPipeError_stdin_write(self):
+        # By not setting stdout or stderr or a timeout we force the fast path
+        # that just calls _stdin_write() internally due to our mock.
+        proc = subprocess.Popen([sys.executable, '-c', 'pass'])
+        with proc, mock.patch.object(proc, 'stdin') as mock_proc_stdin:
+            mock_proc_stdin.write.side_effect = BrokenPipeError
+            proc.communicate(b'stuff')  # Should swallow the BrokenPipeError.
+            mock_proc_stdin.write.assert_called_once_with(b'stuff')
+            mock_proc_stdin.close.assert_called_once_with()
+
+    def test_communicate_BrokenPipeError_stdin_flush(self):
+        # Setting stdin and stdout forces the ._communicate() code path.
+        # python -h exits faster than python -c pass (but spams stdout).
+        proc = subprocess.Popen([sys.executable, '-h'],
+                                stdin=subprocess.PIPE,
+                                stdout=subprocess.PIPE)
+        with proc, mock.patch.object(proc, 'stdin') as mock_proc_stdin, \
+                open(os.devnull, 'wb') as dev_null:
+            mock_proc_stdin.flush.side_effect = BrokenPipeError
+            # because _communicate registers a selector using proc.stdin...
+            mock_proc_stdin.fileno.return_value = dev_null.fileno()
+            # _communicate() should swallow BrokenPipeError from flush.
+            proc.communicate(b'stuff')
+            mock_proc_stdin.flush.assert_called_once_with()
+
+    def test_communicate_BrokenPipeError_stdin_close_with_timeout(self):
+        # Setting stdin and stdout forces the ._communicate() code path.
+        # python -h exits faster than python -c pass (but spams stdout).
+        proc = subprocess.Popen([sys.executable, '-h'],
+                                stdin=subprocess.PIPE,
+                                stdout=subprocess.PIPE)
+        with proc, mock.patch.object(proc, 'stdin') as mock_proc_stdin:
+            mock_proc_stdin.close.side_effect = BrokenPipeError
+            # _communicate() should swallow BrokenPipeError from close.
+            proc.communicate(timeout=999)
+            mock_proc_stdin.close.assert_called_once_with()
+
 
 @unittest.skipUnless(mswindows, "Windows specific tests")
 class Win32ProcessTestCase(BaseTestCase):
@@ -2496,7 +2586,7 @@ class Win32ProcessTestCase(BaseTestCase):
     def test_terminate_dead(self):
         self._kill_dead_process('terminate')
 
-class CommandTests(unittest.TestCase):
+class MiscTests(unittest.TestCase):
     def test_getoutput(self):
         self.assertEqual(subprocess.getoutput('echo xyzzy'), 'xyzzy')
         self.assertEqual(subprocess.getstatusoutput('echo xyzzy'),
@@ -2516,22 +2606,10 @@ class CommandTests(unittest.TestCase):
             if dir is not None:
                 os.rmdir(dir)
 
-
-@unittest.skipUnless(hasattr(selectors, 'PollSelector'),
-                     "Test needs selectors.PollSelector")
-class ProcessTestCaseNoPoll(ProcessTestCase):
-    def setUp(self):
-        self.orig_selector = subprocess._PopenSelector
-        subprocess._PopenSelector = selectors.SelectSelector
-        ProcessTestCase.setUp(self)
-
-    def tearDown(self):
-        subprocess._PopenSelector = self.orig_selector
-        ProcessTestCase.tearDown(self)
-
     def test__all__(self):
         """Ensure that __all__ is populated properly."""
-        intentionally_excluded = set(("list2cmdline",))
+        # STARTUPINFO added to __all__ in 3.6
+        intentionally_excluded = {"list2cmdline", "STARTUPINFO", "Handle"}
         exported = set(subprocess.__all__)
         possible_exports = set()
         import types
@@ -2544,6 +2622,18 @@ class ProcessTestCaseNoPoll(ProcessTestCase):
         self.assertEqual(exported, possible_exports - intentionally_excluded)
 
 
+@unittest.skipUnless(hasattr(selectors, 'PollSelector'),
+                     "Test needs selectors.PollSelector")
+class ProcessTestCaseNoPoll(ProcessTestCase):
+    def setUp(self):
+        self.orig_selector = subprocess._PopenSelector
+        subprocess._PopenSelector = selectors.SelectSelector
+        ProcessTestCase.setUp(self)
+
+    def tearDown(self):
+        subprocess._PopenSelector = self.orig_selector
+        ProcessTestCase.tearDown(self)
+
 
 @unittest.skipUnless(mswindows, "Windows-specific tests")
 class CommandsWithSpaces (BaseTestCase):
@@ -2647,7 +2737,7 @@ def test_main():
     unit_tests = (ProcessTestCase,
                   POSIXProcessTestCase,
                   Win32ProcessTestCase,
-                  CommandTests,
+                  MiscTests,
                   ProcessTestCaseNoPoll,
                   CommandsWithSpaces,
                   ContextManagerTests,
index dc3a15f..b84863f 100644 (file)
@@ -171,6 +171,15 @@ class TestSuper(unittest.TestCase):
         c = f().__closure__[0]
         self.assertRaises(TypeError, X.meth, c)
 
+    def test_super_init_leaks(self):
+        # Issue #26718: super.__init__ leaked memory if called multiple times.
+        # This will be caught by regrtest.py -R if this leak.
+        # NOTE: Despite the use in the test a direct call of super.__init__
+        # is not endorsed.
+        sp = super(float, 1.0)
+        for i in range(1000):
+            super.__init__(sp, int, i)
+
 
 if __name__ == "__main__":
     unittest.main()
index a22cebb..057441c 100644 (file)
@@ -416,6 +416,14 @@ TODO(jhylton): Figure out how to test SyntaxWarning with doctest.
 ##     ...
 ##   SyntaxWarning: name 'x' is assigned to before nonlocal declaration
 
+ From https://bugs.python.org/issue25973
+   >>> class A:
+   ...     def f(self):
+   ...         nonlocal __x
+   Traceback (most recent call last):
+     ...
+   SyntaxError: no binding for nonlocal '_A__x' found
+
 
 This tests assignment-context; there was a bug in Python 2.5 where compiling
 a complex 'if' (one with 'elif') would fail to notice an invalid suite,
index 2d95653..a531879 100644 (file)
@@ -644,7 +644,7 @@ class SysModuleTest(unittest.TestCase):
         self.assertEqual(os.path.abspath(sys.executable), sys.executable)
 
         # Issue #7774: Ensure that sys.executable is an empty string if argv[0]
-        # has been set to an non existent program name and Python is unable to
+        # has been set to a non existent program name and Python is unable to
         # retrieve the real program name
 
         # For a normal installation, it should work without 'cwd'
@@ -691,8 +691,10 @@ class SysModuleTest(unittest.TestCase):
         args = [sys.executable, "-c", code]
         if isolated:
             args.append("-I")
-        elif encoding:
+        if encoding is not None:
             env['PYTHONIOENCODING'] = encoding
+        else:
+            env.pop('PYTHONIOENCODING', None)
         p = subprocess.Popen(args,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.STDOUT,
@@ -709,15 +711,32 @@ class SysModuleTest(unittest.TestCase):
                          'stderr: backslashreplace\n')
 
         # replace the default error handler
-        out = self.c_locale_get_error_handler(encoding=':strict')
+        out = self.c_locale_get_error_handler(encoding=':ignore')
         self.assertEqual(out,
-                         'stdin: strict\n'
-                         'stdout: strict\n'
+                         'stdin: ignore\n'
+                         'stdout: ignore\n'
                          'stderr: backslashreplace\n')
 
         # force the encoding
         out = self.c_locale_get_error_handler(encoding='iso8859-1')
         self.assertEqual(out,
+                         'stdin: strict\n'
+                         'stdout: strict\n'
+                         'stderr: backslashreplace\n')
+        out = self.c_locale_get_error_handler(encoding='iso8859-1:')
+        self.assertEqual(out,
+                         'stdin: strict\n'
+                         'stdout: strict\n'
+                         'stderr: backslashreplace\n')
+
+        # have no any effect
+        out = self.c_locale_get_error_handler(encoding=':')
+        self.assertEqual(out,
+                         'stdin: surrogateescape\n'
+                         'stdout: surrogateescape\n'
+                         'stderr: backslashreplace\n')
+        out = self.c_locale_get_error_handler(encoding='')
+        self.assertEqual(out,
                          'stdin: surrogateescape\n'
                          'stdout: surrogateescape\n'
                          'stderr: backslashreplace\n')
@@ -814,11 +833,6 @@ class SizeofTest(unittest.TestCase):
         self.longdigit = sys.int_info.sizeof_digit
         import _testcapi
         self.gc_headsize = _testcapi.SIZEOF_PYGC_HEAD
-        self.file = open(test.support.TESTFN, 'wb')
-
-    def tearDown(self):
-        self.file.close()
-        test.support.unlink(test.support.TESTFN)
 
     check_sizeof = test.support.check_sizeof
 
@@ -869,6 +883,7 @@ class SizeofTest(unittest.TestCase):
 
     def test_objecttypes(self):
         # check all types defined in Objects/
+        calcsize = struct.calcsize
         size = test.support.calcobjsize
         vsize = test.support.calcvobjsize
         check = self.check_sizeof
@@ -920,17 +935,23 @@ class SizeofTest(unittest.TestCase):
         # method-wrapper (descriptor object)
         check({}.__iter__, size('2P'))
         # dict
-        check({}, size('n2P' + '2nPn' + 8*'n2P'))
+        check({}, size('n2P') + calcsize('2nPn') + 8*calcsize('n2P'))
         longdict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8}
-        check(longdict, size('n2P' + '2nPn') + 16*struct.calcsize('n2P'))
-        # dictionary-keyiterator
+        check(longdict, size('n2P') + calcsize('2nPn') + 16*calcsize('n2P'))
+        # dictionary-keyview
         check({}.keys(), size('P'))
-        # dictionary-valueiterator
+        # dictionary-valueview
         check({}.values(), size('P'))
-        # dictionary-itemiterator
+        # dictionary-itemview
         check({}.items(), size('P'))
         # dictionary iterator
         check(iter({}), size('P2nPn'))
+        # dictionary-keyiterator
+        check(iter({}.keys()), size('P2nPn'))
+        # dictionary-valueiterator
+        check(iter({}.values()), size('P2nPn'))
+        # dictionary-itemiterator
+        check(iter({}.items()), size('P2nPn'))
         # dictproxy
         class C(object): pass
         check(C.__dict__, size('P'))
@@ -1049,8 +1070,8 @@ class SizeofTest(unittest.TestCase):
                 check(set(sample), s)
                 check(frozenset(sample), s)
             else:
-                check(set(sample), s + newsize*struct.calcsize('nP'))
-                check(frozenset(sample), s + newsize*struct.calcsize('nP'))
+                check(set(sample), s + newsize*calcsize('nP'))
+                check(frozenset(sample), s + newsize*calcsize('nP'))
         # setiterator
         check(iter(set()), size('P3n'))
         # slice
@@ -1064,11 +1085,15 @@ class SizeofTest(unittest.TestCase):
         # static type: PyTypeObject
         s = vsize('P2n15Pl4Pn9Pn11PIP')
         check(int, s)
-        # (PyTypeObject + PyAsyncMethods + PyNumberMethods + PyMappingMethods +
-        #  PySequenceMethods + PyBufferProcs + 4P)
-        s = vsize('P2n17Pl4Pn9Pn11PIP') + struct.calcsize('34P 3P 3P 10P 2P 4P')
+        s = vsize('P2n15Pl4Pn9Pn11PIP'  # PyTypeObject
+                  '3P'                  # PyAsyncMethods
+                  '36P'                 # PyNumberMethods
+                  '3P'                  # PyMappingMethods
+                  '10P'                 # PySequenceMethods
+                  '2P'                  # PyBufferProcs
+                  '4P')
         # Separate block for PyDictKeysObject with 4 entries
-        s += struct.calcsize("2nPn") + 4*struct.calcsize("n2P")
+        s += calcsize("2nPn") + 4*calcsize("n2P")
         # class
         class newstyleclass(object): pass
         check(newstyleclass, s)
@@ -1112,6 +1137,36 @@ class SizeofTest(unittest.TestCase):
         # weakcallableproxy
         check(weakref.proxy(int), size('2Pn2P'))
 
+    def check_slots(self, obj, base, extra):
+        expected = sys.getsizeof(base) + struct.calcsize(extra)
+        if gc.is_tracked(obj) and not gc.is_tracked(base):
+            expected += self.gc_headsize
+        self.assertEqual(sys.getsizeof(obj), expected)
+
+    def test_slots(self):
+        # check all subclassable types defined in Objects/ that allow
+        # non-empty __slots__
+        check = self.check_slots
+        class BA(bytearray):
+            __slots__ = 'a', 'b', 'c'
+        check(BA(), bytearray(), '3P')
+        class D(dict):
+            __slots__ = 'a', 'b', 'c'
+        check(D(x=[]), {'x': []}, '3P')
+        class L(list):
+            __slots__ = 'a', 'b', 'c'
+        check(L(), [], '3P')
+        class S(set):
+            __slots__ = 'a', 'b', 'c'
+        check(S(), set(), '3P')
+        class FS(frozenset):
+            __slots__ = 'a', 'b', 'c'
+        check(FS(), frozenset(), '3P')
+        from collections import OrderedDict
+        class OD(OrderedDict):
+            __slots__ = 'a', 'b', 'c'
+        check(OD(x=[]), OrderedDict(x=[]), '3P')
+
     def test_pythontypes(self):
         # check all types defined in Python/
         size = test.support.calcobjsize
index bb71acd..a3e1d31 100644 (file)
@@ -164,7 +164,7 @@ class ProfileHookTestCase(TestCaseBase):
                               (1, 'return', g_ident),
                               ])
 
-    def test_exception_propogation(self):
+    def test_exception_propagation(self):
         def f(p):
             1/0
         def g(p):
index ae8f845..509bc3e 100644 (file)
@@ -388,6 +388,15 @@ class TraceTestCase(unittest.TestCase):
              (257, 'line'),
              (257, 'return')])
 
+    def test_17_none_f_trace(self):
+        # Issue 20041: fix TypeError when f_trace is set to None.
+        def func():
+            sys._getframe().f_trace = None
+            lineno = 2
+        self.run_and_compare(func,
+            [(0, 'call'),
+             (1, 'line')])
+
 
 class RaisingTraceFuncTestCase(unittest.TestCase):
     def setUp(self):
index 0917c3e..a23bf06 100644 (file)
@@ -421,6 +421,8 @@ class MakefileTests(unittest.TestCase):
             print("var3=42", file=makefile)
             print("var4=$/invalid", file=makefile)
             print("var5=dollar$$5", file=makefile)
+            print("var6=${var3}/lib/python3.5/config-$(VAR2)$(var5)"
+                  "-x86_64-linux-gnu", file=makefile)
         vars = sysconfig._parse_makefile(TESTFN)
         self.assertEqual(vars, {
             'var1': 'ab42',
@@ -428,6 +430,7 @@ class MakefileTests(unittest.TestCase):
             'var3': 42,
             'var4': '$/invalid',
             'var5': 'dollar$5',
+            'var6': '42/lib/python3.5/config-b42dollar$5-x86_64-linux-gnu',
         })
 
 
index 1412cae..abfb34d 100644 (file)
@@ -1667,9 +1667,7 @@ class PaxWriteTest(GNUWriteTest):
             tar.close()
 
 
-class UstarUnicodeTest(unittest.TestCase):
-
-    format = tarfile.USTAR_FORMAT
+class UnicodeTest:
 
     def test_iso8859_1_filename(self):
         self._test_unicode_filename("iso8859-1")
@@ -1750,7 +1748,86 @@ class UstarUnicodeTest(unittest.TestCase):
             tar.close()
 
 
-class GNUUnicodeTest(UstarUnicodeTest):
+class UstarUnicodeTest(UnicodeTest, unittest.TestCase):
+
+    format = tarfile.USTAR_FORMAT
+
+    # Test whether the utf-8 encoded version of a filename exceeds the 100
+    # bytes name field limit (every occurrence of '\xff' will be expanded to 2
+    # bytes).
+    def test_unicode_name1(self):
+        self._test_ustar_name("0123456789" * 10)
+        self._test_ustar_name("0123456789" * 10 + "0", ValueError)
+        self._test_ustar_name("0123456789" * 9 + "01234567\xff")
+        self._test_ustar_name("0123456789" * 9 + "012345678\xff", ValueError)
+
+    def test_unicode_name2(self):
+        self._test_ustar_name("0123456789" * 9 + "012345\xff\xff")
+        self._test_ustar_name("0123456789" * 9 + "0123456\xff\xff", ValueError)
+
+    # Test whether the utf-8 encoded version of a filename exceeds the 155
+    # bytes prefix + '/' + 100 bytes name limit.
+    def test_unicode_longname1(self):
+        self._test_ustar_name("0123456789" * 15 + "01234/" + "0123456789" * 10)
+        self._test_ustar_name("0123456789" * 15 + "0123/4" + "0123456789" * 10, ValueError)
+        self._test_ustar_name("0123456789" * 15 + "012\xff/" + "0123456789" * 10)
+        self._test_ustar_name("0123456789" * 15 + "0123\xff/" + "0123456789" * 10, ValueError)
+
+    def test_unicode_longname2(self):
+        self._test_ustar_name("0123456789" * 15 + "01\xff/2" + "0123456789" * 10, ValueError)
+        self._test_ustar_name("0123456789" * 15 + "01\xff\xff/" + "0123456789" * 10, ValueError)
+
+    def test_unicode_longname3(self):
+        self._test_ustar_name("0123456789" * 15 + "01\xff\xff/2" + "0123456789" * 10, ValueError)
+        self._test_ustar_name("0123456789" * 15 + "01234/" + "0123456789" * 9 + "01234567\xff")
+        self._test_ustar_name("0123456789" * 15 + "01234/" + "0123456789" * 9 + "012345678\xff", ValueError)
+
+    def test_unicode_longname4(self):
+        self._test_ustar_name("0123456789" * 15 + "01234/" + "0123456789" * 9 + "012345\xff\xff")
+        self._test_ustar_name("0123456789" * 15 + "01234/" + "0123456789" * 9 + "0123456\xff\xff", ValueError)
+
+    def _test_ustar_name(self, name, exc=None):
+        with tarfile.open(tmpname, "w", format=self.format, encoding="utf-8") as tar:
+            t = tarfile.TarInfo(name)
+            if exc is None:
+                tar.addfile(t)
+            else:
+                self.assertRaises(exc, tar.addfile, t)
+
+        if exc is None:
+            with tarfile.open(tmpname, "r", encoding="utf-8") as tar:
+                for t in tar:
+                    self.assertEqual(name, t.name)
+                    break
+
+    # Test the same as above for the 100 bytes link field.
+    def test_unicode_link1(self):
+        self._test_ustar_link("0123456789" * 10)
+        self._test_ustar_link("0123456789" * 10 + "0", ValueError)
+        self._test_ustar_link("0123456789" * 9 + "01234567\xff")
+        self._test_ustar_link("0123456789" * 9 + "012345678\xff", ValueError)
+
+    def test_unicode_link2(self):
+        self._test_ustar_link("0123456789" * 9 + "012345\xff\xff")
+        self._test_ustar_link("0123456789" * 9 + "0123456\xff\xff", ValueError)
+
+    def _test_ustar_link(self, name, exc=None):
+        with tarfile.open(tmpname, "w", format=self.format, encoding="utf-8") as tar:
+            t = tarfile.TarInfo("foo")
+            t.linkname = name
+            if exc is None:
+                tar.addfile(t)
+            else:
+                self.assertRaises(exc, tar.addfile, t)
+
+        if exc is None:
+            with tarfile.open(tmpname, "r", encoding="utf-8") as tar:
+                for t in tar:
+                    self.assertEqual(name, t.linkname)
+                    break
+
+
+class GNUUnicodeTest(UnicodeTest, unittest.TestCase):
 
     format = tarfile.GNU_FORMAT
 
@@ -1768,7 +1845,7 @@ class GNUUnicodeTest(UstarUnicodeTest):
                     self.fail("unable to read bad GNU tar pax header")
 
 
-class PAXUnicodeTest(UstarUnicodeTest):
+class PAXUnicodeTest(UnicodeTest, unittest.TestCase):
 
     format = tarfile.PAX_FORMAT
 
index 25f6ede..8ffd185 100644 (file)
@@ -649,6 +649,8 @@ class TclTest(unittest.TestCase):
                 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
             self.assertEqual(splitdict(tcl, arg), expected)
 
+    def test_new_tcl_obj(self):
+        self.assertRaises(TypeError, _tkinter.Tcl_Obj)
 
 class BigmemTclTest(unittest.TestCase):
 
index 524bba3..8e219f4 100644 (file)
@@ -4,8 +4,8 @@ import telnetlib
 import time
 import contextlib
 
-from unittest import TestCase
 from test import support
+import unittest
 threading = support.import_module('threading')
 
 HOST = support.HOST
@@ -21,7 +21,7 @@ def server(evt, serv):
     finally:
         serv.close()
 
-class GeneralTests(TestCase):
+class GeneralTests(unittest.TestCase):
 
     def setUp(self):
         self.evt = threading.Event()
@@ -165,7 +165,7 @@ def test_telnet(reads=(), cls=TelnetAlike):
         telnet._messages = '' # debuglevel output
     return telnet
 
-class ExpectAndReadTestCase(TestCase):
+class ExpectAndReadTestCase(unittest.TestCase):
     def setUp(self):
         self.old_selector = telnetlib._TelnetSelector
         telnetlib._TelnetSelector = MockSelector
@@ -237,8 +237,8 @@ class ReadTests(ExpectAndReadTestCase):
         self.assertEqual(data, want)
 
     def test_read_eager(self):
-        # read_eager and read_very_eager make the same gaurantees
-        # (they behave differently but we only test the gaurantees)
+        # read_eager and read_very_eager make the same guarantees
+        # (they behave differently but we only test the guarantees)
         self._read_eager('read_eager')
         self._read_eager('read_very_eager')
         # NB -- we need to test the IAC block which is mentioned in the
@@ -284,7 +284,7 @@ class nego_collector(object):
 
 tl = telnetlib
 
-class WriteTests(TestCase):
+class WriteTests(unittest.TestCase):
     '''The only thing that write does is replace each tl.IAC for
     tl.IAC+tl.IAC'''
 
@@ -300,7 +300,7 @@ class WriteTests(TestCase):
             written = b''.join(telnet.sock.writes)
             self.assertEqual(data.replace(tl.IAC,tl.IAC+tl.IAC), written)
 
-class OptionTests(TestCase):
+class OptionTests(unittest.TestCase):
     # RFC 854 commands
     cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP]
 
index 4a077cc..51df1ec 100644 (file)
@@ -948,8 +948,16 @@ class TestNamedTemporaryFile(BaseTestCase):
                 self.assertRaises(ValueError, tempfile.NamedTemporaryFile)
                 self.assertEqual(len(closed), 1)
 
-    # How to test the mode and bufsize parameters?
+    def test_bad_mode(self):
+        dir = tempfile.mkdtemp()
+        self.addCleanup(support.rmtree, dir)
+        with self.assertRaises(ValueError):
+            tempfile.NamedTemporaryFile(mode='wr', dir=dir)
+        with self.assertRaises(TypeError):
+            tempfile.NamedTemporaryFile(mode=2, dir=dir)
+        self.assertEqual(os.listdir(dir), [])
 
+    # How to test the mode and bufsize parameters?
 
 class TestSpooledTemporaryFile(BaseTestCase):
     """Test SpooledTemporaryFile()."""
index 3b11bf6..b49a961 100644 (file)
@@ -58,7 +58,7 @@ class TestThread(threading.Thread):
                 self.nrunning.inc()
                 if verbose:
                     print(self.nrunning.get(), 'tasks are running')
-                self.testcase.assertTrue(self.nrunning.get() <= 3)
+                self.testcase.assertLessEqual(self.nrunning.get(), 3)
 
             time.sleep(delay)
             if verbose:
@@ -66,7 +66,7 @@ class TestThread(threading.Thread):
 
             with self.mutex:
                 self.nrunning.dec()
-                self.testcase.assertTrue(self.nrunning.get() >= 0)
+                self.testcase.assertGreaterEqual(self.nrunning.get(), 0)
                 if verbose:
                     print('%s is finished. %d tasks are running' %
                           (self.name, self.nrunning.get()))
@@ -100,26 +100,25 @@ class ThreadTests(BaseTestCase):
         for i in range(NUMTASKS):
             t = TestThread("<thread %d>"%i, self, sema, mutex, numrunning)
             threads.append(t)
-            self.assertEqual(t.ident, None)
-            self.assertTrue(re.match('<TestThread\(.*, initial\)>', repr(t)))
+            self.assertIsNone(t.ident)
+            self.assertRegex(repr(t), r'^<TestThread\(.*, initial\)>$')
             t.start()
 
         if verbose:
             print('waiting for all tasks to complete')
         for t in threads:
             t.join()
-            self.assertTrue(not t.is_alive())
+            self.assertFalse(t.is_alive())
             self.assertNotEqual(t.ident, 0)
-            self.assertFalse(t.ident is None)
-            self.assertTrue(re.match('<TestThread\(.*, stopped -?\d+\)>',
-                                     repr(t)))
+            self.assertIsNotNone(t.ident)
+            self.assertRegex(repr(t), r'^<TestThread\(.*, stopped -?\d+\)>$')
         if verbose:
             print('all tasks done')
         self.assertEqual(numrunning.get(), 0)
 
     def test_ident_of_no_threading_threads(self):
         # The ident still must work for the main thread and dummy threads.
-        self.assertFalse(threading.currentThread().ident is None)
+        self.assertIsNotNone(threading.currentThread().ident)
         def f():
             ident.append(threading.currentThread().ident)
             done.set()
@@ -127,7 +126,7 @@ class ThreadTests(BaseTestCase):
         ident = []
         _thread.start_new_thread(f, ())
         done.wait()
-        self.assertFalse(ident[0] is None)
+        self.assertIsNotNone(ident[0])
         # Kill the "immortal" _DummyThread
         del threading._active[ident[0]]
 
@@ -244,7 +243,7 @@ class ThreadTests(BaseTestCase):
         self.assertTrue(ret)
         if verbose:
             print("    verifying worker hasn't exited")
-        self.assertTrue(not t.finished)
+        self.assertFalse(t.finished)
         if verbose:
             print("    attempting to raise asynch exception in worker")
         result = set_async_exc(ctypes.c_long(t.id), exception)
@@ -415,9 +414,9 @@ class ThreadTests(BaseTestCase):
 
     def test_repr_daemon(self):
         t = threading.Thread()
-        self.assertFalse('daemon' in repr(t))
+        self.assertNotIn('daemon', repr(t))
         t.daemon = True
-        self.assertTrue('daemon' in repr(t))
+        self.assertIn('daemon', repr(t))
 
     def test_deamon_param(self):
         t = threading.Thread()
@@ -569,7 +568,7 @@ class ThreadTests(BaseTestCase):
         tstate_lock.release()
         self.assertFalse(t.is_alive())
         # And verify the thread disposed of _tstate_lock.
-        self.assertTrue(t._tstate_lock is None)
+        self.assertIsNone(t._tstate_lock)
 
     def test_repr_stopped(self):
         # Verify that "stopped" shows up in repr(Thread) appropriately.
@@ -1083,7 +1082,7 @@ class EventTests(lock_tests.EventTests):
     eventtype = staticmethod(threading.Event)
 
 class ConditionAsRLockTests(lock_tests.RLockTests):
-    # An Condition uses an RLock by default and exports its API.
+    # Condition uses an RLock by default and exports its API.
     locktype = staticmethod(threading.Condition)
 
 class ConditionTests(lock_tests.ConditionTests):
index c7f394c..4092cf3 100644 (file)
@@ -189,7 +189,7 @@ class BaseLocalTest:
         wr = weakref.ref(x)
         del x
         gc.collect()
-        self.assertIs(wr(), None)
+        self.assertIsNone(wr())
 
 
 class ThreadLocalTest(unittest.TestCase, BaseLocalTest):
index 845a2a8..0c294ec 100644 (file)
@@ -22,7 +22,7 @@ class Gprof2htmlTests(unittest.TestCase):
         sys.argv = []
 
     def test_gprof(self):
-        # Issue #14508: this used to fail with an NameError.
+        # Issue #14508: this used to fail with a NameError.
         with mock.patch.object(self.gprof, 'webbrowser') as wmock, \
                 tempfile.TemporaryDirectory() as tmpdir:
             fn = os.path.join(tmpdir, 'abc')
index 976a6c5..734bbc2 100644 (file)
@@ -250,6 +250,11 @@ class UnparseTestCase(ASTTestCase):
     def test_with_two_items(self):
         self.check_roundtrip(with_two_items)
 
+    def test_dict_unpacking_in_dict(self):
+        # See issue 26489
+        self.check_roundtrip(r"""{**{'y': 2}, 'x': 1}""")
+        self.check_roundtrip(r"""{**{'y': 2}, **{'x': 1}}""")
+
 
 class DirectoryTestCase(ASTTestCase):
     """Test roundtrip behaviour on all files in Lib and Lib/test."""
index f65e361..da89a9a 100644 (file)
@@ -253,7 +253,7 @@ class TestTracemallocEnabled(unittest.TestCase):
         snapshot.dump(support.TESTFN)
         self.addCleanup(support.unlink, support.TESTFN)
 
-        # load() should recreates the attribute
+        # load() should recreate the attribute
         snapshot2 = tracemalloc.Snapshot.load(support.TESTFN)
         self.assertEqual(snapshot2.test_attr, "new")
 
index fb113ab..5d1fcf6 100644 (file)
@@ -1,4 +1,5 @@
 from test import support, seq_tests
+import unittest
 
 import gc
 import pickle
diff --git a/Lib/test/test_turtle.py b/Lib/test/test_turtle.py
new file mode 100644 (file)
index 0000000..2fd10cc
--- /dev/null
@@ -0,0 +1,436 @@
+import pickle
+import unittest
+from test import support
+
+turtle = support.import_module('turtle')
+Vec2D = turtle.Vec2D
+
+test_config = """\
+width = 0.75
+height = 0.8
+canvwidth = 500
+canvheight = 200
+leftright = 100
+topbottom = 100
+mode = world
+colormode = 255
+delay = 100
+undobuffersize = 10000
+shape = circle
+pencolor  = red
+fillcolor  = blue
+resizemode  = auto
+visible  = None
+language = english
+exampleturtle = turtle
+examplescreen = screen
+title = Python Turtle Graphics
+using_IDLE = ''
+"""
+
+test_config_two = """\
+# Comments!
+# Testing comments!
+pencolor  = red
+fillcolor  = blue
+visible  = False
+language = english
+# Some more
+# comments
+using_IDLE = False
+"""
+
+invalid_test_config = """
+pencolor = red
+fillcolor: blue
+visible = False
+"""
+
+
+class TurtleConfigTest(unittest.TestCase):
+
+    def get_cfg_file(self, cfg_str):
+        self.addCleanup(support.unlink, support.TESTFN)
+        with open(support.TESTFN, 'w') as f:
+            f.write(cfg_str)
+        return support.TESTFN
+
+    def test_config_dict(self):
+
+        cfg_name = self.get_cfg_file(test_config)
+        parsed_cfg = turtle.config_dict(cfg_name)
+
+        expected = {
+            'width' : 0.75,
+            'height' : 0.8,
+            'canvwidth' : 500,
+            'canvheight': 200,
+            'leftright': 100,
+            'topbottom': 100,
+            'mode': 'world',
+            'colormode': 255,
+            'delay': 100,
+            'undobuffersize': 10000,
+            'shape': 'circle',
+            'pencolor' : 'red',
+            'fillcolor' : 'blue',
+            'resizemode' : 'auto',
+            'visible' : None,
+            'language': 'english',
+            'exampleturtle': 'turtle',
+            'examplescreen': 'screen',
+            'title': 'Python Turtle Graphics',
+            'using_IDLE': '',
+        }
+
+        self.assertEqual(parsed_cfg, expected)
+
+    def test_partial_config_dict_with_commments(self):
+
+        cfg_name = self.get_cfg_file(test_config_two)
+        parsed_cfg = turtle.config_dict(cfg_name)
+
+        expected = {
+            'pencolor': 'red',
+            'fillcolor': 'blue',
+            'visible': False,
+            'language': 'english',
+            'using_IDLE': False,
+        }
+
+        self.assertEqual(parsed_cfg, expected)
+
+    def test_config_dict_invalid(self):
+
+        cfg_name = self.get_cfg_file(invalid_test_config)
+
+        with support.captured_stdout() as stdout:
+            parsed_cfg = turtle.config_dict(cfg_name)
+
+        err_msg = stdout.getvalue()
+
+        self.assertIn('Bad line in config-file ', err_msg)
+        self.assertIn('fillcolor: blue', err_msg)
+
+        self.assertEqual(parsed_cfg, {
+            'pencolor': 'red',
+            'visible': False,
+        })
+
+
+class VectorComparisonMixin:
+
+    def assertVectorsAlmostEqual(self, vec1, vec2):
+        if len(vec1) != len(vec2):
+            self.fail("Tuples are not of equal size")
+        for idx, (i, j) in enumerate(zip(vec1, vec2)):
+            self.assertAlmostEqual(
+                i, j, msg='values at index {} do not match'.format(idx))
+
+
+class TestVec2D(VectorComparisonMixin, unittest.TestCase):
+
+    def test_constructor(self):
+        vec = Vec2D(0.5, 2)
+        self.assertEqual(vec[0], 0.5)
+        self.assertEqual(vec[1], 2)
+        self.assertIsInstance(vec, Vec2D)
+
+        self.assertRaises(TypeError, Vec2D)
+        self.assertRaises(TypeError, Vec2D, 0)
+        self.assertRaises(TypeError, Vec2D, (0, 1))
+        self.assertRaises(TypeError, Vec2D, vec)
+        self.assertRaises(TypeError, Vec2D, 0, 1, 2)
+
+    def test_repr(self):
+        vec = Vec2D(0.567, 1.234)
+        self.assertEqual(repr(vec), '(0.57,1.23)')
+
+    def test_equality(self):
+        vec1 = Vec2D(0, 1)
+        vec2 = Vec2D(0.0, 1)
+        vec3 = Vec2D(42, 1)
+        self.assertEqual(vec1, vec2)
+        self.assertEqual(vec1, tuple(vec1))
+        self.assertEqual(tuple(vec1), vec1)
+        self.assertNotEqual(vec1, vec3)
+        self.assertNotEqual(vec2, vec3)
+
+    def test_pickling(self):
+        vec = Vec2D(0.5, 2)
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            with self.subTest(proto=proto):
+                pickled = pickle.dumps(vec, protocol=proto)
+                unpickled = pickle.loads(pickled)
+                self.assertEqual(unpickled, vec)
+                self.assertIsInstance(unpickled, Vec2D)
+
+    def _assert_arithmetic_cases(self, test_cases, lambda_operator):
+        for test_case in test_cases:
+            with self.subTest(case=test_case):
+
+                ((first, second), expected) = test_case
+
+                op1 = Vec2D(*first)
+                op2 = Vec2D(*second)
+
+                result = lambda_operator(op1, op2)
+
+                expected = Vec2D(*expected)
+
+                self.assertVectorsAlmostEqual(result, expected)
+
+    def test_vector_addition(self):
+
+        test_cases = [
+            (((0, 0), (1, 1)), (1.0, 1.0)),
+            (((-1, 0), (2, 2)), (1, 2)),
+            (((1.5, 0), (1, 1)), (2.5, 1)),
+        ]
+
+        self._assert_arithmetic_cases(test_cases, lambda x, y: x + y)
+
+    def test_vector_subtraction(self):
+
+        test_cases = [
+            (((0, 0), (1, 1)), (-1, -1)),
+            (((10.625, 0.125), (10, 0)), (0.625, 0.125)),
+        ]
+
+        self._assert_arithmetic_cases(test_cases, lambda x, y: x - y)
+
+    def test_vector_multiply(self):
+
+        vec1 = Vec2D(10, 10)
+        vec2 = Vec2D(0.5, 3)
+        answer = vec1 * vec2
+        expected = 35
+        self.assertAlmostEqual(answer, expected)
+
+        vec = Vec2D(0.5, 3)
+        answer = vec * 10
+        expected = Vec2D(5, 30)
+        self.assertVectorsAlmostEqual(answer, expected)
+
+    def test_vector_negative(self):
+        vec = Vec2D(10, -10)
+        expected = (-10, 10)
+        self.assertVectorsAlmostEqual(-vec, expected)
+
+    def test_distance(self):
+        vec = Vec2D(6, 8)
+        expected = 10
+        self.assertEqual(abs(vec), expected)
+
+        vec = Vec2D(0, 0)
+        expected = 0
+        self.assertEqual(abs(vec), expected)
+
+        vec = Vec2D(2.5, 6)
+        expected = 6.5
+        self.assertEqual(abs(vec), expected)
+
+    def test_rotate(self):
+
+        cases = [
+            (((0, 0), 0), (0, 0)),
+            (((0, 1), 90), (-1, 0)),
+            (((0, 1), -90), (1, 0)),
+            (((1, 0), 180), (-1, 0)),
+            (((1, 0), 360), (1, 0)),
+        ]
+
+        for case in cases:
+            with self.subTest(case=case):
+                (vec, rot), expected = case
+                vec = Vec2D(*vec)
+                got = vec.rotate(rot)
+                self.assertVectorsAlmostEqual(got, expected)
+
+
+class TestTNavigator(VectorComparisonMixin, unittest.TestCase):
+
+    def setUp(self):
+        self.nav = turtle.TNavigator()
+
+    def test_goto(self):
+        self.nav.goto(100, -100)
+        self.assertAlmostEqual(self.nav.xcor(), 100)
+        self.assertAlmostEqual(self.nav.ycor(), -100)
+
+    def test_pos(self):
+        self.assertEqual(self.nav.pos(), self.nav._position)
+        self.nav.goto(100, -100)
+        self.assertEqual(self.nav.pos(), self.nav._position)
+
+    def test_left(self):
+        self.assertEqual(self.nav._orient, (1.0, 0))
+        self.nav.left(90)
+        self.assertVectorsAlmostEqual(self.nav._orient, (0.0, 1.0))
+
+    def test_right(self):
+        self.assertEqual(self.nav._orient, (1.0, 0))
+        self.nav.right(90)
+        self.assertVectorsAlmostEqual(self.nav._orient, (0, -1.0))
+
+    def test_reset(self):
+        self.nav.goto(100, -100)
+        self.assertAlmostEqual(self.nav.xcor(), 100)
+        self.assertAlmostEqual(self.nav.ycor(), -100)
+        self.nav.reset()
+        self.assertAlmostEqual(self.nav.xcor(), 0)
+        self.assertAlmostEqual(self.nav.ycor(), 0)
+
+    def test_forward(self):
+        self.nav.forward(150)
+        expected = Vec2D(150, 0)
+        self.assertVectorsAlmostEqual(self.nav.position(), expected)
+
+        self.nav.reset()
+        self.nav.left(90)
+        self.nav.forward(150)
+        expected = Vec2D(0, 150)
+        self.assertVectorsAlmostEqual(self.nav.position(), expected)
+
+        self.assertRaises(TypeError, self.nav.forward, 'skldjfldsk')
+
+    def test_backwards(self):
+        self.nav.back(200)
+        expected = Vec2D(-200, 0)
+        self.assertVectorsAlmostEqual(self.nav.position(), expected)
+
+        self.nav.reset()
+        self.nav.right(90)
+        self.nav.back(200)
+        expected = Vec2D(0, 200)
+        self.assertVectorsAlmostEqual(self.nav.position(), expected)
+
+    def test_distance(self):
+        self.nav.forward(100)
+        expected = 100
+        self.assertAlmostEqual(self.nav.distance(Vec2D(0,0)), expected)
+
+    def test_radians_and_degrees(self):
+        self.nav.left(90)
+        self.assertAlmostEqual(self.nav.heading(), 90)
+        self.nav.radians()
+        self.assertAlmostEqual(self.nav.heading(), 1.57079633)
+        self.nav.degrees()
+        self.assertAlmostEqual(self.nav.heading(), 90)
+
+    def test_towards(self):
+
+        coordinates = [
+            # coordinates, expected
+            ((100, 0), 0.0),
+            ((100, 100), 45.0),
+            ((0, 100), 90.0),
+            ((-100, 100), 135.0),
+            ((-100, 0), 180.0),
+            ((-100, -100), 225.0),
+            ((0, -100), 270.0),
+            ((100, -100), 315.0),
+        ]
+
+        for (x, y), expected in coordinates:
+            self.assertEqual(self.nav.towards(x, y), expected)
+            self.assertEqual(self.nav.towards((x, y)), expected)
+            self.assertEqual(self.nav.towards(Vec2D(x, y)), expected)
+
+    def test_heading(self):
+
+        self.nav.left(90)
+        self.assertAlmostEqual(self.nav.heading(), 90)
+        self.nav.left(45)
+        self.assertAlmostEqual(self.nav.heading(), 135)
+        self.nav.right(1.6)
+        self.assertAlmostEqual(self.nav.heading(), 133.4)
+        self.assertRaises(TypeError, self.nav.right, 'sdkfjdsf')
+        self.nav.reset()
+
+        rotations = [10, 20, 170, 300]
+        result = sum(rotations) % 360
+        for num in rotations:
+            self.nav.left(num)
+        self.assertEqual(self.nav.heading(), result)
+        self.nav.reset()
+
+        result = (360-sum(rotations)) % 360
+        for num in rotations:
+            self.nav.right(num)
+        self.assertEqual(self.nav.heading(), result)
+        self.nav.reset()
+
+        rotations = [10, 20, -170, 300, -210, 34.3, -50.2, -10, -29.98, 500]
+        sum_so_far = 0
+        for num in rotations:
+            if num < 0:
+                self.nav.right(abs(num))
+            else:
+                self.nav.left(num)
+            sum_so_far += num
+            self.assertAlmostEqual(self.nav.heading(), sum_so_far % 360)
+
+    def test_setheading(self):
+        self.nav.setheading(102.32)
+        self.assertAlmostEqual(self.nav.heading(), 102.32)
+        self.nav.setheading(-123.23)
+        self.assertAlmostEqual(self.nav.heading(), (-123.23) % 360)
+        self.nav.setheading(-1000.34)
+        self.assertAlmostEqual(self.nav.heading(), (-1000.34) % 360)
+        self.nav.setheading(300000)
+        self.assertAlmostEqual(self.nav.heading(), 300000%360)
+
+    def test_positions(self):
+        self.nav.forward(100)
+        self.nav.left(90)
+        self.nav.forward(-200)
+        self.assertVectorsAlmostEqual(self.nav.pos(), (100.0, -200.0))
+
+    def test_setx_and_sety(self):
+        self.nav.setx(-1023.2334)
+        self.nav.sety(193323.234)
+        self.assertVectorsAlmostEqual(self.nav.pos(), (-1023.2334, 193323.234))
+
+    def test_home(self):
+        self.nav.left(30)
+        self.nav.forward(-100000)
+        self.nav.home()
+        self.assertVectorsAlmostEqual(self.nav.pos(), (0,0))
+        self.assertAlmostEqual(self.nav.heading(), 0)
+
+    def test_distance_method(self):
+        self.assertAlmostEqual(self.nav.distance(30, 40), 50)
+        vec = Vec2D(0.22, .001)
+        self.assertAlmostEqual(self.nav.distance(vec), 0.22000227271553355)
+        another_turtle = turtle.TNavigator()
+        another_turtle.left(90)
+        another_turtle.forward(10000)
+        self.assertAlmostEqual(self.nav.distance(another_turtle), 10000)
+
+
+class TestTPen(unittest.TestCase):
+
+    def test_pendown_and_penup(self):
+
+        tpen = turtle.TPen()
+
+        self.assertTrue(tpen.isdown())
+        tpen.penup()
+        self.assertFalse(tpen.isdown())
+        tpen.pendown()
+        self.assertTrue(tpen.isdown())
+
+    def test_showturtle_hideturtle_and_isvisible(self):
+
+        tpen = turtle.TPen()
+
+        self.assertTrue(tpen.isvisible())
+        tpen.hideturtle()
+        self.assertFalse(tpen.isvisible())
+        tpen.showturtle()
+        self.assertTrue(tpen.isvisible())
+
+
+if __name__ == '__main__':
+    unittest.main()
index 060119a..a7f8dd5 100644 (file)
@@ -1,7 +1,9 @@
+import contextlib
+import collections
 import pickle
 import re
 import sys
-from unittest import TestCase, main
+from unittest import TestCase, main, skipUnless, SkipTest
 
 from typing import Any
 from typing import TypeVar, AnyStr
@@ -13,12 +15,31 @@ from typing import Generic
 from typing import cast
 from typing import get_type_hints
 from typing import no_type_check, no_type_check_decorator
+from typing import Type
+from typing import NewType
 from typing import NamedTuple
 from typing import IO, TextIO, BinaryIO
 from typing import Pattern, Match
 import typing
 
 
+class BaseTestCase(TestCase):
+
+    def assertIsSubclass(self, cls, class_or_tuple, msg=None):
+        if not issubclass(cls, class_or_tuple):
+            message = '%r is not a subclass of %r' % (cls, class_or_tuple)
+            if msg is not None:
+                message += ' : %s' % msg
+            raise self.failureException(message)
+
+    def assertNotIsSubclass(self, cls, class_or_tuple, msg=None):
+        if issubclass(cls, class_or_tuple):
+            message = '%r is a subclass of %r' % (cls, class_or_tuple)
+            if msg is not None:
+                message += ' : %s' % msg
+            raise self.failureException(message)
+
+
 class Employee:
     pass
 
@@ -35,7 +56,7 @@ class ManagingFounder(Manager, Founder):
     pass
 
 
-class AnyTests(TestCase):
+class AnyTests(BaseTestCase):
 
     def test_any_instance_type_error(self):
         with self.assertRaises(TypeError):
@@ -78,40 +99,40 @@ class AnyTests(TestCase):
 
     def test_any_is_subclass(self):
         # Any should be considered a subclass of everything.
-        assert issubclass(Any, Any)
-        assert issubclass(Any, typing.List)
-        assert issubclass(Any, typing.List[int])
-        assert issubclass(Any, typing.List[T])
-        assert issubclass(Any, typing.Mapping)
-        assert issubclass(Any, typing.Mapping[str, int])
-        assert issubclass(Any, typing.Mapping[KT, VT])
-        assert issubclass(Any, Generic)
-        assert issubclass(Any, Generic[T])
-        assert issubclass(Any, Generic[KT, VT])
-        assert issubclass(Any, AnyStr)
-        assert issubclass(Any, Union)
-        assert issubclass(Any, Union[int, str])
-        assert issubclass(Any, typing.Match)
-        assert issubclass(Any, typing.Match[str])
+        self.assertIsSubclass(Any, Any)
+        self.assertIsSubclass(Any, typing.List)
+        self.assertIsSubclass(Any, typing.List[int])
+        self.assertIsSubclass(Any, typing.List[T])
+        self.assertIsSubclass(Any, typing.Mapping)
+        self.assertIsSubclass(Any, typing.Mapping[str, int])
+        self.assertIsSubclass(Any, typing.Mapping[KT, VT])
+        self.assertIsSubclass(Any, Generic)
+        self.assertIsSubclass(Any, Generic[T])
+        self.assertIsSubclass(Any, Generic[KT, VT])
+        self.assertIsSubclass(Any, AnyStr)
+        self.assertIsSubclass(Any, Union)
+        self.assertIsSubclass(Any, Union[int, str])
+        self.assertIsSubclass(Any, typing.Match)
+        self.assertIsSubclass(Any, typing.Match[str])
         # These expressions must simply not fail.
         typing.Match[Any]
         typing.Pattern[Any]
         typing.IO[Any]
 
 
-class TypeVarTests(TestCase):
+class TypeVarTests(BaseTestCase):
 
     def test_basic_plain(self):
         T = TypeVar('T')
         # Every class is a subclass of T.
-        assert issubclass(int, T)
-        assert issubclass(str, T)
+        self.assertIsSubclass(int, T)
+        self.assertIsSubclass(str, T)
         # T equals itself.
-        assert T == T
+        self.assertEqual(T, T)
         # T is a subclass of itself.
-        assert issubclass(T, T)
+        self.assertIsSubclass(T, T)
         # T is an instance of TypeVar
-        assert isinstance(T, TypeVar)
+        self.assertIsInstance(T, TypeVar)
 
     def test_typevar_instance_type_error(self):
         T = TypeVar('T')
@@ -121,33 +142,34 @@ class TypeVarTests(TestCase):
     def test_basic_constrained(self):
         A = TypeVar('A', str, bytes)
         # Only str and bytes are subclasses of A.
-        assert issubclass(str, A)
-        assert issubclass(bytes, A)
-        assert not issubclass(int, A)
+        self.assertIsSubclass(str, A)
+        self.assertIsSubclass(bytes, A)
+        self.assertNotIsSubclass(int, A)
         # A equals itself.
-        assert A == A
+        self.assertEqual(A, A)
         # A is a subclass of itself.
-        assert issubclass(A, A)
+        self.assertIsSubclass(A, A)
 
     def test_constrained_error(self):
         with self.assertRaises(TypeError):
             X = TypeVar('X', int)
+            X
 
     def test_union_unique(self):
         X = TypeVar('X')
         Y = TypeVar('Y')
-        assert X != Y
-        assert Union[X] == X
-        assert Union[X] != Union[X, Y]
-        assert Union[X, X] == X
-        assert Union[X, int] != Union[X]
-        assert Union[X, int] != Union[int]
-        assert Union[X, int].__union_params__ == (X, int)
-        assert Union[X, int].__union_set_params__ == {X, int}
+        self.assertNotEqual(X, Y)
+        self.assertEqual(Union[X], X)
+        self.assertNotEqual(Union[X], Union[X, Y])
+        self.assertEqual(Union[X, X], X)
+        self.assertNotEqual(Union[X, int], Union[X])
+        self.assertNotEqual(Union[X, int], Union[int])
+        self.assertEqual(Union[X, int].__union_params__, (X, int))
+        self.assertEqual(Union[X, int].__union_set_params__, {X, int})
 
     def test_union_constrained(self):
         A = TypeVar('A', str, bytes)
-        assert Union[A, str] != Union[A]
+        self.assertNotEqual(Union[A, str], Union[A])
 
     def test_repr(self):
         self.assertEqual(repr(T), '~T')
@@ -192,9 +214,9 @@ class TypeVarTests(TestCase):
 
     def test_bound(self):
         X = TypeVar('X', bound=Employee)
-        assert issubclass(Employee, X)
-        assert issubclass(Manager, X)
-        assert not issubclass(int, X)
+        self.assertIsSubclass(Employee, X)
+        self.assertIsSubclass(Manager, X)
+        self.assertNotIsSubclass(int, X)
 
     def test_bound_errors(self):
         with self.assertRaises(TypeError):
@@ -203,7 +225,7 @@ class TypeVarTests(TestCase):
             TypeVar('X', str, float, bound=Employee)
 
 
-class UnionTests(TestCase):
+class UnionTests(BaseTestCase):
 
     def test_basics(self):
         u = Union[int, float]
@@ -306,8 +328,8 @@ class UnionTests(TestCase):
             Union[()]
 
     def test_issubclass_union(self):
-        assert issubclass(Union[int, str], Union)
-        assert not issubclass(int, Union)
+        self.assertIsSubclass(Union[int, str], Union)
+        self.assertNotIsSubclass(int, Union)
 
     def test_union_instance_type_error(self):
         with self.assertRaises(TypeError):
@@ -316,23 +338,38 @@ class UnionTests(TestCase):
     def test_union_str_pattern(self):
         # Shouldn't crash; see http://bugs.python.org/issue25390
         A = Union[str, Pattern]
+        A
+
+    def test_etree(self):
+        # See https://github.com/python/typing/issues/229
+        # (Only relevant for Python 2.)
+        try:
+            from xml.etree.cElementTree import Element
+        except ImportError:
+            raise SkipTest("cElementTree not found")
+        Union[Element, str]  # Shouldn't crash
+
+        def Elem(*args):
+            return Element(*args)
 
+        Union[Elem, str]  # Nor should this
 
-class TypeVarUnionTests(TestCase):
+
+class TypeVarUnionTests(BaseTestCase):
 
     def test_simpler(self):
         A = TypeVar('A', int, str, float)
         B = TypeVar('B', int, str)
-        assert issubclass(A, A)
-        assert issubclass(B, B)
-        assert not issubclass(B, A)
-        assert issubclass(A, Union[int, str, float])
-        assert not issubclass(Union[int, str, float], A)
-        assert not issubclass(Union[int, str], B)
-        assert issubclass(B, Union[int, str])
-        assert not issubclass(A, B)
-        assert not issubclass(Union[int, str, float], B)
-        assert not issubclass(A, Union[int, str])
+        self.assertIsSubclass(A, A)
+        self.assertIsSubclass(B, B)
+        self.assertNotIsSubclass(B, A)
+        self.assertIsSubclass(A, Union[int, str, float])
+        self.assertNotIsSubclass(Union[int, str, float], A)
+        self.assertNotIsSubclass(Union[int, str], B)
+        self.assertIsSubclass(B, Union[int, str])
+        self.assertNotIsSubclass(A, B)
+        self.assertNotIsSubclass(Union[int, str, float], B)
+        self.assertNotIsSubclass(A, Union[int, str])
 
     def test_var_union_subclass(self):
         self.assertTrue(issubclass(T, Union[int, T]))
@@ -340,11 +377,11 @@ class TypeVarUnionTests(TestCase):
 
     def test_var_union(self):
         TU = TypeVar('TU', Union[int, float], None)
-        assert issubclass(int, TU)
-        assert issubclass(float, TU)
+        self.assertIsSubclass(int, TU)
+        self.assertIsSubclass(float, TU)
 
 
-class TupleTests(TestCase):
+class TupleTests(BaseTestCase):
 
     def test_basics(self):
         self.assertTrue(issubclass(Tuple[int, str], Tuple))
@@ -356,6 +393,12 @@ class TupleTests(TestCase):
         self.assertTrue(issubclass(tuple, Tuple))
         self.assertFalse(issubclass(Tuple, tuple))  # Can't have it both ways.
 
+    def test_equality(self):
+        self.assertEqual(Tuple[int], Tuple[int])
+        self.assertEqual(Tuple[int, ...], Tuple[int, ...])
+        self.assertNotEqual(Tuple[int], Tuple[int, int])
+        self.assertNotEqual(Tuple[int], Tuple[int, ...])
+
     def test_tuple_subclass(self):
         class MyTuple(tuple):
             pass
@@ -375,14 +418,14 @@ class TupleTests(TestCase):
         class C(B):
             pass
 
-        assert not issubclass(Tuple[B], Tuple[B, ...])
-        assert issubclass(Tuple[C, ...], Tuple[B, ...])
-        assert not issubclass(Tuple[C, ...], Tuple[B])
-        assert not issubclass(Tuple[C], Tuple[B, ...])
+        self.assertNotIsSubclass(Tuple[B], Tuple[B, ...])
+        self.assertIsSubclass(Tuple[C, ...], Tuple[B, ...])
+        self.assertNotIsSubclass(Tuple[C, ...], Tuple[B])
+        self.assertNotIsSubclass(Tuple[C], Tuple[B, ...])
 
     def test_repr(self):
         self.assertEqual(repr(Tuple), 'typing.Tuple')
-        self.assertEqual(repr(Tuple[()]), 'typing.Tuple[]')
+        self.assertEqual(repr(Tuple[()]), 'typing.Tuple[()]')
         self.assertEqual(repr(Tuple[int, float]), 'typing.Tuple[int, float]')
         self.assertEqual(repr(Tuple[int, ...]), 'typing.Tuple[int, ...]')
 
@@ -393,7 +436,7 @@ class TupleTests(TestCase):
             issubclass(42, Tuple[int])
 
 
-class CallableTests(TestCase):
+class CallableTests(BaseTestCase):
 
     def test_self_subclass(self):
         self.assertTrue(issubclass(Callable[[int], int], Callable))
@@ -438,20 +481,20 @@ class CallableTests(TestCase):
     def test_callable_instance_works(self):
         def f():
             pass
-        assert isinstance(f, Callable)
-        assert not isinstance(None, Callable)
+        self.assertIsInstance(f, Callable)
+        self.assertNotIsInstance(None, Callable)
 
     def test_callable_instance_type_error(self):
         def f():
             pass
         with self.assertRaises(TypeError):
-            assert isinstance(f, Callable[[], None])
+            self.assertIsInstance(f, Callable[[], None])
         with self.assertRaises(TypeError):
-            assert isinstance(f, Callable[[], Any])
+            self.assertIsInstance(f, Callable[[], Any])
         with self.assertRaises(TypeError):
-            assert not isinstance(None, Callable[[], None])
+            self.assertNotIsInstance(None, Callable[[], None])
         with self.assertRaises(TypeError):
-            assert not isinstance(None, Callable[[], Any])
+            self.assertNotIsInstance(None, Callable[[], Any])
 
     def test_repr(self):
         ct0 = Callable[[], bool]
@@ -486,7 +529,7 @@ class SimpleMapping(Generic[XK, XV]):
         ...
 
 
-class MySimpleMapping(SimpleMapping):
+class MySimpleMapping(SimpleMapping[XK, XV]):
 
     def __init__(self):
         self.store = {}
@@ -504,15 +547,15 @@ class MySimpleMapping(SimpleMapping):
             return default
 
 
-class ProtocolTests(TestCase):
+class ProtocolTests(BaseTestCase):
 
     def test_supports_int(self):
-        assert issubclass(int, typing.SupportsInt)
-        assert not issubclass(str, typing.SupportsInt)
+        self.assertIsSubclass(int, typing.SupportsInt)
+        self.assertNotIsSubclass(str, typing.SupportsInt)
 
     def test_supports_float(self):
-        assert issubclass(float, typing.SupportsFloat)
-        assert not issubclass(str, typing.SupportsFloat)
+        self.assertIsSubclass(float, typing.SupportsFloat)
+        self.assertNotIsSubclass(str, typing.SupportsFloat)
 
     def test_supports_complex(self):
 
@@ -521,8 +564,8 @@ class ProtocolTests(TestCase):
             def __complex__(self):
                 return 0j
 
-        assert issubclass(C, typing.SupportsComplex)
-        assert not issubclass(str, typing.SupportsComplex)
+        self.assertIsSubclass(C, typing.SupportsComplex)
+        self.assertNotIsSubclass(str, typing.SupportsComplex)
 
     def test_supports_bytes(self):
 
@@ -531,39 +574,43 @@ class ProtocolTests(TestCase):
             def __bytes__(self):
                 return b''
 
-        assert issubclass(B, typing.SupportsBytes)
-        assert not issubclass(str, typing.SupportsBytes)
+        self.assertIsSubclass(B, typing.SupportsBytes)
+        self.assertNotIsSubclass(str, typing.SupportsBytes)
 
     def test_supports_abs(self):
-        assert issubclass(float, typing.SupportsAbs)
-        assert issubclass(int, typing.SupportsAbs)
-        assert not issubclass(str, typing.SupportsAbs)
+        self.assertIsSubclass(float, typing.SupportsAbs)
+        self.assertIsSubclass(int, typing.SupportsAbs)
+        self.assertNotIsSubclass(str, typing.SupportsAbs)
 
     def test_supports_round(self):
-        assert issubclass(float, typing.SupportsRound)
-        assert issubclass(int, typing.SupportsRound)
-        assert not issubclass(str, typing.SupportsRound)
+        issubclass(float, typing.SupportsRound)
+        self.assertIsSubclass(float, typing.SupportsRound)
+        self.assertIsSubclass(int, typing.SupportsRound)
+        self.assertNotIsSubclass(str, typing.SupportsRound)
 
     def test_reversible(self):
-        assert issubclass(list, typing.Reversible)
-        assert not issubclass(int, typing.Reversible)
+        self.assertIsSubclass(list, typing.Reversible)
+        self.assertNotIsSubclass(int, typing.Reversible)
 
     def test_protocol_instance_type_error(self):
         with self.assertRaises(TypeError):
-            isinstance([], typing.Reversible)
+            isinstance(0, typing.SupportsAbs)
 
 
-class GenericTests(TestCase):
+class GenericTests(BaseTestCase):
 
     def test_basics(self):
         X = SimpleMapping[str, Any]
-        Y = SimpleMapping[XK, str]
-        X[str, str]
-        Y[str, str]
+        self.assertEqual(X.__parameters__, ())
         with self.assertRaises(TypeError):
-            X[int, str]
+            X[str]
         with self.assertRaises(TypeError):
-            Y[str, bytes]
+            X[str, str]
+        Y = SimpleMapping[XK, str]
+        self.assertEqual(Y.__parameters__, (XK,))
+        Y[str]
+        with self.assertRaises(TypeError):
+            Y[str, str]
 
     def test_init(self):
         T = TypeVar('T')
@@ -575,30 +622,61 @@ class GenericTests(TestCase):
 
     def test_repr(self):
         self.assertEqual(repr(SimpleMapping),
-                         __name__ + '.' + 'SimpleMapping[~XK, ~XV]')
+                         __name__ + '.' + 'SimpleMapping<~XK, ~XV>')
         self.assertEqual(repr(MySimpleMapping),
-                         __name__ + '.' + 'MySimpleMapping[~XK, ~XV]')
+                         __name__ + '.' + 'MySimpleMapping<~XK, ~XV>')
+
+    def test_chain_repr(self):
+        T = TypeVar('T')
+        S = TypeVar('S')
+
+        class C(Generic[T]):
+            pass
+
+        X = C[Tuple[S, T]]
+        self.assertEqual(X, C[Tuple[S, T]])
+        self.assertNotEqual(X, C[Tuple[T, S]])
+
+        Y = X[T, int]
+        self.assertEqual(Y, X[T, int])
+        self.assertNotEqual(Y, X[S, int])
+        self.assertNotEqual(Y, X[T, str])
+
+        Z = Y[str]
+        self.assertEqual(Z, Y[str])
+        self.assertNotEqual(Z, Y[int])
+        self.assertNotEqual(Z, Y[T])
+
+        self.assertTrue(str(Z).endswith(
+            '.C<~T>[typing.Tuple[~S, ~T]]<~S, ~T>[~T, int]<~T>[str]'))
 
     def test_dict(self):
         T = TypeVar('T')
+
         class B(Generic[T]):
             pass
+
         b = B()
         b.foo = 42
         self.assertEqual(b.__dict__, {'foo': 42})
+
         class C(B[int]):
             pass
+
         c = C()
         c.bar = 'abc'
         self.assertEqual(c.__dict__, {'bar': 'abc'})
 
     def test_pickle(self):
+        global C  # pickle wants to reference the class by name
         T = TypeVar('T')
+
         class B(Generic[T]):
             pass
-        global C  # pickle wants to reference the class by name
+
         class C(B[int]):
             pass
+
         c = C()
         c.foo = 42
         c.bar = 'abc'
@@ -622,28 +700,30 @@ class GenericTests(TestCase):
         class C(Generic[T]):
             pass
 
-        assert C.__module__ == __name__
+        self.assertEqual(C.__module__, __name__)
         if not PY32:
-            assert C.__qualname__ == 'GenericTests.test_repr_2.<locals>.C'
-        assert repr(C).split('.')[-1] == 'C[~T]'
+            self.assertEqual(C.__qualname__,
+                             'GenericTests.test_repr_2.<locals>.C')
+        self.assertEqual(repr(C).split('.')[-1], 'C<~T>')
         X = C[int]
-        assert X.__module__ == __name__
+        self.assertEqual(X.__module__, __name__)
         if not PY32:
-            assert X.__qualname__ == 'C'
-        assert repr(X).split('.')[-1] == 'C[int]'
+            self.assertEqual(X.__qualname__, 'C')
+        self.assertEqual(repr(X).split('.')[-1], 'C<~T>[int]')
 
         class Y(C[int]):
             pass
 
-        assert Y.__module__ == __name__
+        self.assertEqual(Y.__module__, __name__)
         if not PY32:
-            assert Y.__qualname__ == 'GenericTests.test_repr_2.<locals>.Y'
-        assert repr(Y).split('.')[-1] == 'Y[int]'
+            self.assertEqual(Y.__qualname__,
+                             'GenericTests.test_repr_2.<locals>.Y')
+        self.assertEqual(repr(Y).split('.')[-1], 'Y')
 
     def test_eq_1(self):
-        assert Generic == Generic
-        assert Generic[T] == Generic[T]
-        assert Generic[KT] != Generic[VT]
+        self.assertEqual(Generic, Generic)
+        self.assertEqual(Generic[T], Generic[T])
+        self.assertNotEqual(Generic[KT], Generic[VT])
 
     def test_eq_2(self):
 
@@ -653,10 +733,10 @@ class GenericTests(TestCase):
         class B(Generic[T]):
             pass
 
-        assert A == A
-        assert A != B
-        assert A[T] == A[T]
-        assert A[T] != B[T]
+        self.assertEqual(A, A)
+        self.assertNotEqual(A, B)
+        self.assertEqual(A[T], A[T])
+        self.assertNotEqual(A[T], B[T])
 
     def test_multiple_inheritance(self):
 
@@ -666,15 +746,14 @@ class GenericTests(TestCase):
         class B(Generic[KT, T]):
             pass
 
-        class C(A, Generic[KT, VT], B):
+        class C(A[T, VT], Generic[VT, T, KT], B[KT, T]):
             pass
 
-        assert C.__parameters__ == (T, VT, KT)
+        self.assertEqual(C.__parameters__, (VT, T, KT))
 
     def test_nested(self):
 
-        class G(Generic):
-            pass
+        G = Generic
 
         class Visitor(G[T]):
 
@@ -700,7 +779,7 @@ class GenericTests(TestCase):
         a.set([])
         a.append(1)
         a.append(42)
-        assert a.get() == [1, 42]
+        self.assertEqual(a.get(), [1, 42])
 
     def test_type_erasure(self):
         T = TypeVar('T')
@@ -717,68 +796,91 @@ class GenericTests(TestCase):
             a = Node(x)
             b = Node[T](x)
             c = Node[Any](x)
-            assert type(a) is Node
-            assert type(b) is Node
-            assert type(c) is Node
+            self.assertIs(type(a), Node)
+            self.assertIs(type(b), Node)
+            self.assertIs(type(c), Node)
+            self.assertEqual(a.label, x)
+            self.assertEqual(b.label, x)
+            self.assertEqual(c.label, x)
 
         foo(42)
 
+    def test_implicit_any(self):
+        T = TypeVar('T')
+
+        class C(Generic[T]):
+            pass
+
+        class D(C):
+            pass
+
+        self.assertEqual(D.__parameters__, ())
 
-class VarianceTests(TestCase):
+        with self.assertRaises(Exception):
+            D[int]
+        with self.assertRaises(Exception):
+            D[Any]
+        with self.assertRaises(Exception):
+            D[T]
+
+
+class VarianceTests(BaseTestCase):
 
     def test_invariance(self):
         # Because of invariance, List[subclass of X] is not a subclass
         # of List[X], and ditto for MutableSequence.
-        assert not issubclass(typing.List[Manager], typing.List[Employee])
-        assert not issubclass(typing.MutableSequence[Manager],
+        self.assertNotIsSubclass(typing.List[Manager], typing.List[Employee])
+        self.assertNotIsSubclass(typing.MutableSequence[Manager],
                               typing.MutableSequence[Employee])
         # It's still reflexive.
-        assert issubclass(typing.List[Employee], typing.List[Employee])
-        assert issubclass(typing.MutableSequence[Employee],
+        self.assertIsSubclass(typing.List[Employee], typing.List[Employee])
+        self.assertIsSubclass(typing.MutableSequence[Employee],
                           typing.MutableSequence[Employee])
 
     def test_covariance_tuple(self):
         # Check covariace for Tuple (which are really special cases).
-        assert issubclass(Tuple[Manager], Tuple[Employee])
-        assert not issubclass(Tuple[Employee], Tuple[Manager])
+        self.assertIsSubclass(Tuple[Manager], Tuple[Employee])
+        self.assertNotIsSubclass(Tuple[Employee], Tuple[Manager])
         # And pairwise.
-        assert issubclass(Tuple[Manager, Manager], Tuple[Employee, Employee])
-        assert not issubclass(Tuple[Employee, Employee],
+        self.assertIsSubclass(Tuple[Manager, Manager],
+                              Tuple[Employee, Employee])
+        self.assertNotIsSubclass(Tuple[Employee, Employee],
                               Tuple[Manager, Employee])
         # And using ellipsis.
-        assert issubclass(Tuple[Manager, ...], Tuple[Employee, ...])
-        assert not issubclass(Tuple[Employee, ...], Tuple[Manager, ...])
+        self.assertIsSubclass(Tuple[Manager, ...], Tuple[Employee, ...])
+        self.assertNotIsSubclass(Tuple[Employee, ...], Tuple[Manager, ...])
 
     def test_covariance_sequence(self):
         # Check covariance for Sequence (which is just a generic class
         # for this purpose, but using a covariant type variable).
-        assert issubclass(typing.Sequence[Manager], typing.Sequence[Employee])
-        assert not issubclass(typing.Sequence[Employee],
+        self.assertIsSubclass(typing.Sequence[Manager],
+                              typing.Sequence[Employee])
+        self.assertNotIsSubclass(typing.Sequence[Employee],
                               typing.Sequence[Manager])
 
     def test_covariance_mapping(self):
         # Ditto for Mapping (covariant in the value, invariant in the key).
-        assert issubclass(typing.Mapping[Employee, Manager],
+        self.assertIsSubclass(typing.Mapping[Employee, Manager],
                           typing.Mapping[Employee, Employee])
-        assert not issubclass(typing.Mapping[Manager, Employee],
+        self.assertNotIsSubclass(typing.Mapping[Manager, Employee],
                               typing.Mapping[Employee, Employee])
-        assert not issubclass(typing.Mapping[Employee, Manager],
+        self.assertNotIsSubclass(typing.Mapping[Employee, Manager],
                               typing.Mapping[Manager, Manager])
-        assert not issubclass(typing.Mapping[Manager, Employee],
+        self.assertNotIsSubclass(typing.Mapping[Manager, Employee],
                               typing.Mapping[Manager, Manager])
 
 
-class CastTests(TestCase):
+class CastTests(BaseTestCase):
 
     def test_basics(self):
-        assert cast(int, 42) == 42
-        assert cast(float, 42) == 42
-        assert type(cast(float, 42)) is int
-        assert cast(Any, 42) == 42
-        assert cast(list, 42) == 42
-        assert cast(Union[str, float], 42) == 42
-        assert cast(AnyStr, 42) == 42
-        assert cast(None, 42) == 42
+        self.assertEqual(cast(int, 42), 42)
+        self.assertEqual(cast(float, 42), 42)
+        self.assertIs(type(cast(float, 42)), int)
+        self.assertEqual(cast(Any, 42), 42)
+        self.assertEqual(cast(list, 42), 42)
+        self.assertEqual(cast(Union[str, float], 42), 42)
+        self.assertEqual(cast(AnyStr, 42), 42)
+        self.assertEqual(cast(None, 42), 42)
 
     def test_errors(self):
         # Bogus calls are not expected to fail.
@@ -786,7 +888,7 @@ class CastTests(TestCase):
         cast('hello', 42)
 
 
-class ForwardRefTests(TestCase):
+class ForwardRefTests(BaseTestCase):
 
     def test_basics(self):
 
@@ -812,15 +914,17 @@ class ForwardRefTests(TestCase):
 
         t = Node[int]
         both_hints = get_type_hints(t.add_both, globals(), locals())
-        assert both_hints['left'] == both_hints['right'] == Optional[Node[T]]
-        assert both_hints['stuff'] == Optional[int]
-        assert 'blah' not in both_hints
+        self.assertEqual(both_hints['left'], Optional[Node[T]])
+        self.assertEqual(both_hints['right'], Optional[Node[T]])
+        self.assertEqual(both_hints['left'], both_hints['right'])
+        self.assertEqual(both_hints['stuff'], Optional[int])
+        self.assertNotIn('blah', both_hints)
 
         left_hints = get_type_hints(t.add_left, globals(), locals())
-        assert left_hints['node'] == Optional[Node[T]]
+        self.assertEqual(left_hints['node'], Optional[Node[T]])
 
         right_hints = get_type_hints(t.add_right, globals(), locals())
-        assert right_hints['node'] == Optional[Node[T]]
+        self.assertEqual(right_hints['node'], Optional[Node[T]])
 
     def test_forwardref_instance_type_error(self):
         fr = typing._ForwardRef('int')
@@ -943,10 +1047,10 @@ class ForwardRefTests(TestCase):
         ns = {}
         exec(code, ns)
         hints = get_type_hints(ns['C'].foo)
-        assert hints == {'a': ns['C'], 'return': ns['D']}
+        self.assertEqual(hints, {'a': ns['C'], 'return': ns['D']})
 
 
-class OverloadTests(TestCase):
+class OverloadTests(BaseTestCase):
 
     def test_overload_exists(self):
         from typing import overload
@@ -955,84 +1059,173 @@ class OverloadTests(TestCase):
         from typing import overload
 
         with self.assertRaises(RuntimeError):
+
             @overload
             def blah():
                 pass
 
+            blah()
+
+    def test_overload_succeeds(self):
+        from typing import overload
+
+        @overload
+        def blah():
+            pass
+
+        def blah():
+            pass
+
+        blah()
+
+
+PY35 = sys.version_info[:2] >= (3, 5)
 
-class CollectionsAbcTests(TestCase):
+PY35_TESTS = """
+import asyncio
+
+T_a = TypeVar('T')
+
+class AwaitableWrapper(typing.Awaitable[T_a]):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __await__(self) -> typing.Iterator[T_a]:
+        yield
+        return self.value
+
+class AsyncIteratorWrapper(typing.AsyncIterator[T_a]):
+
+    def __init__(self, value: typing.Iterable[T_a]):
+        self.value = value
+
+    def __aiter__(self) -> typing.AsyncIterator[T_a]:
+        return self
+
+    @asyncio.coroutine
+    def __anext__(self) -> T_a:
+        data = yield from self.value
+        if data:
+            return data
+        else:
+            raise StopAsyncIteration
+"""
+
+if PY35:
+    exec(PY35_TESTS)
+
+
+class CollectionsAbcTests(BaseTestCase):
 
     def test_hashable(self):
-        assert isinstance(42, typing.Hashable)
-        assert not isinstance([], typing.Hashable)
+        self.assertIsInstance(42, typing.Hashable)
+        self.assertNotIsInstance([], typing.Hashable)
 
     def test_iterable(self):
-        assert isinstance([], typing.Iterable)
+        self.assertIsInstance([], typing.Iterable)
         # Due to ABC caching, the second time takes a separate code
         # path and could fail.  So call this a few times.
-        assert isinstance([], typing.Iterable)
-        assert isinstance([], typing.Iterable)
-        assert isinstance([], typing.Iterable[int])
-        assert not isinstance(42, typing.Iterable)
+        self.assertIsInstance([], typing.Iterable)
+        self.assertIsInstance([], typing.Iterable)
+        self.assertIsInstance([], typing.Iterable[int])
+        self.assertNotIsInstance(42, typing.Iterable)
         # Just in case, also test issubclass() a few times.
-        assert issubclass(list, typing.Iterable)
-        assert issubclass(list, typing.Iterable)
+        self.assertIsSubclass(list, typing.Iterable)
+        self.assertIsSubclass(list, typing.Iterable)
 
     def test_iterator(self):
         it = iter([])
-        assert isinstance(it, typing.Iterator)
-        assert isinstance(it, typing.Iterator[int])
-        assert not isinstance(42, typing.Iterator)
+        self.assertIsInstance(it, typing.Iterator)
+        self.assertIsInstance(it, typing.Iterator[int])
+        self.assertNotIsInstance(42, typing.Iterator)
+
+    @skipUnless(PY35, 'Python 3.5 required')
+    def test_awaitable(self):
+        ns = {}
+        exec(
+            "async def foo() -> typing.Awaitable[int]:\n"
+            "    return await AwaitableWrapper(42)\n",
+            globals(), ns)
+        foo = ns['foo']
+        g = foo()
+        self.assertIsSubclass(type(g), typing.Awaitable[int])
+        self.assertIsInstance(g, typing.Awaitable)
+        self.assertNotIsInstance(foo, typing.Awaitable)
+        self.assertIsSubclass(typing.Awaitable[Manager],
+                          typing.Awaitable[Employee])
+        self.assertNotIsSubclass(typing.Awaitable[Employee],
+                              typing.Awaitable[Manager])
+        g.send(None)  # Run foo() till completion, to avoid warning.
+
+    @skipUnless(PY35, 'Python 3.5 required')
+    def test_async_iterable(self):
+        base_it = range(10)  # type: Iterator[int]
+        it = AsyncIteratorWrapper(base_it)
+        self.assertIsInstance(it, typing.AsyncIterable)
+        self.assertIsInstance(it, typing.AsyncIterable)
+        self.assertIsSubclass(typing.AsyncIterable[Manager],
+                          typing.AsyncIterable[Employee])
+        self.assertNotIsInstance(42, typing.AsyncIterable)
+
+    @skipUnless(PY35, 'Python 3.5 required')
+    def test_async_iterator(self):
+        base_it = range(10)  # type: Iterator[int]
+        it = AsyncIteratorWrapper(base_it)
+        self.assertIsInstance(it, typing.AsyncIterator)
+        self.assertIsSubclass(typing.AsyncIterator[Manager],
+                          typing.AsyncIterator[Employee])
+        self.assertNotIsInstance(42, typing.AsyncIterator)
 
     def test_sized(self):
-        assert isinstance([], typing.Sized)
-        assert not isinstance(42, typing.Sized)
+        self.assertIsInstance([], typing.Sized)
+        self.assertNotIsInstance(42, typing.Sized)
 
     def test_container(self):
-        assert isinstance([], typing.Container)
-        assert not isinstance(42, typing.Container)
+        self.assertIsInstance([], typing.Container)
+        self.assertNotIsInstance(42, typing.Container)
 
     def test_abstractset(self):
-        assert isinstance(set(), typing.AbstractSet)
-        assert not isinstance(42, typing.AbstractSet)
+        self.assertIsInstance(set(), typing.AbstractSet)
+        self.assertNotIsInstance(42, typing.AbstractSet)
 
     def test_mutableset(self):
-        assert isinstance(set(), typing.MutableSet)
-        assert not isinstance(frozenset(), typing.MutableSet)
+        self.assertIsInstance(set(), typing.MutableSet)
+        self.assertNotIsInstance(frozenset(), typing.MutableSet)
 
     def test_mapping(self):
-        assert isinstance({}, typing.Mapping)
-        assert not isinstance(42, typing.Mapping)
+        self.assertIsInstance({}, typing.Mapping)
+        self.assertNotIsInstance(42, typing.Mapping)
 
     def test_mutablemapping(self):
-        assert isinstance({}, typing.MutableMapping)
-        assert not isinstance(42, typing.MutableMapping)
+        self.assertIsInstance({}, typing.MutableMapping)
+        self.assertNotIsInstance(42, typing.MutableMapping)
 
     def test_sequence(self):
-        assert isinstance([], typing.Sequence)
-        assert not isinstance(42, typing.Sequence)
+        self.assertIsInstance([], typing.Sequence)
+        self.assertNotIsInstance(42, typing.Sequence)
 
     def test_mutablesequence(self):
-        assert isinstance([], typing.MutableSequence)
-        assert not isinstance((), typing.MutableSequence)
+        self.assertIsInstance([], typing.MutableSequence)
+        self.assertNotIsInstance((), typing.MutableSequence)
 
     def test_bytestring(self):
-        assert isinstance(b'', typing.ByteString)
-        assert isinstance(bytearray(b''), typing.ByteString)
+        self.assertIsInstance(b'', typing.ByteString)
+        self.assertIsInstance(bytearray(b''), typing.ByteString)
 
     def test_list(self):
-        assert issubclass(list, typing.List)
+        self.assertIsSubclass(list, typing.List)
 
     def test_set(self):
-        assert issubclass(set, typing.Set)
-        assert not issubclass(frozenset, typing.Set)
+        self.assertIsSubclass(set, typing.Set)
+        self.assertNotIsSubclass(frozenset, typing.Set)
 
     def test_frozenset(self):
-        assert issubclass(frozenset, typing.FrozenSet)
-        assert not issubclass(set, typing.FrozenSet)
+        self.assertIsSubclass(frozenset, typing.FrozenSet)
+        self.assertNotIsSubclass(set, typing.FrozenSet)
 
     def test_dict(self):
-        assert issubclass(dict, typing.Dict)
+        self.assertIsSubclass(dict, typing.Dict)
 
     def test_no_list_instantiation(self):
         with self.assertRaises(TypeError):
@@ -1042,13 +1235,17 @@ class CollectionsAbcTests(TestCase):
         with self.assertRaises(TypeError):
             typing.List[int]()
 
-    def test_list_subclass_instantiation(self):
+    def test_list_subclass(self):
 
         class MyList(typing.List[int]):
             pass
 
         a = MyList()
-        assert isinstance(a, MyList)
+        self.assertIsInstance(a, MyList)
+        self.assertIsInstance(a, typing.Sequence)
+
+        self.assertIsSubclass(MyList, list)
+        self.assertNotIsSubclass(list, MyList)
 
     def test_no_dict_instantiation(self):
         with self.assertRaises(TypeError):
@@ -1058,13 +1255,36 @@ class CollectionsAbcTests(TestCase):
         with self.assertRaises(TypeError):
             typing.Dict[str, int]()
 
-    def test_dict_subclass_instantiation(self):
+    def test_dict_subclass(self):
 
         class MyDict(typing.Dict[str, int]):
             pass
 
         d = MyDict()
-        assert isinstance(d, MyDict)
+        self.assertIsInstance(d, MyDict)
+        self.assertIsInstance(d, typing.MutableMapping)
+
+        self.assertIsSubclass(MyDict, dict)
+        self.assertNotIsSubclass(dict, MyDict)
+
+    def test_no_defaultdict_instantiation(self):
+        with self.assertRaises(TypeError):
+            typing.DefaultDict()
+        with self.assertRaises(TypeError):
+            typing.DefaultDict[KT, VT]()
+        with self.assertRaises(TypeError):
+            typing.DefaultDict[str, int]()
+
+    def test_defaultdict_subclass(self):
+
+        class MyDefDict(typing.DefaultDict[str, int]):
+            pass
+
+        dd = MyDefDict()
+        self.assertIsInstance(dd, MyDefDict)
+
+        self.assertIsSubclass(MyDefDict, collections.defaultdict)
+        self.assertNotIsSubclass(collections.defaultdict, MyDefDict)
 
     def test_no_set_instantiation(self):
         with self.assertRaises(TypeError):
@@ -1080,7 +1300,7 @@ class CollectionsAbcTests(TestCase):
             pass
 
         d = MySet()
-        assert isinstance(d, MySet)
+        self.assertIsInstance(d, MySet)
 
     def test_no_frozenset_instantiation(self):
         with self.assertRaises(TypeError):
@@ -1096,7 +1316,7 @@ class CollectionsAbcTests(TestCase):
             pass
 
         d = MyFrozenSet()
-        assert isinstance(d, MyFrozenSet)
+        self.assertIsInstance(d, MyFrozenSet)
 
     def test_no_tuple_instantiation(self):
         with self.assertRaises(TypeError):
@@ -1110,10 +1330,10 @@ class CollectionsAbcTests(TestCase):
         def foo():
             yield 42
         g = foo()
-        assert issubclass(type(g), typing.Generator)
-        assert issubclass(typing.Generator[Manager, Employee, Manager],
+        self.assertIsSubclass(type(g), typing.Generator)
+        self.assertIsSubclass(typing.Generator[Manager, Employee, Manager],
                           typing.Generator[Employee, Manager, Employee])
-        assert not issubclass(typing.Generator[Manager, Manager, Manager],
+        self.assertNotIsSubclass(typing.Generator[Manager, Manager, Manager],
                               typing.Generator[Employee, Employee, Employee])
 
     def test_no_generator_instantiation(self):
@@ -1136,33 +1356,101 @@ class CollectionsAbcTests(TestCase):
             def __len__(self):
                 return 0
 
-        assert len(MMC()) == 0
+        self.assertEqual(len(MMC()), 0)
 
         class MMB(typing.MutableMapping[KT, VT]):
             def __len__(self):
                 return 0
 
-        assert len(MMB()) == 0
-        assert len(MMB[str, str]()) == 0
-        assert len(MMB[KT, VT]()) == 0
+        self.assertEqual(len(MMB()), 0)
+        self.assertEqual(len(MMB[str, str]()), 0)
+        self.assertEqual(len(MMB[KT, VT]()), 0)
+
+        self.assertNotIsSubclass(dict, MMA)
+        self.assertNotIsSubclass(dict, MMB)
+
+        self.assertIsSubclass(MMA, typing.Mapping)
+        self.assertIsSubclass(MMB, typing.Mapping)
+        self.assertIsSubclass(MMC, typing.Mapping)
+
+
+class OtherABCTests(BaseTestCase):
+
+    @skipUnless(hasattr(typing, 'ContextManager'),
+                'requires typing.ContextManager')
+    def test_contextmanager(self):
+        @contextlib.contextmanager
+        def manager():
+            yield 42
+
+        cm = manager()
+        self.assertIsInstance(cm, typing.ContextManager)
+        self.assertIsInstance(cm, typing.ContextManager[int])
+        self.assertNotIsInstance(42, typing.ContextManager)
+
+
+class TypeTests(BaseTestCase):
+
+    def test_type_basic(self):
+
+        class User: pass
+        class BasicUser(User): pass
+        class ProUser(User): pass
+
+        def new_user(user_class: Type[User]) -> User:
+            return user_class()
+
+        joe = new_user(BasicUser)
+
+    def test_type_typevar(self):
+
+        class User: pass
+        class BasicUser(User): pass
+        class ProUser(User): pass
+
+        U = TypeVar('U', bound=User)
+
+        def new_user(user_class: Type[U]) -> U:
+            return user_class()
+
+        joe = new_user(BasicUser)
+
+
+class NewTypeTests(BaseTestCase):
+
+    def test_basic(self):
+        UserId = NewType('UserId', int)
+        UserName = NewType('UserName', str)
+        self.assertIsInstance(UserId(5), int)
+        self.assertIsInstance(UserName('Joe'), str)
+        self.assertEqual(UserId(5) + 1, 6)
+
+    def test_errors(self):
+        UserId = NewType('UserId', int)
+        UserName = NewType('UserName', str)
+        with self.assertRaises(TypeError):
+            issubclass(UserId, int)
+        with self.assertRaises(TypeError):
+            class D(UserName):
+                pass
 
 
-class NamedTupleTests(TestCase):
+class NamedTupleTests(BaseTestCase):
 
     def test_basics(self):
         Emp = NamedTuple('Emp', [('name', str), ('id', int)])
-        assert issubclass(Emp, tuple)
+        self.assertIsSubclass(Emp, tuple)
         joe = Emp('Joe', 42)
         jim = Emp(name='Jim', id=1)
-        assert isinstance(joe, Emp)
-        assert isinstance(joe, tuple)
-        assert joe.name == 'Joe'
-        assert joe.id == 42
-        assert jim.name == 'Jim'
-        assert jim.id == 1
-        assert Emp.__name__ == 'Emp'
-        assert Emp._fields == ('name', 'id')
-        assert Emp._field_types == dict(name=str, id=int)
+        self.assertIsInstance(joe, Emp)
+        self.assertIsInstance(joe, tuple)
+        self.assertEqual(joe.name, 'Joe')
+        self.assertEqual(joe.id, 42)
+        self.assertEqual(jim.name, 'Jim')
+        self.assertEqual(jim.id, 1)
+        self.assertEqual(Emp.__name__, 'Emp')
+        self.assertEqual(Emp._fields, ('name', 'id'))
+        self.assertEqual(Emp._field_types, dict(name=str, id=int))
 
     def test_pickle(self):
         global Emp  # pickle wants to reference the class by name
@@ -1174,7 +1462,7 @@ class NamedTupleTests(TestCase):
             self.assertEqual(jane2, jane)
 
 
-class IOTests(TestCase):
+class IOTests(BaseTestCase):
 
     def test_io(self):
 
@@ -1182,7 +1470,7 @@ class IOTests(TestCase):
             return a.readline()
 
         a = stuff.__annotations__['a']
-        assert a.__parameters__ == (AnyStr,)
+        self.assertEqual(a.__parameters__, (AnyStr,))
 
     def test_textio(self):
 
@@ -1190,7 +1478,7 @@ class IOTests(TestCase):
             return a.readline()
 
         a = stuff.__annotations__['a']
-        assert a.__parameters__ == (str,)
+        self.assertEqual(a.__parameters__, ())
 
     def test_binaryio(self):
 
@@ -1198,40 +1486,40 @@ class IOTests(TestCase):
             return a.readline()
 
         a = stuff.__annotations__['a']
-        assert a.__parameters__ == (bytes,)
+        self.assertEqual(a.__parameters__, ())
 
     def test_io_submodule(self):
         from typing.io import IO, TextIO, BinaryIO, __all__, __name__
-        assert IO is typing.IO
-        assert TextIO is typing.TextIO
-        assert BinaryIO is typing.BinaryIO
-        assert set(__all__) == set(['IO', 'TextIO', 'BinaryIO'])
-        assert __name__ == 'typing.io'
+        self.assertIs(IO, typing.IO)
+        self.assertIs(TextIO, typing.TextIO)
+        self.assertIs(BinaryIO, typing.BinaryIO)
+        self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO']))
+        self.assertEqual(__name__, 'typing.io')
 
 
-class RETests(TestCase):
+class RETests(BaseTestCase):
     # Much of this is really testing _TypeAlias.
 
     def test_basics(self):
         pat = re.compile('[a-z]+', re.I)
-        assert issubclass(pat.__class__, Pattern)
-        assert issubclass(type(pat), Pattern)
-        assert issubclass(type(pat), Pattern[str])
+        self.assertIsSubclass(pat.__class__, Pattern)
+        self.assertIsSubclass(type(pat), Pattern)
+        self.assertIsSubclass(type(pat), Pattern[str])
 
         mat = pat.search('12345abcde.....')
-        assert issubclass(mat.__class__, Match)
-        assert issubclass(mat.__class__, Match[str])
-        assert issubclass(mat.__class__, Match[bytes])  # Sad but true.
-        assert issubclass(type(mat), Match)
-        assert issubclass(type(mat), Match[str])
+        self.assertIsSubclass(mat.__class__, Match)
+        self.assertIsSubclass(mat.__class__, Match[str])
+        self.assertIsSubclass(mat.__class__, Match[bytes])  # Sad but true.
+        self.assertIsSubclass(type(mat), Match)
+        self.assertIsSubclass(type(mat), Match[str])
 
         p = Pattern[Union[str, bytes]]
-        assert issubclass(Pattern[str], Pattern)
-        assert issubclass(Pattern[str], p)
+        self.assertIsSubclass(Pattern[str], Pattern)
+        self.assertIsSubclass(Pattern[str], p)
 
         m = Match[Union[bytes, str]]
-        assert issubclass(Match[bytes], Match)
-        assert issubclass(Match[bytes], m)
+        self.assertIsSubclass(Match[bytes], Match)
+        self.assertIsSubclass(Match[bytes], m)
 
     def test_errors(self):
         with self.assertRaises(TypeError):
@@ -1252,19 +1540,19 @@ class RETests(TestCase):
             isinstance(42, Pattern[str])
 
     def test_repr(self):
-        assert repr(Pattern) == 'Pattern[~AnyStr]'
-        assert repr(Pattern[str]) == 'Pattern[str]'
-        assert repr(Pattern[bytes]) == 'Pattern[bytes]'
-        assert repr(Match) == 'Match[~AnyStr]'
-        assert repr(Match[str]) == 'Match[str]'
-        assert repr(Match[bytes]) == 'Match[bytes]'
+        self.assertEqual(repr(Pattern), 'Pattern[~AnyStr]')
+        self.assertEqual(repr(Pattern[str]), 'Pattern[str]')
+        self.assertEqual(repr(Pattern[bytes]), 'Pattern[bytes]')
+        self.assertEqual(repr(Match), 'Match[~AnyStr]')
+        self.assertEqual(repr(Match[str]), 'Match[str]')
+        self.assertEqual(repr(Match[bytes]), 'Match[bytes]')
 
     def test_re_submodule(self):
         from typing.re import Match, Pattern, __all__, __name__
-        assert Match is typing.Match
-        assert Pattern is typing.Pattern
-        assert set(__all__) == set(['Match', 'Pattern'])
-        assert __name__ == 'typing.re'
+        self.assertIs(Match, typing.Match)
+        self.assertIs(Pattern, typing.Pattern)
+        self.assertEqual(set(__all__), set(['Match', 'Pattern']))
+        self.assertEqual(__name__, 'typing.re')
 
     def test_cannot_subclass(self):
         with self.assertRaises(TypeError) as ex:
@@ -1272,24 +1560,30 @@ class RETests(TestCase):
             class A(typing.Match):
                 pass
 
-        assert str(ex.exception) == "A type alias cannot be subclassed"
+        self.assertEqual(str(ex.exception),
+                         "A type alias cannot be subclassed")
 
 
-class AllTests(TestCase):
+class AllTests(BaseTestCase):
     """Tests for __all__."""
 
     def test_all(self):
         from typing import __all__ as a
         # Just spot-check the first and last of every category.
-        assert 'AbstractSet' in a
-        assert 'ValuesView' in a
-        assert 'cast' in a
-        assert 'overload' in a
-        assert 'io' in a
-        assert 're' in a
+        self.assertIn('AbstractSet', a)
+        self.assertIn('ValuesView', a)
+        self.assertIn('cast', a)
+        self.assertIn('overload', a)
+        if hasattr(contextlib, 'AbstractContextManager'):
+            self.assertIn('ContextManager', a)
+        # Check that io and re are not exported.
+        self.assertNotIn('io', a)
+        self.assertNotIn('re', a)
         # Spot-check that stdlib modules aren't exported.
-        assert 'os' not in a
-        assert 'sys' not in a
+        self.assertNotIn('os', a)
+        self.assertNotIn('sys', a)
+        # Check that Text is defined.
+        self.assertIn('Text', a)
 
 
 if __name__ == '__main__':
index d7f37c5..a38e7b1 100644 (file)
@@ -43,6 +43,9 @@ def duplicate_string(text):
     """
     return text.encode().decode()
 
+class StrSubclass(str):
+    pass
+
 class UnicodeTest(string_tests.CommonTest,
         string_tests.MixinStrUnicodeUserStringTest,
         string_tests.MixinStrUnicodeTest,
@@ -338,12 +341,22 @@ class UnicodeTest(string_tests.CommonTest,
                          "[XXX]")
         self.assertEqual("[a]".translate(str.maketrans({'a': '\xe9'})),
                          "[\xe9]")
+        self.assertEqual('axb'.translate(str.maketrans({'a': None, 'b': '123'})),
+                         "x123")
+        self.assertEqual('axb'.translate(str.maketrans({'a': None, 'b': '\xe9'})),
+                         "x\xe9")
+
+        # test non-ASCII (don't take the fast-path)
         self.assertEqual("[a]".translate(str.maketrans({'a': '<\xe9>'})),
                          "[<\xe9>]")
         self.assertEqual("[\xe9]".translate(str.maketrans({'\xe9': 'a'})),
                          "[a]")
         self.assertEqual("[\xe9]".translate(str.maketrans({'\xe9': None})),
                          "[]")
+        self.assertEqual("[\xe9]".translate(str.maketrans({'\xe9': '123'})),
+                         "[123]")
+        self.assertEqual("[a\xe9]".translate(str.maketrans({'a': '<\u20ac>'})),
+                         "[<\u20ac>\xe9]")
 
         # invalid Unicode characters
         invalid_char = 0x10ffff+1
@@ -367,10 +380,6 @@ class UnicodeTest(string_tests.CommonTest,
     def test_split(self):
         string_tests.CommonTest.test_split(self)
 
-        # Mixed arguments
-        self.checkequalnofix(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//')
-        self.checkequalnofix(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//')
-        self.checkequalnofix(['endcase ', ''], 'endcase test', 'split', 'test')
         # test mixed kinds
         for left, right in ('ba', '\u0101\u0100', '\U00010301\U00010300'):
             left *= 9
@@ -552,7 +561,7 @@ class UnicodeTest(string_tests.CommonTest,
         self.assertTrue('\ud800\udc02' < '\ud84d\udc56')
 
     def test_islower(self):
-        string_tests.MixinStrUnicodeUserStringTest.test_islower(self)
+        super().test_islower()
         self.checkequalnofix(False, '\u1FFc', 'islower')
         self.assertFalse('\u2167'.islower())
         self.assertTrue('\u2177'.islower())
@@ -567,7 +576,7 @@ class UnicodeTest(string_tests.CommonTest,
         self.assertFalse('\U0001F46F'.islower())
 
     def test_isupper(self):
-        string_tests.MixinStrUnicodeUserStringTest.test_isupper(self)
+        super().test_isupper()
         if not sys.platform.startswith('java'):
             self.checkequalnofix(False, '\u1FFc', 'isupper')
         self.assertTrue('\u2167'.isupper())
@@ -583,7 +592,7 @@ class UnicodeTest(string_tests.CommonTest,
         self.assertFalse('\U0001F46F'.isupper())
 
     def test_istitle(self):
-        string_tests.MixinStrUnicodeUserStringTest.test_istitle(self)
+        super().test_istitle()
         self.checkequalnofix(True, '\u1FFc', 'istitle')
         self.checkequalnofix(True, 'Greek \u1FFcitlecases ...', 'istitle')
 
@@ -595,7 +604,7 @@ class UnicodeTest(string_tests.CommonTest,
             self.assertFalse(ch.istitle(), '{!a} is not title'.format(ch))
 
     def test_isspace(self):
-        string_tests.MixinStrUnicodeUserStringTest.test_isspace(self)
+        super().test_isspace()
         self.checkequalnofix(True, '\u2000', 'isspace')
         self.checkequalnofix(True, '\u200a', 'isspace')
         self.checkequalnofix(False, '\u2014', 'isspace')
@@ -605,13 +614,13 @@ class UnicodeTest(string_tests.CommonTest,
             self.assertFalse(ch.isspace(), '{!a} is not space.'.format(ch))
 
     def test_isalnum(self):
-        string_tests.MixinStrUnicodeUserStringTest.test_isalnum(self)
+        super().test_isalnum()
         for ch in ['\U00010401', '\U00010427', '\U00010429', '\U0001044E',
                    '\U0001D7F6', '\U00011066', '\U000104A0', '\U0001F107']:
             self.assertTrue(ch.isalnum(), '{!a} is alnum.'.format(ch))
 
     def test_isalpha(self):
-        string_tests.MixinStrUnicodeUserStringTest.test_isalpha(self)
+        super().test_isalpha()
         self.checkequalnofix(True, '\u1FFc', 'isalpha')
         # non-BMP, cased
         self.assertTrue('\U00010401'.isalpha())
@@ -641,7 +650,7 @@ class UnicodeTest(string_tests.CommonTest,
             self.assertTrue(ch.isdecimal(), '{!a} is decimal.'.format(ch))
 
     def test_isdigit(self):
-        string_tests.MixinStrUnicodeUserStringTest.test_isdigit(self)
+        super().test_isdigit()
         self.checkequalnofix(True, '\u2460', 'isdigit')
         self.checkequalnofix(False, '\xbc', 'isdigit')
         self.checkequalnofix(True, '\u0660', 'isdigit')
@@ -794,7 +803,7 @@ class UnicodeTest(string_tests.CommonTest,
         self.assertEqual('A\u0345\u03a3'.capitalize(), 'A\u0345\u03c2')
 
     def test_title(self):
-        string_tests.MixinStrUnicodeUserStringTest.test_title(self)
+        super().test_title()
         self.assertEqual('\U0001044F'.title(), '\U00010427')
         self.assertEqual('\U0001044F\U0001044F'.title(),
                          '\U00010427\U0001044F')
@@ -1441,11 +1450,8 @@ class UnicodeTest(string_tests.CommonTest,
             'unicode remains unicode'
         )
 
-        class UnicodeSubclass(str):
-            pass
-
         for text in ('ascii', '\xe9', '\u20ac', '\U0010FFFF'):
-            subclass = UnicodeSubclass(text)
+            subclass = StrSubclass(text)
             self.assertEqual(str(subclass), text)
             self.assertEqual(len(subclass), len(text))
             if text == 'ascii':
@@ -1768,7 +1774,7 @@ class UnicodeTest(string_tests.CommonTest,
 
     def assertCorrectUTF8Decoding(self, seq, res, err):
         """
-        Check that an invalid UTF-8 sequence raises an UnicodeDecodeError when
+        Check that an invalid UTF-8 sequence raises a UnicodeDecodeError when
         'strict' is used, returns res when 'replace' is used, and that doesn't
         return anything when 'ignore' is used.
         """
@@ -2199,6 +2205,9 @@ class UnicodeTest(string_tests.CommonTest,
         s = str(StrSubclassToStrSubclass("foo"))
         self.assertEqual(s, "foofoo")
         self.assertIs(type(s), StrSubclassToStrSubclass)
+        s = StrSubclass(StrSubclassToStrSubclass("foo"))
+        self.assertEqual(s, "foofoo")
+        self.assertIs(type(s), StrSubclass)
 
     def test_unicode_repr(self):
         class s1:
@@ -2716,6 +2725,10 @@ class UnicodeTest(string_tests.CommonTest,
                 # Check that the second call returns the same result
                 self.assertEqual(getargs_s_hash(s), chr(k).encode() * (i + 1))
 
+    def test_free_after_iterating(self):
+        support.check_free_after_iterating(self, iter, str)
+        support.check_free_after_iterating(self, reversed, str)
+
 
 class StringModuleTest(unittest.TestCase):
     def test_formatter_parser(self):
index 57eeeaa..5d05f8d 100644 (file)
@@ -1,4 +1,4 @@
-"""Regresssion tests for urllib"""
+"""Regresssion tests for what was in Python 2's "urllib" module"""
 
 import urllib.parse
 import urllib.request
@@ -39,10 +39,7 @@ def urlopen(url, data=None, proxies=None):
     if proxies is not None:
         opener = urllib.request.FancyURLopener(proxies=proxies)
     elif not _urlopener:
-        with support.check_warnings(
-                ('FancyURLopener style of invoking requests is deprecated.',
-                DeprecationWarning)):
-            opener = urllib.request.FancyURLopener()
+        opener = FancyURLopener()
         _urlopener = opener
     else:
         opener = _urlopener
@@ -52,6 +49,13 @@ def urlopen(url, data=None, proxies=None):
         return opener.open(url, data)
 
 
+def FancyURLopener():
+    with support.check_warnings(
+            ('FancyURLopener style of invoking requests is deprecated.',
+            DeprecationWarning)):
+        return urllib.request.FancyURLopener()
+
+
 def fakehttp(fakedata):
     class FakeSocket(io.BytesIO):
         io_refs = 1
@@ -82,10 +86,11 @@ def fakehttp(fakedata):
 
         # buffer to store data for verification in urlopen tests.
         buf = None
-        fakesock = FakeSocket(fakedata)
 
         def connect(self):
-            self.sock = self.fakesock
+            self.sock = FakeSocket(self.fakedata)
+            type(self).fakesock = self.sock
+    FakeHTTPConnection.fakedata = fakedata
 
     return FakeHTTPConnection
 
@@ -222,8 +227,59 @@ class ProxyTests(unittest.TestCase):
         # getproxies_environment use lowered case truncated (no '_proxy') keys
         self.assertEqual('localhost', proxies['no'])
         # List of no_proxies with space.
-        self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
+        self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com:1234')
         self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com'))
+        self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com:8888'))
+        self.assertTrue(urllib.request.proxy_bypass_environment('newdomain.com:1234'))
+
+    def test_proxy_bypass_environment_host_match(self):
+        bypass = urllib.request.proxy_bypass_environment
+        self.env.set('NO_PROXY',
+            'localhost, anotherdomain.com, newdomain.com:1234')
+        self.assertTrue(bypass('localhost'))
+        self.assertTrue(bypass('LocalHost'))                 # MixedCase
+        self.assertTrue(bypass('LOCALHOST'))                 # UPPERCASE
+        self.assertTrue(bypass('newdomain.com:1234'))
+        self.assertTrue(bypass('anotherdomain.com:8888'))
+        self.assertTrue(bypass('www.newdomain.com:1234'))
+        self.assertFalse(bypass('prelocalhost'))
+        self.assertFalse(bypass('newdomain.com'))            # no port
+        self.assertFalse(bypass('newdomain.com:1235'))       # wrong port
+
+class ProxyTests_withOrderedEnv(unittest.TestCase):
+
+    def setUp(self):
+        # We need to test conditions, where variable order _is_ significant
+        self._saved_env = os.environ
+        # Monkey patch os.environ, start with empty fake environment
+        os.environ = collections.OrderedDict()
+
+    def tearDown(self):
+        os.environ = self._saved_env
+
+    def test_getproxies_environment_prefer_lowercase(self):
+        # Test lowercase preference with removal
+        os.environ['no_proxy'] = ''
+        os.environ['No_Proxy'] = 'localhost'
+        self.assertFalse(urllib.request.proxy_bypass_environment('localhost'))
+        self.assertFalse(urllib.request.proxy_bypass_environment('arbitrary'))
+        os.environ['http_proxy'] = ''
+        os.environ['HTTP_PROXY'] = 'http://somewhere:3128'
+        proxies = urllib.request.getproxies_environment()
+        self.assertEqual({}, proxies)
+        # Test lowercase preference of proxy bypass and correct matching including ports
+        os.environ['no_proxy'] = 'localhost, noproxy.com, my.proxy:1234'
+        os.environ['No_Proxy'] = 'xyz.com'
+        self.assertTrue(urllib.request.proxy_bypass_environment('localhost'))
+        self.assertTrue(urllib.request.proxy_bypass_environment('noproxy.com:5678'))
+        self.assertTrue(urllib.request.proxy_bypass_environment('my.proxy:1234'))
+        self.assertFalse(urllib.request.proxy_bypass_environment('my.proxy'))
+        self.assertFalse(urllib.request.proxy_bypass_environment('arbitrary'))
+        # Test lowercase preference with replacement
+        os.environ['http_proxy'] = 'http://somewhere:3128'
+        os.environ['Http_Proxy'] = 'http://somewhereelse:3128'
+        proxies = urllib.request.getproxies_environment()
+        self.assertEqual('http://somewhere:3128', proxies['http'])
 
 class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin, FakeFTPMixin):
     """Test urlopen() opening a fake http connection."""
@@ -291,11 +347,26 @@ Connection: close
 Content-Type: text/html; charset=iso-8859-1
 ''')
         try:
-            self.assertRaises(urllib.error.HTTPError, urlopen,
-                              "http://python.org/")
+            msg = "Redirection to url 'file:"
+            with self.assertRaisesRegex(urllib.error.HTTPError, msg):
+                urlopen("http://python.org/")
         finally:
             self.unfakehttp()
 
+    def test_redirect_limit_independent(self):
+        # Ticket #12923: make sure independent requests each use their
+        # own retry limit.
+        for i in range(FancyURLopener().maxtries):
+            self.fakehttp(b'''HTTP/1.1 302 Found
+Location: file://guidocomputer.athome.com:/python/license
+Connection: close
+''')
+            try:
+                self.assertRaises(urllib.error.HTTPError, urlopen,
+                    "http://something")
+            finally:
+                self.unfakehttp()
+
     def test_empty_socket(self):
         # urlopen() raises OSError if the underlying socket does not send any
         # data. (#1680230)
index a5281d8..eda7ccc 100644 (file)
@@ -13,7 +13,8 @@ import urllib.request
 # proxy config data structure but is testable on all platforms.
 from urllib.request import (Request, OpenerDirector, HTTPBasicAuthHandler,
                             HTTPPasswordMgrWithPriorAuth, _parse_proxy,
-                            _proxy_bypass_macosx_sysconf)
+                            _proxy_bypass_macosx_sysconf,
+                            AbstractDigestAuthHandler)
 from urllib.parse import urlparse
 import urllib.error
 import http.client
@@ -461,7 +462,7 @@ class MockHTTPHandler(urllib.request.BaseHandler):
         self.requests = []
 
     def http_open(self, req):
-        import email, http.client, copy
+        import email, copy
         self.requests.append(copy.deepcopy(req))
         if self._count == 0:
             self._count = self._count + 1
@@ -479,8 +480,8 @@ class MockHTTPSHandler(urllib.request.AbstractHTTPHandler):
     # Useful for testing the Proxy-Authorization request by verifying the
     # properties of httpcon
 
-    def __init__(self):
-        urllib.request.AbstractHTTPHandler.__init__(self)
+    def __init__(self, debuglevel=0):
+        urllib.request.AbstractHTTPHandler.__init__(self, debuglevel=debuglevel)
         self.httpconn = MockHTTPClass()
 
     def https_open(self, req):
@@ -949,6 +950,13 @@ class HandlerTests(unittest.TestCase):
             newreq = h.do_request_(req)
             self.assertEqual(int(newreq.get_header('Content-length')),16)
 
+    def test_http_handler_debuglevel(self):
+        o = OpenerDirector()
+        h = MockHTTPSHandler(debuglevel=1)
+        o.add_handler(h)
+        o.open("https://www.example.com")
+        self.assertEqual(h._debuglevel, 1)
+
     def test_http_doubleslash(self):
         # Checks the presence of any unnecessary double slash in url does not
         # break anything. Previously, a double slash directly after the host
@@ -1200,6 +1208,57 @@ class HandlerTests(unittest.TestCase):
         fp = o.open('http://www.example.com')
         self.assertEqual(fp.geturl(), redirected_url.strip())
 
+    def test_redirect_no_path(self):
+        # Issue 14132: Relative redirect strips original path
+        real_class = http.client.HTTPConnection
+        response1 = b"HTTP/1.1 302 Found\r\nLocation: ?query\r\n\r\n"
+        http.client.HTTPConnection = test_urllib.fakehttp(response1)
+        self.addCleanup(setattr, http.client, "HTTPConnection", real_class)
+        urls = iter(("/path", "/path?query"))
+        def request(conn, method, url, *pos, **kw):
+            self.assertEqual(url, next(urls))
+            real_class.request(conn, method, url, *pos, **kw)
+            # Change response for subsequent connection
+            conn.__class__.fakedata = b"HTTP/1.1 200 OK\r\n\r\nHello!"
+        http.client.HTTPConnection.request = request
+        fp = urllib.request.urlopen("http://python.org/path")
+        self.assertEqual(fp.geturl(), "http://python.org/path?query")
+
+    def test_redirect_encoding(self):
+        # Some characters in the redirect target may need special handling,
+        # but most ASCII characters should be treated as already encoded
+        class Handler(urllib.request.HTTPHandler):
+            def http_open(self, req):
+                result = self.do_open(self.connection, req)
+                self.last_buf = self.connection.buf
+                # Set up a normal response for the next request
+                self.connection = test_urllib.fakehttp(
+                    b'HTTP/1.1 200 OK\r\n'
+                    b'Content-Length: 3\r\n'
+                    b'\r\n'
+                    b'123'
+                )
+                return result
+        handler = Handler()
+        opener = urllib.request.build_opener(handler)
+        tests = (
+            (b'/p\xC3\xA5-dansk/', b'/p%C3%A5-dansk/'),
+            (b'/spaced%20path/', b'/spaced%20path/'),
+            (b'/spaced path/', b'/spaced%20path/'),
+            (b'/?p\xC3\xA5-dansk', b'/?p%C3%A5-dansk'),
+        )
+        for [location, result] in tests:
+            with self.subTest(repr(location)):
+                handler.connection = test_urllib.fakehttp(
+                    b'HTTP/1.1 302 Redirect\r\n'
+                    b'Location: ' + location + b'\r\n'
+                    b'\r\n'
+                )
+                response = opener.open('http://example.com/')
+                expected = b'GET ' + result + b' '
+                request = handler.last_buf
+                self.assertTrue(request.startswith(expected), repr(request))
+
     def test_proxy(self):
         o = OpenerDirector()
         ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128"))
@@ -1680,6 +1739,15 @@ class MiscTests(unittest.TestCase):
 
         self.assertRaises(ValueError, _parse_proxy, 'file:/ftp.example.com'),
 
+    def test_unsupported_algorithm(self):
+        handler = AbstractDigestAuthHandler()
+        with self.assertRaises(ValueError) as exc:
+            handler.get_algorithm_impls('invalid')
+        self.assertEqual(
+            str(exc.exception),
+            "Unsupported digest authentication algorithm 'invalid'"
+        )
+
 
 class RequestTests(unittest.TestCase):
     class PutRequest(Request):
index 0650aa2..c8b37ee 100644 (file)
@@ -626,35 +626,6 @@ class TestUrlopen(unittest.TestCase):
         url = open_url.geturl()
         self.assertEqual(url, "http://localhost:%s" % handler.port)
 
-    def test_bad_address(self):
-        # Make sure proper exception is raised when connecting to a bogus
-        # address.
-
-        # as indicated by the comment below, this might fail with some ISP,
-        # so we run the test only when -unetwork/-uall is specified to
-        # mitigate the problem a bit (see #17564)
-        support.requires('network')
-        self.assertRaises(OSError,
-                          # Given that both VeriSign and various ISPs have in
-                          # the past or are presently hijacking various invalid
-                          # domain name requests in an attempt to boost traffic
-                          # to their own sites, finding a domain name to use
-                          # for this test is difficult.  RFC2606 leads one to
-                          # believe that '.invalid' should work, but experience
-                          # seemed to indicate otherwise.  Single character
-                          # TLDs are likely to remain invalid, so this seems to
-                          # be the best choice. The trailing '.' prevents a
-                          # related problem: The normal DNS resolver appends
-                          # the domain names from the search path if there is
-                          # no '.' the end and, and if one of those domains
-                          # implements a '*' rule a result is returned.
-                          # However, none of this will prevent the test from
-                          # failing if the ISP hijacks all invalid domain
-                          # requests.  The real solution would be to be able to
-                          # parameterize the framework with a mock resolver.
-                          urllib.request.urlopen,
-                          "http://sadflkjsasf.i.nvali.d./")
-
     def test_iteration(self):
         expected_response = b"pycon 2008..."
         handler = self.start_server([(200, [], expected_response)])
index 42ebb6e..b811930 100644 (file)
@@ -38,12 +38,14 @@ class urlopenNetworkTests(unittest.TestCase):
     for transparent redirection have been written.
 
     setUp is not used for always constructing a connection to
-    http://www.example.com/ since there a few tests that don't use that address
+    http://www.pythontest.net/ since there a few tests that don't use that address
     and making a connection is expensive enough to warrant minimizing unneeded
     connections.
 
     """
 
+    url = 'http://www.pythontest.net/'
+
     @contextlib.contextmanager
     def urlopen(self, *args, **kwargs):
         resource = args[0]
@@ -56,7 +58,7 @@ class urlopenNetworkTests(unittest.TestCase):
 
     def test_basic(self):
         # Simple test expected to pass.
-        with self.urlopen("http://www.example.com/") as open_url:
+        with self.urlopen(self.url) as open_url:
             for attr in ("read", "readline", "readlines", "fileno", "close",
                          "info", "geturl"):
                 self.assertTrue(hasattr(open_url, attr), "object returned from "
@@ -65,7 +67,7 @@ class urlopenNetworkTests(unittest.TestCase):
 
     def test_readlines(self):
         # Test both readline and readlines.
-        with self.urlopen("http://www.example.com/") as open_url:
+        with self.urlopen(self.url) as open_url:
             self.assertIsInstance(open_url.readline(), bytes,
                                   "readline did not return a string")
             self.assertIsInstance(open_url.readlines(), list,
@@ -73,7 +75,7 @@ class urlopenNetworkTests(unittest.TestCase):
 
     def test_info(self):
         # Test 'info'.
-        with self.urlopen("http://www.example.com/") as open_url:
+        with self.urlopen(self.url) as open_url:
             info_obj = open_url.info()
             self.assertIsInstance(info_obj, email.message.Message,
                                   "object returned by 'info' is not an "
@@ -82,14 +84,13 @@ class urlopenNetworkTests(unittest.TestCase):
 
     def test_geturl(self):
         # Make sure same URL as opened is returned by geturl.
-        URL = "http://www.example.com/"
-        with self.urlopen(URL) as open_url:
+        with self.urlopen(self.url) as open_url:
             gotten_url = open_url.geturl()
-            self.assertEqual(gotten_url, URL)
+            self.assertEqual(gotten_url, self.url)
 
     def test_getcode(self):
         # test getcode() with the fancy opener to get 404 error codes
-        URL = "http://www.example.com/XXXinvalidXXX"
+        URL = self.url + "XXXinvalidXXX"
         with support.transient_internet(URL):
             with self.assertWarns(DeprecationWarning):
                 open_url = urllib.request.FancyURLopener().open(URL)
@@ -99,21 +100,28 @@ class urlopenNetworkTests(unittest.TestCase):
                 open_url.close()
             self.assertEqual(code, 404)
 
-    # On Windows, socket handles are not file descriptors; this
-    # test can't pass on Windows.
-    @unittest.skipIf(sys.platform in ('win32',), 'not appropriate for Windows')
-    def test_fileno(self):
-        # Make sure fd returned by fileno is valid.
-        with self.urlopen("http://www.google.com/", timeout=None) as open_url:
-            fd = open_url.fileno()
-            with os.fdopen(fd, 'rb') as f:
-                self.assertTrue(f.read(), "reading from file created using fd "
-                                          "returned by fileno failed")
-
     def test_bad_address(self):
         # Make sure proper exception is raised when connecting to a bogus
         # address.
-        bogus_domain = "sadflkjsasf.i.nvali.d"
+
+        # Given that both VeriSign and various ISPs have in
+        # the past or are presently hijacking various invalid
+        # domain name requests in an attempt to boost traffic
+        # to their own sites, finding a domain name to use
+        # for this test is difficult.  RFC2606 leads one to
+        # believe that '.invalid' should work, but experience
+        # seemed to indicate otherwise.  Single character
+        # TLDs are likely to remain invalid, so this seems to
+        # be the best choice. The trailing '.' prevents a
+        # related problem: The normal DNS resolver appends
+        # the domain names from the search path if there is
+        # no '.' the end and, and if one of those domains
+        # implements a '*' rule a result is returned.
+        # However, none of this will prevent the test from
+        # failing if the ISP hijacks all invalid domain
+        # requests.  The real solution would be to be able to
+        # parameterize the framework with a mock resolver.
+        bogus_domain = "sadflkjsasf.i.nvali.d."
         try:
             socket.gethostbyname(bogus_domain)
         except OSError:
@@ -128,11 +136,7 @@ class urlopenNetworkTests(unittest.TestCase):
                                'can be caused by a broken DNS server '
                                '(e.g. returns 404 or hijacks page)')
         with self.assertRaises(OSError, msg=failure_explanation):
-            # SF patch 809915:  In Sep 2003, VeriSign started highjacking
-            # invalid .com and .net addresses to boost traffic to their own
-            # site.  This test started failing then.  One hopes the .invalid
-            # domain will be spared to serve its defined purpose.
-            urllib.request.urlopen("http://sadflkjsasf.i.nvali.d/")
+            urllib.request.urlopen("http://{}/".format(bogus_domain))
 
 
 class urlretrieveNetworkTests(unittest.TestCase):
@@ -150,7 +154,7 @@ class urlretrieveNetworkTests(unittest.TestCase):
 
     def test_basic(self):
         # Test basic functionality.
-        with self.urlretrieve("http://www.example.com/") as (file_location, info):
+        with self.urlretrieve(self.logo) as (file_location, info):
             self.assertTrue(os.path.exists(file_location), "file location returned by"
                             " urlretrieve is not a valid path")
             with open(file_location, 'rb') as f:
@@ -159,7 +163,7 @@ class urlretrieveNetworkTests(unittest.TestCase):
 
     def test_specified_path(self):
         # Make sure that specifying the location of the file to write to works.
-        with self.urlretrieve("http://www.example.com/",
+        with self.urlretrieve(self.logo,
                               support.TESTFN) as (file_location, info):
             self.assertEqual(file_location, support.TESTFN)
             self.assertTrue(os.path.exists(file_location))
@@ -168,11 +172,11 @@ class urlretrieveNetworkTests(unittest.TestCase):
 
     def test_header(self):
         # Make sure header returned as 2nd value from urlretrieve is good.
-        with self.urlretrieve("http://www.example.com/") as (file_location, info):
+        with self.urlretrieve(self.logo) as (file_location, info):
             self.assertIsInstance(info, email.message.Message,
                                   "info is not an instance of email.message.Message")
 
-    logo = "http://www.example.com/"
+    logo = "http://www.pythontest.net/"
 
     def test_data_header(self):
         with self.urlretrieve(self.logo) as (file_location, fileheaders):
@@ -181,7 +185,7 @@ class urlretrieveNetworkTests(unittest.TestCase):
             try:
                 time.strptime(datevalue, dateformat)
             except ValueError:
-                self.fail('Date value not in %r format', dateformat)
+                self.fail('Date value not in %r format' % dateformat)
 
     def test_reporthook(self):
         records = []
index 0552f90..829997f 100644 (file)
@@ -17,7 +17,6 @@ parse_qsl_test_cases = [
     ("=a", [('', 'a')]),
     ("a", [('a', '')]),
     ("a=", [('a', '')]),
-    ("a=", [('a', '')]),
     ("&a=b", [('a', 'b')]),
     ("a=a+b&b=b+c", [('a', 'a b'), ('b', 'b c')]),
     ("a=1&a=2", [('a', '1'), ('a', '2')]),
@@ -28,10 +27,52 @@ parse_qsl_test_cases = [
     (b"=a", [(b'', b'a')]),
     (b"a", [(b'a', b'')]),
     (b"a=", [(b'a', b'')]),
-    (b"a=", [(b'a', b'')]),
     (b"&a=b", [(b'a', b'b')]),
     (b"a=a+b&b=b+c", [(b'a', b'a b'), (b'b', b'b c')]),
     (b"a=1&a=2", [(b'a', b'1'), (b'a', b'2')]),
+    (";", []),
+    (";;", []),
+    (";a=b", [('a', 'b')]),
+    ("a=a+b;b=b+c", [('a', 'a b'), ('b', 'b c')]),
+    ("a=1;a=2", [('a', '1'), ('a', '2')]),
+    (b";", []),
+    (b";;", []),
+    (b";a=b", [(b'a', b'b')]),
+    (b"a=a+b;b=b+c", [(b'a', b'a b'), (b'b', b'b c')]),
+    (b"a=1;a=2", [(b'a', b'1'), (b'a', b'2')]),
+]
+
+parse_qs_test_cases = [
+    ("", {}),
+    ("&", {}),
+    ("&&", {}),
+    ("=", {'': ['']}),
+    ("=a", {'': ['a']}),
+    ("a", {'a': ['']}),
+    ("a=", {'a': ['']}),
+    ("&a=b", {'a': ['b']}),
+    ("a=a+b&b=b+c", {'a': ['a b'], 'b': ['b c']}),
+    ("a=1&a=2", {'a': ['1', '2']}),
+    (b"", {}),
+    (b"&", {}),
+    (b"&&", {}),
+    (b"=", {b'': [b'']}),
+    (b"=a", {b'': [b'a']}),
+    (b"a", {b'a': [b'']}),
+    (b"a=", {b'a': [b'']}),
+    (b"&a=b", {b'a': [b'b']}),
+    (b"a=a+b&b=b+c", {b'a': [b'a b'], b'b': [b'b c']}),
+    (b"a=1&a=2", {b'a': [b'1', b'2']}),
+    (";", {}),
+    (";;", {}),
+    (";a=b", {'a': ['b']}),
+    ("a=a+b;b=b+c", {'a': ['a b'], 'b': ['b c']}),
+    ("a=1;a=2", {'a': ['1', '2']}),
+    (b";", {}),
+    (b";;", {}),
+    (b";a=b", {b'a': [b'b']}),
+    (b"a=a+b;b=b+c", {b'a': [b'a b'], b'b': [b'b c']}),
+    (b"a=1;a=2", {b'a': [b'1', b'2']}),
 ]
 
 class UrlParseTestCase(unittest.TestCase):
@@ -96,6 +137,16 @@ class UrlParseTestCase(unittest.TestCase):
             self.assertEqual(result, expect_without_blanks,
                             "Error parsing %r" % orig)
 
+    def test_qs(self):
+        for orig, expect in parse_qs_test_cases:
+            result = urllib.parse.parse_qs(orig, keep_blank_values=True)
+            self.assertEqual(result, expect, "Error parsing %r" % orig)
+            expect_without_blanks = {v: expect[v]
+                                     for v in expect if len(expect[v][0])}
+            result = urllib.parse.parse_qs(orig, keep_blank_values=False)
+            self.assertEqual(result, expect_without_blanks,
+                            "Error parsing %r" % orig)
+
     def test_roundtrips(self):
         str_cases = [
             ('file:///tmp/junk.txt',
index 1288943..8357f8b 100644 (file)
@@ -1,6 +1,7 @@
 # Check every path through every method of UserDict
 
 from test import support, mapping_tests
+import unittest
 import collections
 
 d0 = {}
index 4a304df..f92e4d3 100644 (file)
@@ -2,6 +2,7 @@
 
 from collections import UserList
 from test import support, list_tests
+import unittest
 
 class UserListTest(list_tests.CommonTest):
     type2test = UserList
index fcb8454..e34d8e6 100644 (file)
@@ -354,7 +354,6 @@ class TestUUID(unittest.TestCase):
             equal(u, uuid.UUID(v))
             equal(str(u), v)
 
-    @unittest.skipUnless(importable('ctypes'), 'requires ctypes')
     def test_uuid4(self):
         equal = self.assertEqual
 
index 9207a68..d2c986e 100644 (file)
@@ -8,6 +8,7 @@ Licensed to the PSF under a contributor agreement.
 import ensurepip
 import os
 import os.path
+import re
 import struct
 import subprocess
 import sys
@@ -25,6 +26,11 @@ try:
 except ImportError:
     ssl = None
 
+try:
+    import threading
+except ImportError:
+    threading = None
+
 skipInVenv = unittest.skipIf(sys.prefix != sys.base_prefix,
                              'Test not appropriate in a venv')
 
@@ -319,6 +325,8 @@ class EnsurePipTest(BaseTest):
 
     # Requesting pip fails without SSL (http://bugs.python.org/issue19744)
     @unittest.skipIf(ssl is None, ensurepip._MISSING_SSL_MESSAGE)
+    @unittest.skipUnless(threading, 'some dependencies of pip import threading'
+                                    ' module unconditionally')
     def test_with_pip(self):
         rmtree(self.env_dir)
         with EnvironmentVarGuard() as envvars:
@@ -387,7 +395,15 @@ class EnsurePipTest(BaseTest):
         # We force everything to text, so unittest gives the detailed diff
         # if we get unexpected results
         err = err.decode("latin-1") # Force to text, prevent decoding errors
-        self.assertEqual(err, "")
+        # Ignore the warning:
+        #   "The directory '$HOME/.cache/pip/http' or its parent directory
+        #    is not owned by the current user and the cache has been disabled.
+        #    Please check the permissions and owner of that directory. If
+        #    executing pip with sudo, you may want sudo's -H flag."
+        # where $HOME is replaced by the HOME environment variable.
+        err = re.sub("^The directory .* or its parent directory is not owned "
+                     "by the current user .*$", "", err, flags=re.MULTILINE)
+        self.assertEqual(err.rstrip(), "")
         # Being fairly specific regarding the expected behaviour for the
         # initial bundling phase in Python 3.4. If the output changes in
         # future pip versions, this test can likely be relaxed further.
index 43869be..3e6a79d 100644 (file)
@@ -4,6 +4,7 @@
 import os
 import time
 import sys
+import unittest
 from test.fork_wait import ForkWait
 from test.support import reap_children, get_attribute
 
index cea9c57..72fcc73 100644 (file)
@@ -104,7 +104,15 @@ class FilterTests(BaseTest):
             message = "FilterTests.test_ignore_after_default"
             def f():
                 self.module.warn(message, UserWarning)
-            f()
+
+            with support.captured_stderr() as stderr:
+                f()
+            stderr = stderr.getvalue()
+            self.assertIn("UserWarning: FilterTests.test_ignore_after_default",
+                          stderr)
+            self.assertIn("self.module.warn(message, UserWarning)",
+                          stderr)
+
             self.module.filterwarnings("error", category=UserWarning)
             self.assertRaises(UserWarning, f)
 
@@ -265,6 +273,53 @@ class FilterTests(BaseTest):
             self.module.warn_explicit(UserWarning("b"), None, "f.py", 42)
             self.assertEqual(str(w[-1].message), "b")
 
+    def test_filterwarnings_duplicate_filters(self):
+        with original_warnings.catch_warnings(module=self.module):
+            self.module.resetwarnings()
+            self.module.filterwarnings("error", category=UserWarning)
+            self.assertEqual(len(self.module.filters), 1)
+            self.module.filterwarnings("ignore", category=UserWarning)
+            self.module.filterwarnings("error", category=UserWarning)
+            self.assertEqual(
+                len(self.module.filters), 2,
+                "filterwarnings inserted duplicate filter"
+            )
+            self.assertEqual(
+                self.module.filters[0][0], "error",
+                "filterwarnings did not promote filter to "
+                "the beginning of list"
+            )
+
+    def test_simplefilter_duplicate_filters(self):
+        with original_warnings.catch_warnings(module=self.module):
+            self.module.resetwarnings()
+            self.module.simplefilter("error", category=UserWarning)
+            self.assertEqual(len(self.module.filters), 1)
+            self.module.simplefilter("ignore", category=UserWarning)
+            self.module.simplefilter("error", category=UserWarning)
+            self.assertEqual(
+                len(self.module.filters), 2,
+                "simplefilter inserted duplicate filter"
+            )
+            self.assertEqual(
+                self.module.filters[0][0], "error",
+                "simplefilter did not promote filter to the beginning of list"
+            )
+    def test_append_duplicate(self):
+        with original_warnings.catch_warnings(module=self.module,
+                record=True) as w:
+            self.module.resetwarnings()
+            self.module.simplefilter("ignore")
+            self.module.simplefilter("error", append=True)
+            self.module.simplefilter("ignore", append=True)
+            self.module.warn("test_append_duplicate", category=UserWarning)
+            self.assertEqual(len(self.module.filters), 2,
+                "simplefilter inserted duplicate filter"
+            )
+            self.assertEqual(len(w), 0,
+                "appended duplicate changed order of filters"
+            )
+
 class CFilterTests(FilterTests, unittest.TestCase):
     module = c_warnings
 
@@ -534,6 +589,14 @@ class WCmdLineTests(BaseTest):
             self.module._setoption('error::Warning::0')
             self.assertRaises(UserWarning, self.module.warn, 'convert to error')
 
+
+class CWCmdLineTests(WCmdLineTests, unittest.TestCase):
+    module = c_warnings
+
+
+class PyWCmdLineTests(WCmdLineTests, unittest.TestCase):
+    module = py_warnings
+
     def test_improper_option(self):
         # Same as above, but check that the message is printed out when
         # the interpreter is executed. This also checks that options are
@@ -550,12 +613,6 @@ class WCmdLineTests(BaseTest):
         self.assertFalse(out.strip())
         self.assertNotIn(b'RuntimeWarning', err)
 
-class CWCmdLineTests(WCmdLineTests, unittest.TestCase):
-    module = c_warnings
-
-class PyWCmdLineTests(WCmdLineTests, unittest.TestCase):
-    module = py_warnings
-
 
 class _WarningsTests(BaseTest, unittest.TestCase):
 
@@ -931,6 +988,7 @@ class BootstrapTest(unittest.TestCase):
             # Use -W to load warnings module at startup
             assert_python_ok('-c', 'pass', '-W', 'always', PYTHONPATH=cwd)
 
+
 class FinalizationTest(unittest.TestCase):
     def test_finalization(self):
         # Issue #19421: warnings.warn() should not crash
@@ -950,6 +1008,23 @@ a=A()
         # of the script
         self.assertEqual(err, b'__main__:7: UserWarning: test')
 
+    def test_late_resource_warning(self):
+        # Issue #21925: Emitting a ResourceWarning late during the Python
+        # shutdown must be logged.
+
+        expected = b"sys:1: ResourceWarning: unclosed file "
+
+        # don't import the warnings module
+        # (_warnings will try to import it)
+        code = "f = open(%a)" % __file__
+        rc, out, err = assert_python_ok("-Wd", "-c", code)
+        self.assertTrue(err.startswith(expected), ascii(err))
+
+        # import the warnings module
+        code = "import warnings; f = open(%a)" % __file__
+        rc, out, err = assert_python_ok("-Wd", "-c", code)
+        self.assertTrue(err.startswith(expected), ascii(err))
+
 
 def setUpModule():
     py_warnings.onceregistry.clear()
index d6ea2ce..32daec1 100644 (file)
@@ -1,3 +1,3 @@
 import warnings
 
-warnings.warn('module-level warning', DeprecationWarning, stacklevel=2)
\ No newline at end of file
+warnings.warn('module-level warning', DeprecationWarning, stacklevel=2)
index f37f1e9..f49cb7e 100644 (file)
@@ -133,6 +133,10 @@ class ReferencesTestCase(TestBase):
         ref1 = weakref.ref(c, callback)
         del c
 
+    def test_constructor_kwargs(self):
+        c = C()
+        self.assertRaises(TypeError, weakref.ref, c, callback=None)
+
     def test_proxy_ref(self):
         o = C()
         o.bar = 1
index 7afb24b..2a78388 100644 (file)
@@ -158,7 +158,7 @@ class PlaySoundTest(unittest.TestCase):
             )
 
     def test_alias_fallback(self):
-        # In the absense of the ability to tell if a sound was actually
+        # In the absence of the ability to tell if a sound was actually
         # played, this test has two acceptable outcomes: success (no error,
         # sound was theoretically played; although as issue #19987 shows
         # a box without a soundcard can "succeed") or RuntimeError.  Any
index 8cca595..61a750c 100644 (file)
@@ -1,17 +1,22 @@
+from unittest import mock
+from test import support
+from test.test_httpservers import NoLogRequestHandler
 from unittest import TestCase
 from wsgiref.util import setup_testing_defaults
 from wsgiref.headers import Headers
-from wsgiref.handlers import BaseHandler, BaseCGIHandler
+from wsgiref.handlers import BaseHandler, BaseCGIHandler, SimpleHandler
 from wsgiref import util
 from wsgiref.validate import validator
 from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
 from wsgiref.simple_server import make_server
+from http.client import HTTPConnection
 from io import StringIO, BytesIO, BufferedReader
 from socketserver import BaseServer
 from platform import python_implementation
 
 import os
 import re
+import signal
 import sys
 import unittest
 
@@ -166,6 +171,27 @@ class IntegrationTests(TestCase):
             " be of type list: <class 'tuple'>"
         )
 
+    def test_status_validation_errors(self):
+        def create_bad_app(status):
+            def bad_app(environ, start_response):
+                start_response(status, [("Content-Type", "text/plain; charset=utf-8")])
+                return [b"Hello, world!"]
+            return bad_app
+
+        tests = [
+            ('200', 'AssertionError: Status must be at least 4 characters'),
+            ('20X OK', 'AssertionError: Status message must begin w/3-digit code'),
+            ('200OK', 'AssertionError: Status message must have a space after code'),
+        ]
+
+        for status, exc_message in tests:
+            with self.subTest(status=status):
+                out, err = run_amock(create_bad_app(status))
+                self.assertTrue(out.endswith(
+                    b"A server error occurred.  Please contact the administrator."
+                ))
+                self.assertEqual(err.splitlines()[-2], exc_message)
+
     def test_wsgi_input(self):
         def bad_app(e,s):
             e["wsgi.input"].read()
@@ -200,6 +226,79 @@ class IntegrationTests(TestCase):
                 b"data",
                 out)
 
+    def test_cp1252_url(self):
+        def app(e, s):
+            s("200 OK", [
+                ("Content-Type", "text/plain"),
+                ("Date", "Wed, 24 Dec 2008 13:29:32 GMT"),
+                ])
+            # PEP3333 says environ variables are decoded as latin1.
+            # Encode as latin1 to get original bytes
+            return [e["PATH_INFO"].encode("latin1")]
+
+        out, err = run_amock(
+            validator(app), data=b"GET /\x80%80 HTTP/1.0")
+        self.assertEqual(
+            [
+                b"HTTP/1.0 200 OK",
+                mock.ANY,
+                b"Content-Type: text/plain",
+                b"Date: Wed, 24 Dec 2008 13:29:32 GMT",
+                b"",
+                b"/\x80\x80",
+            ],
+            out.splitlines())
+
+    def test_interrupted_write(self):
+        # BaseHandler._write() and _flush() have to write all data, even if
+        # it takes multiple send() calls.  Test this by interrupting a send()
+        # call with a Unix signal.
+        threading = support.import_module("threading")
+        pthread_kill = support.get_attribute(signal, "pthread_kill")
+
+        def app(environ, start_response):
+            start_response("200 OK", [])
+            return [bytes(support.SOCK_MAX_SIZE)]
+
+        class WsgiHandler(NoLogRequestHandler, WSGIRequestHandler):
+            pass
+
+        server = make_server(support.HOST, 0, app, handler_class=WsgiHandler)
+        self.addCleanup(server.server_close)
+        interrupted = threading.Event()
+
+        def signal_handler(signum, frame):
+            interrupted.set()
+
+        original = signal.signal(signal.SIGUSR1, signal_handler)
+        self.addCleanup(signal.signal, signal.SIGUSR1, original)
+        received = None
+        main_thread = threading.get_ident()
+
+        def run_client():
+            http = HTTPConnection(*server.server_address)
+            http.request("GET", "/")
+            with http.getresponse() as response:
+                response.read(100)
+                # The main thread should now be blocking in a send() system
+                # call.  But in theory, it could get interrupted by other
+                # signals, and then retried.  So keep sending the signal in a
+                # loop, in case an earlier signal happens to be delivered at
+                # an inconvenient moment.
+                while True:
+                    pthread_kill(main_thread, signal.SIGUSR1)
+                    if interrupted.wait(timeout=float(1)):
+                        break
+                nonlocal received
+                received = len(response.read())
+            http.close()
+
+        background = threading.Thread(target=run_client)
+        background.start()
+        server.handle_request()
+        background.join()
+        self.assertEqual(received, support.SOCK_MAX_SIZE - 100)
+
 
 class UtilityTests(TestCase):
 
@@ -656,6 +755,31 @@ class HandlerTests(TestCase):
         h.run(error_app)
         self.assertEqual(side_effects['close_called'], True)
 
+    def testPartialWrite(self):
+        written = bytearray()
+
+        class PartialWriter:
+            def write(self, b):
+                partial = b[:7]
+                written.extend(partial)
+                return len(partial)
+
+            def flush(self):
+                pass
+
+        environ = {"SERVER_PROTOCOL": "HTTP/1.0"}
+        h = SimpleHandler(BytesIO(), PartialWriter(), sys.stderr, environ)
+        msg = "should not do partial writes"
+        with self.assertWarnsRegex(DeprecationWarning, msg):
+            h.run(hello_app)
+        self.assertEqual(b"HTTP/1.0 200 OK\r\n"
+            b"Content-Type: text/plain\r\n"
+            b"Date: Mon, 05 Jun 2006 18:49:54 GMT\r\n"
+            b"Content-Length: 13\r\n"
+            b"\r\n"
+            b"Hello, world!",
+            written)
+
 
 if __name__ == "__main__":
     unittest.main()
index 47c4de6..3b03dfc 100644 (file)
@@ -1,5 +1,6 @@
 # Tests for xml.dom.minicompat
 
+import copy
 import pickle
 import unittest
 
@@ -89,6 +90,7 @@ class NodeListTestCase(unittest.TestCase):
             node_list = NodeList()
             pickled = pickle.dumps(node_list, proto)
             unpickled = pickle.loads(pickled)
+            self.assertIsNot(unpickled, node_list)
             self.assertEqual(unpickled, node_list)
 
             # Non-empty NodeList.
@@ -96,7 +98,41 @@ class NodeListTestCase(unittest.TestCase):
             node_list.append(2)
             pickled = pickle.dumps(node_list, proto)
             unpickled = pickle.loads(pickled)
+            self.assertIsNot(unpickled, node_list)
             self.assertEqual(unpickled, node_list)
 
+    def test_nodelist_copy(self):
+        # Empty NodeList.
+        node_list = NodeList()
+        copied = copy.copy(node_list)
+        self.assertIsNot(copied, node_list)
+        self.assertEqual(copied, node_list)
+
+        # Non-empty NodeList.
+        node_list.append([1])
+        node_list.append([2])
+        copied = copy.copy(node_list)
+        self.assertIsNot(copied, node_list)
+        self.assertEqual(copied, node_list)
+        for x, y in zip(copied, node_list):
+            self.assertIs(x, y)
+
+    def test_nodelist_deepcopy(self):
+        # Empty NodeList.
+        node_list = NodeList()
+        copied = copy.deepcopy(node_list)
+        self.assertIsNot(copied, node_list)
+        self.assertEqual(copied, node_list)
+
+        # Non-empty NodeList.
+        node_list.append([1])
+        node_list.append([2])
+        copied = copy.deepcopy(node_list)
+        self.assertIsNot(copied, node_list)
+        self.assertEqual(copied, node_list)
+        for x, y in zip(copied, node_list):
+            self.assertIsNot(x, y)
+            self.assertEqual(x, y)
+
 if __name__ == '__main__':
     unittest.main()
index d09b969..44e3142 100644 (file)
@@ -244,6 +244,33 @@ class ElementTreeTest(unittest.TestCase):
         self.assertEqual(ET.XML, ET.fromstring)
         self.assertEqual(ET.PI, ET.ProcessingInstruction)
 
+    def test_set_attribute(self):
+        element = ET.Element('tag')
+
+        self.assertEqual(element.tag, 'tag')
+        element.tag = 'Tag'
+        self.assertEqual(element.tag, 'Tag')
+        element.tag = 'TAG'
+        self.assertEqual(element.tag, 'TAG')
+
+        self.assertIsNone(element.text)
+        element.text = 'Text'
+        self.assertEqual(element.text, 'Text')
+        element.text = 'TEXT'
+        self.assertEqual(element.text, 'TEXT')
+
+        self.assertIsNone(element.tail)
+        element.tail = 'Tail'
+        self.assertEqual(element.tail, 'Tail')
+        element.tail = 'TAIL'
+        self.assertEqual(element.tail, 'TAIL')
+
+        self.assertEqual(element.attrib, {})
+        element.attrib = {'a': 'b', 'c': 'd'}
+        self.assertEqual(element.attrib, {'a': 'b', 'c': 'd'})
+        element.attrib = {'A': 'B', 'C': 'D'}
+        self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'})
+
     def test_simpleops(self):
         # Basic method sanity checks.
 
@@ -534,11 +561,18 @@ class ElementTreeTest(unittest.TestCase):
         self.assertEqual(res, ['start-ns', 'end-ns'])
 
         events = ("start", "end", "bogus")
-        with self.assertRaises(ValueError) as cm:
-            with open(SIMPLE_XMLFILE, "rb") as f:
+        with open(SIMPLE_XMLFILE, "rb") as f:
+            with self.assertRaises(ValueError) as cm:
                 iterparse(f, events)
+            self.assertFalse(f.closed)
         self.assertEqual(str(cm.exception), "unknown event 'bogus'")
 
+        with support.check_no_resource_warning(self):
+            with self.assertRaises(ValueError) as cm:
+                iterparse(SIMPLE_XMLFILE, events)
+            self.assertEqual(str(cm.exception), "unknown event 'bogus'")
+            del cm
+
         source = io.BytesIO(
             b"<?xml version='1.0' encoding='iso-8859-1'?>\n"
             b"<body xmlns='http://&#233;ffbot.org/ns'\n"
@@ -559,6 +593,18 @@ class ElementTreeTest(unittest.TestCase):
         self.assertEqual(str(cm.exception),
                 'junk after document element: line 1, column 12')
 
+        with open(TESTFN, "wb") as f:
+            f.write(b"<document />junk")
+        it = iterparse(TESTFN)
+        action, elem = next(it)
+        self.assertEqual((action, elem.tag), ('end', 'document'))
+        with support.check_no_resource_warning(self):
+            with self.assertRaises(ET.ParseError) as cm:
+                next(it)
+            self.assertEqual(str(cm.exception),
+                    'junk after document element: line 1, column 12')
+            del cm, it
+
     def test_writefile(self):
         elem = ET.Element("tag")
         elem.text = "text"
@@ -1614,6 +1660,57 @@ class BugsTest(unittest.TestCase):
         ET.register_namespace('test10777', 'http://myuri/')
         ET.register_namespace('test10777', 'http://myuri/')
 
+    def test_lost_text(self):
+        # Issue #25902: Borrowed text can disappear
+        class Text:
+            def __bool__(self):
+                e.text = 'changed'
+                return True
+
+        e = ET.Element('tag')
+        e.text = Text()
+        i = e.itertext()
+        t = next(i)
+        self.assertIsInstance(t, Text)
+        self.assertIsInstance(e.text, str)
+        self.assertEqual(e.text, 'changed')
+
+    def test_lost_tail(self):
+        # Issue #25902: Borrowed tail can disappear
+        class Text:
+            def __bool__(self):
+                e[0].tail = 'changed'
+                return True
+
+        e = ET.Element('root')
+        e.append(ET.Element('tag'))
+        e[0].tail = Text()
+        i = e.itertext()
+        t = next(i)
+        self.assertIsInstance(t, Text)
+        self.assertIsInstance(e[0].tail, str)
+        self.assertEqual(e[0].tail, 'changed')
+
+    def test_lost_elem(self):
+        # Issue #25902: Borrowed element can disappear
+        class Tag:
+            def __eq__(self, other):
+                e[0] = ET.Element('changed')
+                next(i)
+                return True
+
+        e = ET.Element('root')
+        e.append(ET.Element(Tag()))
+        e.append(ET.Element('tag'))
+        i = e.iter('tag')
+        try:
+            t = next(i)
+        except ValueError:
+            self.skipTest('generators are not reentrant')
+        self.assertIsInstance(t.tag, Tag)
+        self.assertIsInstance(e[0].tag, str)
+        self.assertEqual(e[0].tag, 'changed')
+
 
 # --------------------------------------------------------------------
 
@@ -2350,6 +2447,7 @@ class ElementSlicingTest(unittest.TestCase):
         self.assertEqual(e[-2].tag, 'a8')
 
         self.assertRaises(IndexError, lambda: e[12])
+        self.assertRaises(IndexError, lambda: e[-12])
 
     def test_getslice_range(self):
         e = self._make_elem_with_children(6)
@@ -2368,12 +2466,17 @@ class ElementSlicingTest(unittest.TestCase):
         self.assertEqual(self._elem_tags(e[::3]), ['a0', 'a3', 'a6', 'a9'])
         self.assertEqual(self._elem_tags(e[::8]), ['a0', 'a8'])
         self.assertEqual(self._elem_tags(e[1::8]), ['a1', 'a9'])
+        self.assertEqual(self._elem_tags(e[3::sys.maxsize]), ['a3'])
+        self.assertEqual(self._elem_tags(e[3::sys.maxsize<<64]), ['a3'])
 
     def test_getslice_negative_steps(self):
         e = self._make_elem_with_children(4)
 
         self.assertEqual(self._elem_tags(e[::-1]), ['a3', 'a2', 'a1', 'a0'])
         self.assertEqual(self._elem_tags(e[::-2]), ['a3', 'a1'])
+        self.assertEqual(self._elem_tags(e[3::-sys.maxsize]), ['a3'])
+        self.assertEqual(self._elem_tags(e[3::-sys.maxsize-1]), ['a3'])
+        self.assertEqual(self._elem_tags(e[3::-sys.maxsize<<64]), ['a3'])
 
     def test_delslice(self):
         e = self._make_elem_with_children(4)
@@ -2400,6 +2503,75 @@ class ElementSlicingTest(unittest.TestCase):
         del e[::2]
         self.assertEqual(self._subelem_tags(e), ['a1'])
 
+    def test_setslice_single_index(self):
+        e = self._make_elem_with_children(4)
+        e[1] = ET.Element('b')
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
+
+        e[-2] = ET.Element('c')
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3'])
+
+        with self.assertRaises(IndexError):
+            e[5] = ET.Element('d')
+        with self.assertRaises(IndexError):
+            e[-5] = ET.Element('d')
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3'])
+
+    def test_setslice_range(self):
+        e = self._make_elem_with_children(4)
+        e[1:3] = [ET.Element('b%s' % i) for i in range(2)]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'a3'])
+
+        e = self._make_elem_with_children(4)
+        e[1:3] = [ET.Element('b')]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a3'])
+
+        e = self._make_elem_with_children(4)
+        e[1:3] = [ET.Element('b%s' % i) for i in range(3)]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'b2', 'a3'])
+
+    def test_setslice_steps(self):
+        e = self._make_elem_with_children(6)
+        e[1:5:2] = [ET.Element('b%s' % i) for i in range(2)]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'a2', 'b1', 'a4', 'a5'])
+
+        e = self._make_elem_with_children(6)
+        with self.assertRaises(ValueError):
+            e[1:5:2] = [ET.Element('b')]
+        with self.assertRaises(ValueError):
+            e[1:5:2] = [ET.Element('b%s' % i) for i in range(3)]
+        with self.assertRaises(ValueError):
+            e[1:5:2] = []
+        self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3', 'a4', 'a5'])
+
+        e = self._make_elem_with_children(4)
+        e[1::sys.maxsize] = [ET.Element('b')]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
+        e[1::sys.maxsize<<64] = [ET.Element('c')]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3'])
+
+    def test_setslice_negative_steps(self):
+        e = self._make_elem_with_children(4)
+        e[2:0:-1] = [ET.Element('b%s' % i) for i in range(2)]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b1', 'b0', 'a3'])
+
+        e = self._make_elem_with_children(4)
+        with self.assertRaises(ValueError):
+            e[2:0:-1] = [ET.Element('b')]
+        with self.assertRaises(ValueError):
+            e[2:0:-1] = [ET.Element('b%s' % i) for i in range(3)]
+        with self.assertRaises(ValueError):
+            e[2:0:-1] = []
+        self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3'])
+
+        e = self._make_elem_with_children(4)
+        e[1::-sys.maxsize] = [ET.Element('b')]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
+        e[1::-sys.maxsize-1] = [ET.Element('c')]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3'])
+        e[1::-sys.maxsize<<64] = [ET.Element('d')]
+        self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3'])
+
 
 class IOTest(unittest.TestCase):
     def tearDown(self):
index d0df38d..96b446e 100644 (file)
@@ -22,6 +22,38 @@ class MiscTests(unittest.TestCase):
         finally:
             data = None
 
+    def test_del_attribute(self):
+        element = cET.Element('tag')
+
+        element.tag = 'TAG'
+        with self.assertRaises(AttributeError):
+            del element.tag
+        self.assertEqual(element.tag, 'TAG')
+
+        with self.assertRaises(AttributeError):
+            del element.text
+        self.assertIsNone(element.text)
+        element.text = 'TEXT'
+        with self.assertRaises(AttributeError):
+            del element.text
+        self.assertEqual(element.text, 'TEXT')
+
+        with self.assertRaises(AttributeError):
+            del element.tail
+        self.assertIsNone(element.tail)
+        element.tail = 'TAIL'
+        with self.assertRaises(AttributeError):
+            del element.tail
+        self.assertEqual(element.tail, 'TAIL')
+
+        with self.assertRaises(AttributeError):
+            del element.attrib
+        self.assertEqual(element.attrib, {})
+        element.attrib = {'A': 'B', 'C': 'D'}
+        with self.assertRaises(AttributeError):
+            del element.attrib
+        self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'})
+
 
 @unittest.skipUnless(cET, 'requires _elementtree')
 class TestAliasWorking(unittest.TestCase):
index 9880f4a..02d9f5c 100644 (file)
@@ -7,6 +7,7 @@ from unittest import mock
 import xmlrpc.client as xmlrpclib
 import xmlrpc.server
 import http.client
+import http, http.server
 import socket
 import os
 import re
@@ -183,6 +184,27 @@ class XMLRPCTestCase(unittest.TestCase):
                           xmlrpclib.loads(strg)[0][0])
         self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
 
+    def test_dump_encoding(self):
+        value = {'key\u20ac\xa4':
+                 'value\u20ac\xa4'}
+        strg = xmlrpclib.dumps((value,), encoding='iso-8859-15')
+        strg = "<?xml version='1.0' encoding='iso-8859-15'?>" + strg
+        self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
+        strg = strg.encode('iso-8859-15', 'xmlcharrefreplace')
+        self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
+
+        strg = xmlrpclib.dumps((value,), encoding='iso-8859-15',
+                               methodresponse=True)
+        self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
+        strg = strg.encode('iso-8859-15', 'xmlcharrefreplace')
+        self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
+
+        methodname = 'method\u20ac\xa4'
+        strg = xmlrpclib.dumps((value,), encoding='iso-8859-15',
+                               methodname=methodname)
+        self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
+        self.assertEqual(xmlrpclib.loads(strg)[1], methodname)
+
     def test_dump_bytes(self):
         sample = b"my dog has fleas"
         self.assertEqual(sample, xmlrpclib.Binary(sample))
@@ -202,6 +224,20 @@ class XMLRPCTestCase(unittest.TestCase):
             self.assertIs(type(newvalue), xmlrpclib.Binary)
             self.assertIsNone(m)
 
+    def test_loads_unsupported(self):
+        ResponseError = xmlrpclib.ResponseError
+        data = '<params><param><value><spam/></value></param></params>'
+        self.assertRaises(ResponseError, xmlrpclib.loads, data)
+        data = ('<params><param><value><array>'
+                '<value><spam/></value>'
+                '</array></value></param></params>')
+        self.assertRaises(ResponseError, xmlrpclib.loads, data)
+        data = ('<params><param><value><struct>'
+                '<member><name>a</name><value><spam/></value></member>'
+                '<member><name>b</name><value><spam/></value></member>'
+                '</struct></value></param></params>')
+        self.assertRaises(ResponseError, xmlrpclib.loads, data)
+
     def test_get_host_info(self):
         # see bug #3613, this raised a TypeError
         transp = xmlrpc.client.Transport()
@@ -223,6 +259,42 @@ class XMLRPCTestCase(unittest.TestCase):
         except OSError:
             self.assertTrue(has_ssl)
 
+    @unittest.skipUnless(threading, "Threading required for this test.")
+    def test_keepalive_disconnect(self):
+        class RequestHandler(http.server.BaseHTTPRequestHandler):
+            protocol_version = "HTTP/1.1"
+            handled = False
+
+            def do_POST(self):
+                length = int(self.headers.get("Content-Length"))
+                self.rfile.read(length)
+                if self.handled:
+                    self.close_connection = True
+                    return
+                response = xmlrpclib.dumps((5,), methodresponse=True)
+                response = response.encode()
+                self.send_response(http.HTTPStatus.OK)
+                self.send_header("Content-Length", len(response))
+                self.end_headers()
+                self.wfile.write(response)
+                self.handled = True
+                self.close_connection = False
+
+        def run_server():
+            server.socket.settimeout(float(1))  # Don't hang if client fails
+            server.handle_request()  # First request and attempt at second
+            server.handle_request()  # Retried second request
+
+        server = http.server.HTTPServer((support.HOST, 0), RequestHandler)
+        self.addCleanup(server.server_close)
+        thread = threading.Thread(target=run_server)
+        thread.start()
+        self.addCleanup(thread.join)
+        url = "http://{}:{}/".format(*server.server_address)
+        with xmlrpclib.ServerProxy(url) as p:
+            self.assertEqual(p.method(), 5)
+            self.assertEqual(p.method(), 5)
+
 class HelperTestCase(unittest.TestCase):
     def test_escape(self):
         self.assertEqual(xmlrpclib.escape("a&b"), "a&amp;b")
@@ -371,7 +443,7 @@ ADDR = PORT = URL = None
 # The evt is set twice.  First when the server is ready to serve.
 # Second when the server has been shutdown.  The user must clear
 # the event after it has been set the first time to catch the second set.
-def http_server(evt, numrequests, requestHandler=None):
+def http_server(evt, numrequests, requestHandler=None, encoding=None):
     class TestInstanceClass:
         def div(self, x, y):
             return x // y
@@ -400,6 +472,7 @@ def http_server(evt, numrequests, requestHandler=None):
     if not requestHandler:
         requestHandler = xmlrpc.server.SimpleXMLRPCRequestHandler
     serv = MyXMLRPCServer(("localhost", 0), requestHandler,
+                          encoding=encoding,
                           logRequests=False, bind_and_activate=False)
     try:
         serv.server_bind()
@@ -415,6 +488,7 @@ def http_server(evt, numrequests, requestHandler=None):
         serv.register_multicall_functions()
         serv.register_function(pow)
         serv.register_function(lambda x,y: x+y, 'add')
+        serv.register_function(lambda x: x, 'têšt')
         serv.register_function(my_function)
         testInstance = TestInstanceClass()
         serv.register_instance(testInstance, allow_dotted_names=True)
@@ -582,6 +656,30 @@ class SimpleServerTestCase(BaseServerTestCase):
                 # protocol error; provide additional information in test output
                 self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
+    def test_client_encoding(self):
+        start_string = '\u20ac'
+        end_string = '\xa4'
+
+        try:
+            p = xmlrpclib.ServerProxy(URL, encoding='iso-8859-15')
+            self.assertEqual(p.add(start_string, end_string),
+                             start_string + end_string)
+        except (xmlrpclib.ProtocolError, socket.error) as e:
+            # ignore failures due to non-blocking socket unavailable errors.
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
+
+    def test_nonascii_methodname(self):
+        try:
+            p = xmlrpclib.ServerProxy(URL, encoding='ascii')
+            self.assertEqual(p.têšt(42), 42)
+        except (xmlrpclib.ProtocolError, socket.error) as e:
+            # ignore failures due to non-blocking socket unavailable errors.
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
+
     # [ch] The test 404 is causing lots of false alarms.
     def XXXtest_404(self):
         # send POST with http.client, it should return 404 header and
@@ -595,7 +693,7 @@ class SimpleServerTestCase(BaseServerTestCase):
         self.assertEqual(response.reason, 'Not Found')
 
     def test_introspection1(self):
-        expected_methods = set(['pow', 'div', 'my_function', 'add',
+        expected_methods = set(['pow', 'div', 'my_function', 'add', 'têšt',
                                 'system.listMethods', 'system.methodHelp',
                                 'system.methodSignature', 'system.multicall',
                                 'Fixture'])
@@ -731,6 +829,26 @@ class SimpleServerTestCase(BaseServerTestCase):
                          (None, None))
 
 
+class SimpleServerEncodingTestCase(BaseServerTestCase):
+    @staticmethod
+    def threadFunc(evt, numrequests, requestHandler=None, encoding=None):
+        http_server(evt, numrequests, requestHandler, 'iso-8859-15')
+
+    def test_server_encoding(self):
+        start_string = '\u20ac'
+        end_string = '\xa4'
+
+        try:
+            p = xmlrpclib.ServerProxy(URL)
+            self.assertEqual(p.add(start_string, end_string),
+                             start_string + end_string)
+        except (xmlrpclib.ProtocolError, socket.error) as e:
+            # ignore failures due to non-blocking socket unavailable errors.
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
+
+
 class MultiPathServerTestCase(BaseServerTestCase):
     threadFunc = staticmethod(http_multi_server)
     request_count = 2
@@ -1143,8 +1261,9 @@ class UseBuiltinTypesTestCase(unittest.TestCase):
 def test_main():
     support.run_unittest(XMLRPCTestCase, HelperTestCase, DateTimeTestCase,
             BinaryTestCase, FaultTestCase, UseBuiltinTypesTestCase,
-            SimpleServerTestCase, KeepaliveServerTestCase1,
-            KeepaliveServerTestCase2, GzipServerTestCase, GzipUtilTestCase,
+            SimpleServerTestCase, SimpleServerEncodingTestCase,
+            KeepaliveServerTestCase1, KeepaliveServerTestCase2,
+            GzipServerTestCase, GzipUtilTestCase,
             MultiPathServerTestCase, ServerProxyTestCase, FailingServerTestCase,
             CGIHandlerTestCase)
 
index 9734380..d8d4437 100644 (file)
@@ -195,7 +195,7 @@ class ZipAppTest(unittest.TestCase):
         self.assertTrue(new_target.getvalue().startswith(b'#!python2.7\n'))
 
     def test_read_from_pathobj(self):
-        # Test that we can copy an archive using an pathlib.Path object
+        # Test that we can copy an archive using a pathlib.Path object
         # for the source.
         source = self.tmpdir / 'source'
         source.mkdir()
index 2c10821..d278e06 100644 (file)
@@ -1809,11 +1809,12 @@ class TestsWithMultipleOpens(unittest.TestCase):
         for f in get_files(self):
             self.make_test_archive(f)
             with zipfile.ZipFile(f, mode="r") as zipf:
-                with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2:
+                with zipf.open('ones') as zopen1:
                     data1 = zopen1.read(500)
-                    data2 = zopen2.read(500)
-                    data1 += zopen1.read()
-                    data2 += zopen2.read()
+                    with zipf.open('twos') as zopen2:
+                        data2 = zopen2.read(500)
+                        data1 += zopen1.read()
+                        data2 += zopen2.read()
                 self.assertEqual(data1, self.data1)
                 self.assertEqual(data2, self.data2)
 
index 7dea8a3..c29bd8d 100644 (file)
@@ -3,7 +3,7 @@
 # from test_zipfile
 from test import support
 
-# XXX(nnorwitz): disable this test by looking for extra largfile resource
+# XXX(nnorwitz): disable this test by looking for extralargefile resource,
 # which doesn't exist.  This test takes over 30 minutes to run in general
 # and requires more disk space than most of the buildbots.
 support.requires(
@@ -72,15 +72,19 @@ class TestsWithSourceFile(unittest.TestCase):
     def testStored(self):
         # Try the temp file first.  If we do TESTFN2 first, then it hogs
         # gigabytes of disk space for the duration of the test.
-        for f in TemporaryFile(), TESTFN2:
+        with TemporaryFile() as f:
             self.zipTest(f, zipfile.ZIP_STORED)
+            self.assertFalse(f.closed)
+        self.zipTest(TESTFN2, zipfile.ZIP_STORED)
 
     @requires_zlib
     def testDeflated(self):
         # Try the temp file first.  If we do TESTFN2 first, then it hogs
         # gigabytes of disk space for the duration of the test.
-        for f in TemporaryFile(), TESTFN2:
+        with TemporaryFile() as f:
             self.zipTest(f, zipfile.ZIP_DEFLATED)
+            self.assertFalse(f.closed)
+        self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED)
 
     def tearDown(self):
         for fname in TESTFN, TESTFN2:
index a97a778..0da5906 100644 (file)
@@ -1,6 +1,7 @@
 import sys
 import os
 import marshal
+import importlib
 import importlib.util
 import struct
 import time
@@ -48,6 +49,7 @@ test_pyc = make_pyc(test_co, NOW, len(test_src))
 TESTMOD = "ziptestmodule"
 TESTPACK = "ziptestpackage"
 TESTPACK2 = "ziptestpackage2"
+TEMP_DIR = os.path.abspath("junk95142")
 TEMP_ZIP = os.path.abspath("junk95142.zip")
 
 pyc_file = importlib.util.cache_from_source(TESTMOD + '.py')
@@ -77,45 +79,64 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
 
     def setUp(self):
         # We're reusing the zip archive path, so we must clear the
-        # cached directory info and linecache
+        # cached directory info and linecache.
         linecache.clearcache()
         zipimport._zip_directory_cache.clear()
         ImportHooksBaseTestCase.setUp(self)
 
-    def doTest(self, expected_ext, files, *modules, **kw):
-        z = ZipFile(TEMP_ZIP, "w")
-        try:
+    def makeTree(self, files, dirName=TEMP_DIR):
+        # Create a filesystem based set of modules/packages
+        # defined by files under the directory dirName.
+        self.addCleanup(support.rmtree, dirName)
+
+        for name, (mtime, data) in files.items():
+            path = os.path.join(dirName, name)
+            if path[-1] == os.sep:
+                if not os.path.isdir(path):
+                    os.makedirs(path)
+            else:
+                dname = os.path.dirname(path)
+                if not os.path.isdir(dname):
+                    os.makedirs(dname)
+                with open(path, 'wb') as fp:
+                    fp.write(data)
+
+    def makeZip(self, files, zipName=TEMP_ZIP, **kw):
+        # Create a zip archive based set of modules/packages
+        # defined by files in the zip file zipName.  If the
+        # key 'stuff' exists in kw it is prepended to the archive.
+        self.addCleanup(support.unlink, zipName)
+
+        with ZipFile(zipName, "w") as z:
             for name, (mtime, data) in files.items():
                 zinfo = ZipInfo(name, time.localtime(mtime))
                 zinfo.compress_type = self.compression
                 z.writestr(zinfo, data)
-            z.close()
 
-            stuff = kw.get("stuff", None)
-            if stuff is not None:
-                # Prepend 'stuff' to the start of the zipfile
-                with open(TEMP_ZIP, "rb") as f:
-                    data = f.read()
-                with open(TEMP_ZIP, "wb") as f:
-                    f.write(stuff)
-                    f.write(data)
+        stuff = kw.get("stuff", None)
+        if stuff is not None:
+            # Prepend 'stuff' to the start of the zipfile
+            with open(zipName, "rb") as f:
+                data = f.read()
+            with open(zipName, "wb") as f:
+                f.write(stuff)
+                f.write(data)
+
+    def doTest(self, expected_ext, files, *modules, **kw):
+        self.makeZip(files, **kw)
 
-            sys.path.insert(0, TEMP_ZIP)
+        sys.path.insert(0, TEMP_ZIP)
 
-            mod = __import__(".".join(modules), globals(), locals(),
-                             ["__dummy__"])
+        mod = importlib.import_module(".".join(modules))
 
-            call = kw.get('call')
-            if call is not None:
-                call(mod)
+        call = kw.get('call')
+        if call is not None:
+            call(mod)
 
-            if expected_ext:
-                file = mod.get_file()
-                self.assertEqual(file, os.path.join(TEMP_ZIP,
+        if expected_ext:
+            file = mod.get_file()
+            self.assertEqual(file, os.path.join(TEMP_ZIP,
                                  *modules) + expected_ext)
-        finally:
-            z.close()
-            os.remove(TEMP_ZIP)
 
     def testAFakeZlib(self):
         #
@@ -201,7 +222,9 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
                  packdir + TESTMOD + pyc_ext: (NOW, test_pyc)}
         self.doTest(pyc_ext, files, TESTPACK, TESTMOD)
 
-    def testDeepPackage(self):
+    def testSubPackage(self):
+        # Test that subpackages function when loaded from zip
+        # archives.
         packdir = TESTPACK + os.sep
         packdir2 = packdir + TESTPACK2 + os.sep
         files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc),
@@ -209,6 +232,167 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
                  packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
         self.doTest(pyc_ext, files, TESTPACK, TESTPACK2, TESTMOD)
 
+    def testSubNamespacePackage(self):
+        # Test that implicit namespace subpackages function
+        # when loaded from zip archives.
+        packdir = TESTPACK + os.sep
+        packdir2 = packdir + TESTPACK2 + os.sep
+        # The first two files are just directory entries (so have no data).
+        files = {packdir: (NOW, ""),
+                 packdir2: (NOW, ""),
+                 packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
+        self.doTest(pyc_ext, files, TESTPACK, TESTPACK2, TESTMOD)
+
+    def testMixedNamespacePackage(self):
+        # Test implicit namespace packages spread between a
+        # real filesystem and a zip archive.
+        packdir = TESTPACK + os.sep
+        packdir2 = packdir + TESTPACK2 + os.sep
+        packdir3 = packdir2 + TESTPACK + '3' + os.sep
+        files1 = {packdir: (NOW, ""),
+                  packdir + TESTMOD + pyc_ext: (NOW, test_pyc),
+                  packdir2: (NOW, ""),
+                  packdir3: (NOW, ""),
+                  packdir3 + TESTMOD + pyc_ext: (NOW, test_pyc),
+                  packdir2 + TESTMOD + '3' + pyc_ext: (NOW, test_pyc),
+                  packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
+        files2 = {packdir: (NOW, ""),
+                  packdir + TESTMOD + '2' + pyc_ext: (NOW, test_pyc),
+                  packdir2: (NOW, ""),
+                  packdir2 + TESTMOD + '2' + pyc_ext: (NOW, test_pyc),
+                  packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
+
+        zip1 = os.path.abspath("path1.zip")
+        self.makeZip(files1, zip1)
+
+        zip2 = TEMP_DIR
+        self.makeTree(files2, zip2)
+
+        # zip2 should override zip1.
+        sys.path.insert(0, zip1)
+        sys.path.insert(0, zip2)
+
+        mod = importlib.import_module(TESTPACK)
+
+        # if TESTPACK is functioning as a namespace pkg then
+        # there should be two entries in the __path__.
+        # First should be path2 and second path1.
+        self.assertEqual(2, len(mod.__path__))
+        p1, p2 = mod.__path__
+        self.assertEqual(os.path.basename(TEMP_DIR), p1.split(os.sep)[-2])
+        self.assertEqual("path1.zip", p2.split(os.sep)[-2])
+
+        # packdir3 should import as a namespace package.
+        # Its __path__ is an iterable of 1 element from zip1.
+        mod = importlib.import_module(packdir3.replace(os.sep, '.')[:-1])
+        self.assertEqual(1, len(mod.__path__))
+        mpath = list(mod.__path__)[0].split('path1.zip' + os.sep)[1]
+        self.assertEqual(packdir3[:-1], mpath)
+
+        # TESTPACK/TESTMOD only exists in path1.
+        mod = importlib.import_module('.'.join((TESTPACK, TESTMOD)))
+        self.assertEqual("path1.zip", mod.__file__.split(os.sep)[-3])
+
+        # And TESTPACK/(TESTMOD + '2') only exists in path2.
+        mod = importlib.import_module('.'.join((TESTPACK, TESTMOD + '2')))
+        self.assertEqual(os.path.basename(TEMP_DIR),
+                         mod.__file__.split(os.sep)[-3])
+
+        # One level deeper...
+        subpkg = '.'.join((TESTPACK, TESTPACK2))
+        mod = importlib.import_module(subpkg)
+        self.assertEqual(2, len(mod.__path__))
+        p1, p2 = mod.__path__
+        self.assertEqual(os.path.basename(TEMP_DIR), p1.split(os.sep)[-3])
+        self.assertEqual("path1.zip", p2.split(os.sep)[-3])
+
+        # subpkg.TESTMOD exists in both zips should load from zip2.
+        mod = importlib.import_module('.'.join((subpkg, TESTMOD)))
+        self.assertEqual(os.path.basename(TEMP_DIR),
+                         mod.__file__.split(os.sep)[-4])
+
+        # subpkg.TESTMOD + '2' only exists in zip2.
+        mod = importlib.import_module('.'.join((subpkg, TESTMOD + '2')))
+        self.assertEqual(os.path.basename(TEMP_DIR),
+                         mod.__file__.split(os.sep)[-4])
+
+        # Finally subpkg.TESTMOD + '3' only exists in zip1.
+        mod = importlib.import_module('.'.join((subpkg, TESTMOD + '3')))
+        self.assertEqual('path1.zip', mod.__file__.split(os.sep)[-4])
+
+    def testNamespacePackage(self):
+        # Test implicit namespace packages spread between multiple zip
+        # archives.
+        packdir = TESTPACK + os.sep
+        packdir2 = packdir + TESTPACK2 + os.sep
+        packdir3 = packdir2 + TESTPACK + '3' + os.sep
+        files1 = {packdir: (NOW, ""),
+                  packdir + TESTMOD + pyc_ext: (NOW, test_pyc),
+                  packdir2: (NOW, ""),
+                  packdir3: (NOW, ""),
+                  packdir3 + TESTMOD + pyc_ext: (NOW, test_pyc),
+                  packdir2 + TESTMOD + '3' + pyc_ext: (NOW, test_pyc),
+                  packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
+        zip1 = os.path.abspath("path1.zip")
+        self.makeZip(files1, zip1)
+
+        files2 = {packdir: (NOW, ""),
+                  packdir + TESTMOD + '2' + pyc_ext: (NOW, test_pyc),
+                  packdir2: (NOW, ""),
+                  packdir2 + TESTMOD + '2' + pyc_ext: (NOW, test_pyc),
+                  packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
+        zip2 = os.path.abspath("path2.zip")
+        self.makeZip(files2, zip2)
+
+        # zip2 should override zip1.
+        sys.path.insert(0, zip1)
+        sys.path.insert(0, zip2)
+
+        mod = importlib.import_module(TESTPACK)
+
+        # if TESTPACK is functioning as a namespace pkg then
+        # there should be two entries in the __path__.
+        # First should be path2 and second path1.
+        self.assertEqual(2, len(mod.__path__))
+        p1, p2 = mod.__path__
+        self.assertEqual("path2.zip", p1.split(os.sep)[-2])
+        self.assertEqual("path1.zip", p2.split(os.sep)[-2])
+
+        # packdir3 should import as a namespace package.
+        # Tts __path__ is an iterable of 1 element from zip1.
+        mod = importlib.import_module(packdir3.replace(os.sep, '.')[:-1])
+        self.assertEqual(1, len(mod.__path__))
+        mpath = list(mod.__path__)[0].split('path1.zip' + os.sep)[1]
+        self.assertEqual(packdir3[:-1], mpath)
+
+        # TESTPACK/TESTMOD only exists in path1.
+        mod = importlib.import_module('.'.join((TESTPACK, TESTMOD)))
+        self.assertEqual("path1.zip", mod.__file__.split(os.sep)[-3])
+
+        # And TESTPACK/(TESTMOD + '2') only exists in path2.
+        mod = importlib.import_module('.'.join((TESTPACK, TESTMOD + '2')))
+        self.assertEqual("path2.zip", mod.__file__.split(os.sep)[-3])
+
+        # One level deeper...
+        subpkg = '.'.join((TESTPACK, TESTPACK2))
+        mod = importlib.import_module(subpkg)
+        self.assertEqual(2, len(mod.__path__))
+        p1, p2 = mod.__path__
+        self.assertEqual("path2.zip", p1.split(os.sep)[-3])
+        self.assertEqual("path1.zip", p2.split(os.sep)[-3])
+
+        # subpkg.TESTMOD exists in both zips should load from zip2.
+        mod = importlib.import_module('.'.join((subpkg, TESTMOD)))
+        self.assertEqual('path2.zip', mod.__file__.split(os.sep)[-4])
+
+        # subpkg.TESTMOD + '2' only exists in zip2.
+        mod = importlib.import_module('.'.join((subpkg, TESTMOD + '2')))
+        self.assertEqual('path2.zip', mod.__file__.split(os.sep)[-4])
+
+        # Finally subpkg.TESTMOD + '3' only exists in zip1.
+        mod = importlib.import_module('.'.join((subpkg, TESTMOD + '3')))
+        self.assertEqual('path1.zip', mod.__file__.split(os.sep)[-4])
+
     def testZipImporterMethods(self):
         packdir = TESTPACK + os.sep
         packdir2 = packdir + TESTPACK2 + os.sep
@@ -231,7 +415,7 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
             mod = zi.load_module(TESTPACK)
             self.assertEqual(zi.get_filename(TESTPACK), mod.__file__)
 
-            existing_pack_path = __import__(TESTPACK).__path__[0]
+            existing_pack_path = importlib.import_module(TESTPACK).__path__[0]
             expected_path_path = os.path.join(TEMP_ZIP, TESTPACK)
             self.assertEqual(existing_pack_path, expected_path_path)
 
@@ -241,8 +425,8 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
 
             mod_path = packdir2 + TESTMOD
             mod_name = module_path_to_dotted_name(mod_path)
-            __import__(mod_name)
-            mod = sys.modules[mod_name]
+            mod = importlib.import_module(mod_name)
+            self.assertTrue(mod_name in sys.modules)
             self.assertEqual(zi.get_source(TESTPACK), None)
             self.assertEqual(zi.get_source(mod_path), None)
             self.assertEqual(zi.get_filename(mod_path), mod.__file__)
@@ -289,13 +473,13 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
 
             mod_path = TESTPACK2 + os.sep + TESTMOD
             mod_name = module_path_to_dotted_name(mod_path)
-            __import__(mod_name)
-            mod = sys.modules[mod_name]
+            mod = importlib.import_module(mod_name)
+            self.assertTrue(mod_name in sys.modules)
             self.assertEqual(zi.get_source(TESTPACK2), None)
             self.assertEqual(zi.get_source(mod_path), None)
             self.assertEqual(zi.get_filename(mod_path), mod.__file__)
             # To pass in the module name instead of the path, we must use the
-            # right importer
+            # right importer.
             loader = mod.__loader__
             self.assertEqual(loader.get_source(mod_name), None)
             self.assertEqual(loader.get_filename(mod_name), mod.__file__)
index 88c415b..78ecade 100644 (file)
@@ -47,16 +47,11 @@ class ChecksumTestCase(unittest.TestCase):
         self.assertEqual(zlib.adler32(b"", 1), 1)
         self.assertEqual(zlib.adler32(b"", 432), 432)
 
-    def assertEqual32(self, seen, expected):
-        # 32-bit values masked -- checksums on 32- vs 64- bit machines
-        # This is important if bit 31 (0x08000000L) is set.
-        self.assertEqual(seen & 0x0FFFFFFFF, expected & 0x0FFFFFFFF)
-
     def test_penguins(self):
-        self.assertEqual32(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
-        self.assertEqual32(zlib.crc32(b"penguin", 1), 0x43b6aa94)
-        self.assertEqual32(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
-        self.assertEqual32(zlib.adler32(b"penguin", 1), 0x0bd602f7)
+        self.assertEqual(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
+        self.assertEqual(zlib.crc32(b"penguin", 1), 0x43b6aa94)
+        self.assertEqual(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
+        self.assertEqual(zlib.adler32(b"penguin", 1), 0x0bd602f7)
 
         self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
         self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
@@ -176,7 +171,7 @@ class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
             self.assertEqual(zlib.decompress(ob), data)
 
     def test_incomplete_stream(self):
-        # An useful error message is given
+        # A useful error message is given
         x = zlib.compress(HAMLET_SCENE)
         self.assertRaisesRegex(zlib.error,
             "Error -5 while decompressing data: incomplete or truncated stream",
@@ -558,6 +553,15 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
                 self.assertEqual(dco.unconsumed_tail, b'')
                 self.assertEqual(dco.unused_data, remainder)
 
+    # issue27164
+    def test_decompress_raw_with_dictionary(self):
+        zdict = b'abcdefghijklmnopqrstuvwxyz'
+        co = zlib.compressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
+        comp = co.compress(zdict) + co.flush()
+        dco = zlib.decompressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
+        uncomp = dco.decompress(comp) + dco.flush()
+        self.assertEqual(zdict, uncomp)
+
     def test_flush_with_freed_input(self):
         # Issue #16411: decompressor accesses input to last decompress() call
         # in flush(), even if this object has been freed in the meanwhile.
@@ -685,6 +689,58 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
         finally:
             data = None
 
+    def test_wbits(self):
+        # wbits=0 only supported since zlib v1.2.3.5
+        # Register "1.2.3" as "1.2.3.0"
+        v = (zlib.ZLIB_RUNTIME_VERSION + ".0").split(".", 4)
+        supports_wbits_0 = int(v[0]) > 1 or int(v[0]) == 1 \
+            and (int(v[1]) > 2 or int(v[1]) == 2
+            and (int(v[2]) > 3 or int(v[2]) == 3 and int(v[3]) >= 5))
+
+        co = zlib.compressobj(level=1, wbits=15)
+        zlib15 = co.compress(HAMLET_SCENE) + co.flush()
+        self.assertEqual(zlib.decompress(zlib15, 15), HAMLET_SCENE)
+        if supports_wbits_0:
+            self.assertEqual(zlib.decompress(zlib15, 0), HAMLET_SCENE)
+        self.assertEqual(zlib.decompress(zlib15, 32 + 15), HAMLET_SCENE)
+        with self.assertRaisesRegex(zlib.error, 'invalid window size'):
+            zlib.decompress(zlib15, 14)
+        dco = zlib.decompressobj(wbits=32 + 15)
+        self.assertEqual(dco.decompress(zlib15), HAMLET_SCENE)
+        dco = zlib.decompressobj(wbits=14)
+        with self.assertRaisesRegex(zlib.error, 'invalid window size'):
+            dco.decompress(zlib15)
+
+        co = zlib.compressobj(level=1, wbits=9)
+        zlib9 = co.compress(HAMLET_SCENE) + co.flush()
+        self.assertEqual(zlib.decompress(zlib9, 9), HAMLET_SCENE)
+        self.assertEqual(zlib.decompress(zlib9, 15), HAMLET_SCENE)
+        if supports_wbits_0:
+            self.assertEqual(zlib.decompress(zlib9, 0), HAMLET_SCENE)
+        self.assertEqual(zlib.decompress(zlib9, 32 + 9), HAMLET_SCENE)
+        dco = zlib.decompressobj(wbits=32 + 9)
+        self.assertEqual(dco.decompress(zlib9), HAMLET_SCENE)
+
+        co = zlib.compressobj(level=1, wbits=-15)
+        deflate15 = co.compress(HAMLET_SCENE) + co.flush()
+        self.assertEqual(zlib.decompress(deflate15, -15), HAMLET_SCENE)
+        dco = zlib.decompressobj(wbits=-15)
+        self.assertEqual(dco.decompress(deflate15), HAMLET_SCENE)
+
+        co = zlib.compressobj(level=1, wbits=-9)
+        deflate9 = co.compress(HAMLET_SCENE) + co.flush()
+        self.assertEqual(zlib.decompress(deflate9, -9), HAMLET_SCENE)
+        self.assertEqual(zlib.decompress(deflate9, -15), HAMLET_SCENE)
+        dco = zlib.decompressobj(wbits=-9)
+        self.assertEqual(dco.decompress(deflate9), HAMLET_SCENE)
+
+        co = zlib.compressobj(level=1, wbits=16 + 15)
+        gzip = co.compress(HAMLET_SCENE) + co.flush()
+        self.assertEqual(zlib.decompress(gzip, 16 + 15), HAMLET_SCENE)
+        self.assertEqual(zlib.decompress(gzip, 32 + 15), HAMLET_SCENE)
+        dco = zlib.decompressobj(32 + 15)
+        self.assertEqual(dco.decompress(gzip), HAMLET_SCENE)
+
 
 def genblock(seed, length, step=1024, generator=random):
     """length-byte stream of random data from a seed (in step-byte blocks)."""
index 2f53718..dc7c5f0 100644 (file)
@@ -2,7 +2,7 @@
 # IMPORTANT: this file has the utf-8 BOM signature '\xef\xbb\xbf' 
 # at the start of it.  Make sure this is preserved if any changes
 # are made!  Also note that the coding cookie above conflicts with
-# the presense of a utf-8 BOM signature -- this is intended.
+# the presence of a utf-8 BOM signature -- this is intended.
 
 # Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
 x = 'ЉЊЈЁЂ'
diff --git a/Lib/test/wrongcert.pem b/Lib/test/wrongcert.pem
new file mode 100644 (file)
index 0000000..5f92f9b
--- /dev/null
@@ -0,0 +1,32 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQC89ZNxjTgWgq7Z1g0tJ65w+k7lNAj5IgjLb155UkUrz0XsHDnH
+FlbsVUg2Xtk6+bo2UEYIzN7cIm5ImpmyW/2z0J1IDVDlvR2xJ659xrE0v5c2cB6T
+f9lnNTwpSoeK24Nd7Jwq4j9vk95fLrdqsBq0/KVlsCXeixS/CaqqduXfvwIDAQAB
+AoGAQFko4uyCgzfxr4Ezb4Mp5pN3Npqny5+Jey3r8EjSAX9Ogn+CNYgoBcdtFgbq
+1yif/0sK7ohGBJU9FUCAwrqNBI9ZHB6rcy7dx+gULOmRBGckln1o5S1+smVdmOsW
+7zUVLBVByKuNWqTYFlzfVd6s4iiXtAE2iHn3GCyYdlICwrECQQDhMQVxHd3EFbzg
+SFmJBTARlZ2GKA3c1g/h9/XbkEPQ9/RwI3vnjJ2RaSnjlfoLl8TOcf0uOGbOEyFe
+19RvCLXjAkEA1s+UE5ziF+YVkW3WolDCQ2kQ5WG9+ccfNebfh6b67B7Ln5iG0Sbg
+ky9cjsO3jbMJQtlzAQnH1850oRD5Gi51dQJAIbHCDLDZU9Ok1TI+I2BhVuA6F666
+lEZ7TeZaJSYq34OaUYUdrwG9OdqwZ9sy9LUav4ESzu2lhEQchCJrKMn23QJAReqs
+ZLHUeTjfXkVk7dHhWPWSlUZ6AhmIlA/AQ7Payg2/8wM/JkZEJEPvGVykms9iPUrv
+frADRr+hAGe43IewnQJBAJWKZllPgKuEBPwoEldHNS8nRu61D7HzxEzQ2xnfj+Nk
+2fgf1MAzzTRsikfGENhVsVWeqOcijWb6g5gsyCmlRpc=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIICsDCCAhmgAwIBAgIJAOqYOYFJfEEoMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMDgwNjI2MTgxNTUyWhcNMDkwNjI2MTgxNTUyWjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQC89ZNxjTgWgq7Z1g0tJ65w+k7lNAj5IgjLb155UkUrz0XsHDnHFlbsVUg2Xtk6
++bo2UEYIzN7cIm5ImpmyW/2z0J1IDVDlvR2xJ659xrE0v5c2cB6Tf9lnNTwpSoeK
+24Nd7Jwq4j9vk95fLrdqsBq0/KVlsCXeixS/CaqqduXfvwIDAQABo4GnMIGkMB0G
+A1UdDgQWBBTctMtI3EO9OjLI0x9Zo2ifkwIiNjB1BgNVHSMEbjBsgBTctMtI3EO9
+OjLI0x9Zo2ifkwIiNqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
+U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAOqYOYFJ
+fEEoMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAQwa7jya/DfhaDn7E
+usPkpgIX8WCL2B1SqnRTXEZfBPPVq/cUmFGyEVRVATySRuMwi8PXbVcOhXXuocA+
+43W+iIsD9pXapCZhhOerCq18TC1dWK98vLUsoK8PMjB6e5H/O8bqojv0EeC+fyCw
+eSHj5jpC8iZKjCHBn+mAi4cQ514=
+-----END CERTIFICATE-----
index 828019d..c9f8cb6 100644 (file)
@@ -921,7 +921,7 @@ class Thread:
                 # self.
                 if _sys and _sys.stderr is not None:
                     print("Exception in thread %s:\n%s" %
-                          (self.name, _format_exc()), file=self._stderr)
+                          (self.name, _format_exc()), file=_sys.stderr)
                 elif self._stderr is not None:
                     # Do the best job possible w/o a huge amt. of code to
                     # approximate a traceback (code ideas from
@@ -1061,7 +1061,7 @@ class Thread:
         # Issue #18808: wait for the thread state to be gone.
         # At the end of the thread's life, after all knowledge of the thread
         # is removed from C data structures, C code releases our _tstate_lock.
-        # This method passes its arguments to _tstate_lock.aquire().
+        # This method passes its arguments to _tstate_lock.acquire().
         # If the lock is acquired, the C code is done, and self._stop() is
         # called.  That sets ._is_stopped to True, and ._tstate_lock to None.
         lock = self._tstate_lock
index 12085a9..aa646dc 100644 (file)
@@ -1249,7 +1249,7 @@ class Misc:
         nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args
         # Missing: (a, c, d, m, o, v, B, R)
         e = Event()
-        # serial field: valid vor all events
+        # serial field: valid for all events
         # number of button: ButtonPress and ButtonRelease events only
         # height field: Configure, ConfigureRequest, Create,
         # ResizeRequest, and Expose events only
@@ -1257,11 +1257,11 @@ class Misc:
         # time field: "valid for events that contain a time field"
         # width field: Configure, ConfigureRequest, Create, ResizeRequest,
         # and Expose events only
-        # x field: "valid for events that contain a x field"
+        # x field: "valid for events that contain an x field"
         # y field: "valid for events that contain a y field"
         # keysym as decimal: KeyPress and KeyRelease events only
         # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress,
-        # KeyRelease,and Motion events
+        # KeyRelease, and Motion events
         e.serial = getint(nsign)
         e.num = getint_event(b)
         try: e.focus = getboolean(f)
@@ -1337,8 +1337,9 @@ class Misc:
         self.configure({key: value})
     def keys(self):
         """Return a list of all resource names of this widget."""
-        return [x[0][1:] for x in
-                self.tk.splitlist(self.tk.call(self._w, 'configure'))]
+        splitlist = self.tk.splitlist
+        return [splitlist(x)[0][1:] for x in
+                splitlist(self.tk.call(self._w, 'configure'))]
     def __str__(self):
         """Return the window path name of this widget."""
         return self._w
@@ -2500,7 +2501,7 @@ class Checkbutton(Widget):
         self.tk.call(self._w, 'toggle')
 
 class Entry(Widget, XView):
-    """Entry widget which allows to display simple text."""
+    """Entry widget which allows displaying simple text."""
     def __init__(self, master=None, cnf={}, **kw):
         """Construct an entry widget with the parent MASTER.
 
@@ -2696,7 +2697,7 @@ class Listbox(Widget, XView, YView):
     itemconfig = itemconfigure
 
 class Menu(Widget):
-    """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
+    """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus."""
     def __init__(self, master=None, cnf={}, **kw):
         """Construct menu widget with the parent MASTER.
 
@@ -2771,7 +2772,7 @@ class Menu(Widget):
                     self.deletecommand(c)
         self.tk.call(self._w, 'delete', index1, index2)
     def entrycget(self, index, option):
-        """Return the resource value of an menu item for OPTION at INDEX."""
+        """Return the resource value of a menu item for OPTION at INDEX."""
         return self.tk.call(self._w, 'entrycget', index, '-' + option)
     def entryconfigure(self, index, cnf=None, **kw):
         """Configure a menu item at INDEX."""
@@ -3140,7 +3141,7 @@ class Text(Widget, XView, YView):
         """Creates a peer text widget with the given newPathName, and any
         optional standard configuration options. By default the peer will
         have the same start and end line as the parent widget, but
-        these can be overriden with the standard configuration options."""
+        these can be overridden with the standard configuration options."""
         self.tk.call(self._w, 'peer', 'create', newPathName,
             *self._options(cnf, kw))
     def peer_names(self): # new in Tk 8.5
@@ -3406,16 +3407,20 @@ class PhotoImage(Image):
         destImage = PhotoImage(master=self.tk)
         self.tk.call(destImage, 'copy', self.name)
         return destImage
-    def zoom(self,x,y=''):
+    def zoom(self, x, y=''):
         """Return a new PhotoImage with the same image as this widget
-        but zoom it with X and Y."""
+        but zoom it with a factor of x in the X direction and y in the Y
+        direction.  If y is not given, the default value is the same as x.
+        """
         destImage = PhotoImage(master=self.tk)
         if y=='': y=x
         self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
         return destImage
-    def subsample(self,x,y=''):
+    def subsample(self, x, y=''):
         """Return a new PhotoImage based on the same image as this widget
-        but use only every Xth or Yth pixel."""
+        but use only every Xth or Yth pixel.  If y is not given, the
+        default value is the same as x.
+        """
         destImage = PhotoImage(master=self.tk)
         if y=='': y=x
         self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
index 55f0776..e0971a2 100644 (file)
@@ -3,7 +3,7 @@
 This is very preliminary.  I currently only support dnd *within* one
 application, between different windows (or within the same window).
 
-I an trying to make this as generic as possible -- not dependent on
+I am trying to make this as generic as possible -- not dependent on
 the use of a particular widget or icon type, etc.  I also hope that
 this will work with Pmw.
 
index e42b1be..c645d43 100644 (file)
@@ -12,6 +12,8 @@ requires('gui')
 
 class PackTest(AbstractWidgetTest, unittest.TestCase):
 
+    test_keys = None
+
     def create2(self):
         pack = tkinter.Toplevel(self.root, name='pack')
         pack.wm_geometry('300x200+0+0')
@@ -276,6 +278,8 @@ class PackTest(AbstractWidgetTest, unittest.TestCase):
 
 class PlaceTest(AbstractWidgetTest, unittest.TestCase):
 
+    test_keys = None
+
     def create2(self):
         t = tkinter.Toplevel(self.root, width=300, height=200, bd=0)
         t.wm_geometry('300x200+0+0')
@@ -478,6 +482,8 @@ class PlaceTest(AbstractWidgetTest, unittest.TestCase):
 
 class GridTest(AbstractWidgetTest, unittest.TestCase):
 
+    test_keys = None
+
     def tearDown(self):
         cols, rows = self.root.grid_size()
         for i in range(cols + 1):
index 7171667..c924d55 100644 (file)
@@ -102,7 +102,7 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase):
         'background', 'borderwidth',
         'class', 'colormap', 'container', 'cursor', 'height',
         'highlightbackground', 'highlightcolor', 'highlightthickness',
-        'relief', 'takefocus', 'visual', 'width',
+        'padx', 'pady', 'relief', 'takefocus', 'visual', 'width',
     )
 
     def create(self, **kwargs):
@@ -636,7 +636,7 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase):
         'highlightbackground', 'highlightcolor', 'highlightthickness',
         'insertbackground', 'insertborderwidth',
         'insertofftime', 'insertontime', 'insertwidth',
-        'relief', 'scrollregion',
+        'offset', 'relief', 'scrollregion',
         'selectbackground', 'selectborderwidth', 'selectforeground',
         'state', 'takefocus',
         'xscrollcommand', 'xscrollincrement',
@@ -658,6 +658,15 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase):
         widget = self.create()
         self.checkBooleanParam(widget, 'confine')
 
+    def test_offset(self):
+        widget = self.create()
+        self.assertEqual(widget['offset'], '0,0')
+        self.checkParams(widget, 'offset',
+                'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
+        self.checkParam(widget, 'offset', '10,20')
+        self.checkParam(widget, 'offset', '#5,6')
+        self.checkInvalidParam(widget, 'offset', 'spam')
+
     def test_scrollregion(self):
         widget = self.create()
         self.checkParam(widget, 'scrollregion', '0 0 200 150')
index c9dcf97..c68a650 100644 (file)
@@ -193,7 +193,7 @@ class InternalFunctionsTest(unittest.TestCase):
 
         ## Testing type = vsapi
         # vsapi type expects at least a class name and a part_id, so this
-        # should raise an ValueError since it tries to get two elements from
+        # should raise a ValueError since it tries to get two elements from
         # an empty tuple
         self.assertRaises(ValueError, ttk._format_elemcreate, 'vsapi')
 
index afd3230..c031351 100644 (file)
@@ -187,7 +187,7 @@ class AbstractLabelTest(AbstractWidgetTest):
 @add_standard_options(StandardTtkOptionsTests)
 class LabelTest(AbstractLabelTest, unittest.TestCase):
     OPTIONS = (
-        'anchor', 'background',
+        'anchor', 'background', 'borderwidth',
         'class', 'compound', 'cursor', 'font', 'foreground',
         'image', 'justify', 'padding', 'relief', 'state', 'style',
         'takefocus', 'text', 'textvariable',
@@ -208,7 +208,8 @@ class LabelTest(AbstractLabelTest, unittest.TestCase):
 class ButtonTest(AbstractLabelTest, unittest.TestCase):
     OPTIONS = (
         'class', 'command', 'compound', 'cursor', 'default',
-        'image', 'state', 'style', 'takefocus', 'text', 'textvariable',
+        'image', 'padding', 'state', 'style',
+        'takefocus', 'text', 'textvariable',
         'underline', 'width',
     )
 
@@ -232,7 +233,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
         'class', 'command', 'compound', 'cursor',
         'image',
         'offvalue', 'onvalue',
-        'state', 'style',
+        'padding', 'state', 'style',
         'takefocus', 'text', 'textvariable',
         'underline', 'variable', 'width',
     )
@@ -276,137 +277,10 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
 
 
 @add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
-class ComboboxTest(AbstractWidgetTest, unittest.TestCase):
-    OPTIONS = (
-        'class', 'cursor', 'exportselection', 'height',
-        'justify', 'postcommand', 'state', 'style',
-        'takefocus', 'textvariable', 'values', 'width',
-    )
-
-    def setUp(self):
-        super().setUp()
-        self.combo = self.create()
-
-    def create(self, **kwargs):
-        return ttk.Combobox(self.root, **kwargs)
-
-    def test_height(self):
-        widget = self.create()
-        self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
-
-    def test_state(self):
-        widget = self.create()
-        self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
-
-    def _show_drop_down_listbox(self):
-        width = self.combo.winfo_width()
-        self.combo.event_generate('<ButtonPress-1>', x=width - 5, y=5)
-        self.combo.event_generate('<ButtonRelease-1>', x=width - 5, y=5)
-        self.combo.update_idletasks()
-
-
-    def test_virtual_event(self):
-        success = []
-
-        self.combo['values'] = [1]
-        self.combo.bind('<<ComboboxSelected>>',
-            lambda evt: success.append(True))
-        self.combo.pack()
-        self.combo.wait_visibility()
-
-        height = self.combo.winfo_height()
-        self._show_drop_down_listbox()
-        self.combo.update()
-        self.combo.event_generate('<Return>')
-        self.combo.update()
-
-        self.assertTrue(success)
-
-
-    def test_postcommand(self):
-        success = []
-
-        self.combo['postcommand'] = lambda: success.append(True)
-        self.combo.pack()
-        self.combo.wait_visibility()
-
-        self._show_drop_down_listbox()
-        self.assertTrue(success)
-
-        # testing postcommand removal
-        self.combo['postcommand'] = ''
-        self._show_drop_down_listbox()
-        self.assertEqual(len(success), 1)
-
-
-    def test_values(self):
-        def check_get_current(getval, currval):
-            self.assertEqual(self.combo.get(), getval)
-            self.assertEqual(self.combo.current(), currval)
-
-        self.assertEqual(self.combo['values'],
-                         () if tcl_version < (8, 5) else '')
-        check_get_current('', -1)
-
-        self.checkParam(self.combo, 'values', 'mon tue wed thur',
-                        expected=('mon', 'tue', 'wed', 'thur'))
-        self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur'))
-        self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string'))
-        self.checkParam(self.combo, 'values', '',
-                        expected='' if get_tk_patchlevel() < (8, 5, 10) else ())
-
-        self.combo['values'] = ['a', 1, 'c']
-
-        self.combo.set('c')
-        check_get_current('c', 2)
-
-        self.combo.current(0)
-        check_get_current('a', 0)
-
-        self.combo.set('d')
-        check_get_current('d', -1)
-
-        # testing values with empty string
-        self.combo.set('')
-        self.combo['values'] = (1, 2, '', 3)
-        check_get_current('', 2)
-
-        # testing values with empty string set through configure
-        self.combo.configure(values=[1, '', 2])
-        self.assertEqual(self.combo['values'],
-                         ('1', '', '2') if self.wantobjects else
-                         '1 {} 2')
-
-        # testing values with spaces
-        self.combo['values'] = ['a b', 'a\tb', 'a\nb']
-        self.assertEqual(self.combo['values'],
-                         ('a b', 'a\tb', 'a\nb') if self.wantobjects else
-                         '{a b} {a\tb} {a\nb}')
-
-        # testing values with special characters
-        self.combo['values'] = [r'a\tb', '"a"', '} {']
-        self.assertEqual(self.combo['values'],
-                         (r'a\tb', '"a"', '} {') if self.wantobjects else
-                         r'a\\tb {"a"} \}\ \{')
-
-        # out of range
-        self.assertRaises(tkinter.TclError, self.combo.current,
-            len(self.combo['values']))
-        # it expects an integer (or something that can be converted to int)
-        self.assertRaises(tkinter.TclError, self.combo.current, '')
-
-        # testing creating combobox with empty string in values
-        combo2 = ttk.Combobox(self.root, values=[1, 2, ''])
-        self.assertEqual(combo2['values'],
-                         ('1', '2', '') if self.wantobjects else '1 2 {}')
-        combo2.destroy()
-
-
-@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
 class EntryTest(AbstractWidgetTest, unittest.TestCase):
     OPTIONS = (
         'background', 'class', 'cursor',
-        'exportselection', 'font',
+        'exportselection', 'font', 'foreground',
         'invalidcommand', 'justify',
         'show', 'state', 'style', 'takefocus', 'textvariable',
         'validate', 'validatecommand', 'width', 'xscrollcommand',
@@ -535,6 +409,132 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
 
 
 @add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class ComboboxTest(EntryTest, unittest.TestCase):
+    OPTIONS = (
+        'background', 'class', 'cursor', 'exportselection',
+        'font', 'foreground', 'height', 'invalidcommand',
+        'justify', 'postcommand', 'show', 'state', 'style',
+        'takefocus', 'textvariable',
+        'validate', 'validatecommand', 'values',
+        'width', 'xscrollcommand',
+    )
+
+    def setUp(self):
+        super().setUp()
+        self.combo = self.create()
+
+    def create(self, **kwargs):
+        return ttk.Combobox(self.root, **kwargs)
+
+    def test_height(self):
+        widget = self.create()
+        self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
+
+    def _show_drop_down_listbox(self):
+        width = self.combo.winfo_width()
+        self.combo.event_generate('<ButtonPress-1>', x=width - 5, y=5)
+        self.combo.event_generate('<ButtonRelease-1>', x=width - 5, y=5)
+        self.combo.update_idletasks()
+
+
+    def test_virtual_event(self):
+        success = []
+
+        self.combo['values'] = [1]
+        self.combo.bind('<<ComboboxSelected>>',
+            lambda evt: success.append(True))
+        self.combo.pack()
+        self.combo.wait_visibility()
+
+        height = self.combo.winfo_height()
+        self._show_drop_down_listbox()
+        self.combo.update()
+        self.combo.event_generate('<Return>')
+        self.combo.update()
+
+        self.assertTrue(success)
+
+
+    def test_postcommand(self):
+        success = []
+
+        self.combo['postcommand'] = lambda: success.append(True)
+        self.combo.pack()
+        self.combo.wait_visibility()
+
+        self._show_drop_down_listbox()
+        self.assertTrue(success)
+
+        # testing postcommand removal
+        self.combo['postcommand'] = ''
+        self._show_drop_down_listbox()
+        self.assertEqual(len(success), 1)
+
+
+    def test_values(self):
+        def check_get_current(getval, currval):
+            self.assertEqual(self.combo.get(), getval)
+            self.assertEqual(self.combo.current(), currval)
+
+        self.assertEqual(self.combo['values'],
+                         () if tcl_version < (8, 5) else '')
+        check_get_current('', -1)
+
+        self.checkParam(self.combo, 'values', 'mon tue wed thur',
+                        expected=('mon', 'tue', 'wed', 'thur'))
+        self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur'))
+        self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string'))
+        self.checkParam(self.combo, 'values', '',
+                        expected='' if get_tk_patchlevel() < (8, 5, 10) else ())
+
+        self.combo['values'] = ['a', 1, 'c']
+
+        self.combo.set('c')
+        check_get_current('c', 2)
+
+        self.combo.current(0)
+        check_get_current('a', 0)
+
+        self.combo.set('d')
+        check_get_current('d', -1)
+
+        # testing values with empty string
+        self.combo.set('')
+        self.combo['values'] = (1, 2, '', 3)
+        check_get_current('', 2)
+
+        # testing values with empty string set through configure
+        self.combo.configure(values=[1, '', 2])
+        self.assertEqual(self.combo['values'],
+                         ('1', '', '2') if self.wantobjects else
+                         '1 {} 2')
+
+        # testing values with spaces
+        self.combo['values'] = ['a b', 'a\tb', 'a\nb']
+        self.assertEqual(self.combo['values'],
+                         ('a b', 'a\tb', 'a\nb') if self.wantobjects else
+                         '{a b} {a\tb} {a\nb}')
+
+        # testing values with special characters
+        self.combo['values'] = [r'a\tb', '"a"', '} {']
+        self.assertEqual(self.combo['values'],
+                         (r'a\tb', '"a"', '} {') if self.wantobjects else
+                         r'a\\tb {"a"} \}\ \{')
+
+        # out of range
+        self.assertRaises(tkinter.TclError, self.combo.current,
+            len(self.combo['values']))
+        # it expects an integer (or something that can be converted to int)
+        self.assertRaises(tkinter.TclError, self.combo.current, '')
+
+        # testing creating combobox with empty string in values
+        combo2 = ttk.Combobox(self.root, values=[1, 2, ''])
+        self.assertEqual(combo2['values'],
+                         ('1', '2', '') if self.wantobjects else '1 2 {}')
+        combo2.destroy()
+
+
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
 class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
     OPTIONS = (
         'class', 'cursor', 'height',
@@ -674,7 +674,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
     OPTIONS = (
         'class', 'command', 'compound', 'cursor',
         'image',
-        'state', 'style',
+        'padding', 'state', 'style',
         'takefocus', 'text', 'textvariable',
         'underline', 'value', 'variable', 'width',
     )
@@ -724,7 +724,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
 class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
     OPTIONS = (
         'class', 'compound', 'cursor', 'direction',
-        'image', 'menu', 'state', 'style',
+        'image', 'menu', 'padding', 'state', 'style',
         'takefocus', 'text', 'textvariable',
         'underline', 'width',
     )
@@ -902,7 +902,7 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
 @add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
 class NotebookTest(AbstractWidgetTest, unittest.TestCase):
     OPTIONS = (
-        'class', 'cursor', 'height', 'padding', 'style', 'takefocus',
+        'class', 'cursor', 'height', 'padding', 'style', 'takefocus', 'width',
     )
 
     def setUp(self):
index 779538d..75a068f 100644 (file)
@@ -206,6 +206,33 @@ class AbstractWidgetTest(AbstractTkTest):
                 break
 
 
+    def test_keys(self):
+        widget = self.create()
+        keys = widget.keys()
+        # XXX
+        if not isinstance(widget, Scale):
+            self.assertEqual(sorted(keys), sorted(widget.configure()))
+        for k in keys:
+            widget[k]
+        # Test if OPTIONS contains all keys
+        if test.support.verbose:
+            aliases = {
+                'bd': 'borderwidth',
+                'bg': 'background',
+                'fg': 'foreground',
+                'invcmd': 'invalidcommand',
+                'vcmd': 'validatecommand',
+            }
+            keys = set(keys)
+            expected = set(self.OPTIONS)
+            for k in sorted(keys - expected):
+                if not (k in aliases and
+                        aliases[k] in keys and
+                        aliases[k] in expected):
+                    print('%s.OPTIONS doesn\'t contain "%s"' %
+                          (self.__class__.__name__, k))
+
+
 class StandardOptionsTests:
     STANDARD_OPTIONS = (
         'activebackground', 'activeborderwidth', 'activeforeground', 'anchor',
index c1cdfa7..f667933 100644 (file)
@@ -221,7 +221,7 @@ class Tk(tkinter.Tk, tixCommand):
         self.tk.eval('package require Tix')
 
     def destroy(self):
-        # For safety, remove an delete_window binding before destroy
+        # For safety, remove the delete_window binding before destroy
         self.protocol("WM_DELETE_WINDOW", "")
         tkinter.Tk.destroy(self)
 
@@ -702,7 +702,7 @@ class DirSelectBox(TixWidget):
 
 class ExFileSelectBox(TixWidget):
     """ExFileSelectBox - MS Windows style file select box.
-    It provides an convenient method for the user to select files.
+    It provides a convenient method for the user to select files.
 
     Subwidget       Class
     ---------       -----
@@ -760,7 +760,7 @@ class DirSelectDialog(TixWidget):
 # Should inherit from a Dialog class
 class ExFileSelectDialog(TixWidget):
     """ExFileSelectDialog - MS Windows style file select dialog.
-    It provides an convenient method for the user to select files.
+    It provides a convenient method for the user to select files.
 
     Subwidgets       Class
     ----------       -----
@@ -1052,8 +1052,8 @@ class InputOnly(TixWidget):
 
 class LabelEntry(TixWidget):
     """LabelEntry - Entry field with label. Packages an entry widget
-    and a label into one mega widget. It can beused be used to simplify
-    the creation of ``entry-form'' type of interface.
+    and a label into one mega widget. It can be used to simplify the creation
+    of ``entry-form'' type of interface.
 
     Subwidgets       Class
     ----------       -----
index 244fb3d..8f9369b 100644 (file)
@@ -1012,7 +1012,7 @@ class Progressbar(Widget):
         """Begin autoincrement mode: schedules a recurring timer event
         that calls method step every interval milliseconds.
 
-        interval defaults to 50 milliseconds (20 steps/second) if ommited."""
+        interval defaults to 50 milliseconds (20 steps/second) if omitted."""
         self.tk.call(self._w, "start", interval)
 
 
@@ -1474,7 +1474,7 @@ class LabeledScale(Frame):
     can be accessed through instance.label"""
 
     def __init__(self, master=None, variable=None, from_=0, to=10, **kw):
-        """Construct an horizontal LabeledScale with parent master, a
+        """Construct a horizontal LabeledScale with parent master, a
         variable to be associated with the Ttk Scale widget and its range.
         If variable is not specified, a tkinter.IntVar is created.
 
index 65d06e5..b1d0c83 100644 (file)
@@ -33,7 +33,7 @@ import re
 import sys
 from token import *
 
-cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII)
+cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII)
 blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII)
 
 import token
@@ -328,8 +328,8 @@ def untokenize(iterable):
     Round-trip invariant for full input:
         Untokenized source will match input source exactly
 
-    Round-trip invariant for limited intput:
-        # Output bytes will tokenize the back to the input
+    Round-trip invariant for limited input:
+        # Output bytes will tokenize back to the input
         t1 = [tok[:2] for tok in tokenize(f.readline)]
         newcode = untokenize(t1)
         readline = BytesIO(newcode).readline
@@ -465,10 +465,10 @@ def open(filename):
 
 def tokenize(readline):
     """
-    The tokenize() generator requires one argment, readline, which
+    The tokenize() generator requires one argument, readline, which
     must be a callable object which provides the same interface as the
     readline() method of built-in file objects.  Each call to the function
-    should return one line of input as bytes.  Alternately, readline
+    should return one line of input as bytes.  Alternatively, readline
     can be a callable function terminating with StopIteration:
         readline = open(myfile, 'rb').__next__  # Example of alternate readline
 
index 9b69da0..a2eb539 100644 (file)
@@ -136,7 +136,7 @@ def format_exception_only(etype, value):
     return list(TracebackException(etype, value, None).format_exception_only())
 
 
-# -- not offical API but folk probably use these two functions.
+# -- not official API but folk probably use these two functions.
 
 def _format_final_exc_line(etype, value):
     valuestr = _some_str(value)
@@ -418,13 +418,13 @@ class TracebackException:
     - :attr:`stack` A `StackSummary` representing the traceback.
     - :attr:`exc_type` The class of the original traceback.
     - :attr:`filename` For syntax errors - the filename where the error
-      occured.
+      occurred.
     - :attr:`lineno` For syntax errors - the linenumber where the error
-      occured.
+      occurred.
     - :attr:`text` For syntax errors - the text where the error
-      occured.
+      occurred.
     - :attr:`offset` For syntax errors - the offset into the text where the
-      error occured.
+      error occurred.
     - :attr:`msg` For syntax errors - the compiler error message.
     """
 
index 106d058..711d0ab 100644 (file)
@@ -89,8 +89,8 @@ import sys
 import os
 
 from tkinter import *
+from idlelib.ColorDelegator import ColorDelegator, color_config
 from idlelib.Percolator import Percolator
-from idlelib.ColorDelegator import ColorDelegator
 from idlelib.textView import view_text
 from turtledemo import __doc__ as about_turtledemo
 
@@ -124,6 +124,8 @@ help_entries = (  # (help_label,  help_doc)
     ('About turtle module', turtle.__doc__),
     )
 
+
+
 class DemoWindow(object):
 
     def __init__(self, filename=None):
@@ -204,6 +206,7 @@ class DemoWindow(object):
         self.text_frame = text_frame = Frame(root)
         self.text = text = Text(text_frame, name='text', padx=5,
                                 wrap='none', width=45)
+        color_config(text)
 
         self.vbar = vbar = Scrollbar(text_frame, name='vbar')
         vbar['command'] = text.yview
index 1757f13..4cac66c 100644 (file)
@@ -1,10 +1,7 @@
-# TODO nits:
-# Get rid of asserts that are the caller's fault.
-# Docstrings (e.g. ABCs).
-
 import abc
 from abc import abstractmethod, abstractproperty
 import collections
+import contextlib
 import functools
 import re as stdlib_re  # Avoid confusion with the re we export.
 import sys
@@ -22,12 +19,16 @@ __all__ = [
     'Callable',
     'Generic',
     'Optional',
+    'Tuple',
+    'Type',
     'TypeVar',
     'Union',
-    'Tuple',
 
     # ABCs (from collections.abc).
     'AbstractSet',  # collections.abc.Set.
+    'Awaitable',
+    'AsyncIterator',
+    'AsyncIterable',
     'ByteString',
     'Container',
     'Hashable',
@@ -53,6 +54,7 @@ __all__ = [
 
     # Concrete collection types.
     'Dict',
+    'DefaultDict',
     'List',
     'Set',
     'NamedTuple',  # Not really a type.
@@ -62,15 +64,18 @@ __all__ = [
     'AnyStr',
     'cast',
     'get_type_hints',
+    'NewType',
     'no_type_check',
     'no_type_check_decorator',
     'overload',
-
-    # Submodules.
-    'io',
-    're',
+    'Text',
+    'TYPE_CHECKING',
 ]
 
+# The pseudo-submodules 're' and 'io' are part of the public
+# namespace, but excluded from __all__ because they might stomp on
+# legitimate imports of those modules.
+
 
 def _qualname(x):
     if sys.version_info[:2] >= (3, 3):
@@ -114,8 +119,8 @@ class TypingMeta(type):
         """
         return self
 
-    def _has_type_var(self):
-        return False
+    def _get_type_vars(self, tvars):
+        pass
 
     def __repr__(self):
         return '%s.%s' % (self.__module__, _qualname(self))
@@ -211,8 +216,8 @@ class _TypeAlias:
         someone tries to subclass a type alias (not a good idea).
         """
         if (len(args) == 3 and
-            isinstance(args[0], str) and
-            isinstance(args[1], tuple)):
+                isinstance(args[0], str) and
+                isinstance(args[1], tuple)):
             # Close enough.
             raise TypeError("A type alias cannot be subclassed")
         return object.__new__(cls)
@@ -268,8 +273,16 @@ class _TypeAlias:
             return issubclass(cls, self.impl_type)
 
 
-def _has_type_var(t):
-    return t is not None and isinstance(t, TypingMeta) and t._has_type_var()
+def _get_type_vars(types, tvars):
+    for t in types:
+        if isinstance(t, TypingMeta):
+            t._get_type_vars(tvars)
+
+
+def _type_vars(types):
+    tvars = []
+    _get_type_vars(types, tvars)
+    return tuple(tvars)
 
 
 def _eval_type(t, globalns, localns):
@@ -295,7 +308,7 @@ def _type_check(arg, msg):
         return type(None)
     if isinstance(arg, str):
         arg = _ForwardRef(arg)
-    if not isinstance(arg, (type, _TypeAlias)):
+    if not isinstance(arg, (type, _TypeAlias)) and not callable(arg):
         raise TypeError(msg + " Got %.100r." % (arg,))
     return arg
 
@@ -373,7 +386,7 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True):
     At runtime, isinstance(x, T) will raise TypeError.  However,
     issubclass(C, T) is true for any class C, and issubclass(str, A)
     and issubclass(bytes, A) are true, and issubclass(int, A) is
-    false.
+    false.  (TODO: Why is this needed?  This may change.  See #136.)
 
     Type variables may be marked covariant or contravariant by passing
     covariant=True or contravariant=True.  See PEP 484 for more
@@ -407,8 +420,9 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True):
             self.__bound__ = None
         return self
 
-    def _has_type_var(self):
-        return True
+    def _get_type_vars(self, tvars):
+        if self not in tvars:
+            tvars.append(self)
 
     def __repr__(self):
         if self.__covariant__:
@@ -436,6 +450,7 @@ class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True):
 
 
 # Some unconstrained type variables.  These are used by the container types.
+# (These are not for export.)
 T = TypeVar('T')  # Any type.
 KT = TypeVar('KT')  # Key type.
 VT = TypeVar('VT')  # Value type.
@@ -445,7 +460,7 @@ VT_co = TypeVar('VT_co', covariant=True)  # Value type covariant containers.
 T_contra = TypeVar('T_contra', contravariant=True)  # Ditto contravariant.
 
 # A useful type variable with constraints.  This represents string types.
-# TODO: What about bytearray, memoryview?
+# (This one *is* for export!)
 AnyStr = TypeVar('AnyStr', bytes, str)
 
 
@@ -490,7 +505,10 @@ class UnionMeta(TypingMeta):
             if isinstance(t1, _TypeAlias):
                 # _TypeAlias is not a real class.
                 continue
-            if any(issubclass(t1, t2)
+            if not isinstance(t1, type):
+                assert callable(t1)  # A callable might sneak through.
+                continue
+            if any(isinstance(t2, type) and issubclass(t1, t2)
                    for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
                 all_params.remove(t1)
         # It's not a union if there's only one type left.
@@ -511,12 +529,9 @@ class UnionMeta(TypingMeta):
             return self.__class__(self.__name__, self.__bases__, {},
                                   p, _root=True)
 
-    def _has_type_var(self):
+    def _get_type_vars(self, tvars):
         if self.__union_params__:
-            for t in self.__union_params__:
-                if _has_type_var(t):
-                    return True
-        return False
+            _get_type_vars(self.__union_params__, tvars)
 
     def __repr__(self):
         r = super().__repr__()
@@ -653,12 +668,9 @@ class TupleMeta(TypingMeta):
         self.__tuple_use_ellipsis__ = use_ellipsis
         return self
 
-    def _has_type_var(self):
+    def _get_type_vars(self, tvars):
         if self.__tuple_params__:
-            for t in self.__tuple_params__:
-                if _has_type_var(t):
-                    return True
-        return False
+            _get_type_vars(self.__tuple_params__, tvars)
 
     def _eval_type(self, globalns, localns):
         tp = self.__tuple_params__
@@ -677,6 +689,8 @@ class TupleMeta(TypingMeta):
             params = [_type_repr(p) for p in self.__tuple_params__]
             if self.__tuple_use_ellipsis__:
                 params.append('...')
+            if not params:
+                params.append('()')
             r += '[%s]' % (
                 ', '.join(params))
         return r
@@ -701,7 +715,8 @@ class TupleMeta(TypingMeta):
     def __eq__(self, other):
         if not isinstance(other, TupleMeta):
             return NotImplemented
-        return self.__tuple_params__ == other.__tuple_params__
+        return (self.__tuple_params__ == other.__tuple_params__ and
+                self.__tuple_use_ellipsis__ == other.__tuple_use_ellipsis__)
 
     def __hash__(self):
         return hash(self.__tuple_params__)
@@ -766,12 +781,9 @@ class CallableMeta(TypingMeta):
         self.__result__ = result
         return self
 
-    def _has_type_var(self):
+    def _get_type_vars(self, tvars):
         if self.__args__:
-            for t in self.__args__:
-                if _has_type_var(t):
-                    return True
-        return _has_type_var(self.__result__)
+            _get_type_vars(self.__args__, tvars)
 
     def _eval_type(self, globalns, localns):
         if self.__args__ is None and self.__result__ is None:
@@ -875,76 +887,101 @@ def _geqv(a, b):
     return _gorg(a) is _gorg(b)
 
 
-class GenericMeta(TypingMeta, abc.ABCMeta):
-    """Metaclass for generic types."""
+def _next_in_mro(cls):
+    """Helper for Generic.__new__.
 
-    # TODO: Constrain more how Generic is used; only a few
-    # standard patterns should be allowed.
+    Returns the class after the last occurrence of Generic or
+    Generic[...] in cls.__mro__.
+    """
+    next_in_mro = object
+    # Look for the last occurrence of Generic or Generic[...].
+    for i, c in enumerate(cls.__mro__[:-1]):
+        if isinstance(c, GenericMeta) and _gorg(c) is Generic:
+            next_in_mro = cls.__mro__[i+1]
+    return next_in_mro
 
-    # TODO: Use a more precise rule than matching __name__ to decide
-    # whether two classes are the same.  Also, save the formal
-    # parameters.  (These things are related!  A solution lies in
-    # using origin.)
 
-    __extra__ = None
+class GenericMeta(TypingMeta, abc.ABCMeta):
+    """Metaclass for generic types."""
 
     def __new__(cls, name, bases, namespace,
-                parameters=None, origin=None, extra=None):
-        if parameters is None:
-            # Extract parameters from direct base classes.  Only
-            # direct bases are considered and only those that are
-            # themselves generic, and parameterized with type
-            # variables.  Don't use bases like Any, Union, Tuple,
-            # Callable or type variables.
-            params = None
+                tvars=None, args=None, origin=None, extra=None):
+        self = super().__new__(cls, name, bases, namespace, _root=True)
+
+        if tvars is not None:
+            # Called from __getitem__() below.
+            assert origin is not None
+            assert all(isinstance(t, TypeVar) for t in tvars), tvars
+        else:
+            # Called from class statement.
+            assert tvars is None, tvars
+            assert args is None, args
+            assert origin is None, origin
+
+            # Get the full set of tvars from the bases.
+            tvars = _type_vars(bases)
+            # Look for Generic[T1, ..., Tn].
+            # If found, tvars must be a subset of it.
+            # If not found, tvars is it.
+            # Also check for and reject plain Generic,
+            # and reject multiple Generic[...].
+            gvars = None
             for base in bases:
-                if isinstance(base, TypingMeta):
-                    if not isinstance(base, GenericMeta):
+                if base is Generic:
+                    raise TypeError("Cannot inherit from plain Generic")
+                if (isinstance(base, GenericMeta) and
+                        base.__origin__ is Generic):
+                    if gvars is not None:
                         raise TypeError(
-                            "You cannot inherit from magic class %s" %
-                            repr(base))
-                    if base.__parameters__ is None:
-                        continue  # The base is unparameterized.
-                    for bp in base.__parameters__:
-                        if _has_type_var(bp) and not isinstance(bp, TypeVar):
-                            raise TypeError(
-                                "Cannot inherit from a generic class "
-                                "parameterized with "
-                                "non-type-variable %s" % bp)
-                        if params is None:
-                            params = []
-                        if bp not in params:
-                            params.append(bp)
-            if params is not None:
-                parameters = tuple(params)
-        self = super().__new__(cls, name, bases, namespace, _root=True)
-        self.__parameters__ = parameters
-        if extra is not None:
-            self.__extra__ = extra
-        # Else __extra__ is inherited, eventually from the
-        # (meta-)class default above.
+                            "Cannot inherit from Generic[...] multiple types.")
+                    gvars = base.__parameters__
+            if gvars is None:
+                gvars = tvars
+            else:
+                tvarset = set(tvars)
+                gvarset = set(gvars)
+                if not tvarset <= gvarset:
+                    raise TypeError(
+                        "Some type variables (%s) "
+                        "are not listed in Generic[%s]" %
+                        (", ".join(str(t) for t in tvars if t not in gvarset),
+                         ", ".join(str(g) for g in gvars)))
+                tvars = gvars
+
+        self.__parameters__ = tvars
+        self.__args__ = args
         self.__origin__ = origin
+        self.__extra__ = extra
+        # Speed hack (https://github.com/python/typing/issues/196).
+        self.__next_in_mro__ = _next_in_mro(self)
         return self
 
-    def _has_type_var(self):
-        if self.__parameters__:
-            for t in self.__parameters__:
-                if _has_type_var(t):
-                    return True
-        return False
+    def _get_type_vars(self, tvars):
+        if self.__origin__ and self.__parameters__:
+            _get_type_vars(self.__parameters__, tvars)
 
     def __repr__(self):
-        r = super().__repr__()
-        if self.__parameters__ is not None:
+        if self.__origin__ is not None:
+            r = repr(self.__origin__)
+        else:
+            r = super().__repr__()
+        if self.__args__:
             r += '[%s]' % (
+                ', '.join(_type_repr(p) for p in self.__args__))
+        if self.__parameters__:
+            r += '<%s>' % (
                 ', '.join(_type_repr(p) for p in self.__parameters__))
         return r
 
     def __eq__(self, other):
         if not isinstance(other, GenericMeta):
             return NotImplemented
-        return (_geqv(self, other) and
-                self.__parameters__ == other.__parameters__)
+        if self.__origin__ is not None:
+            return (self.__origin__ is other.__origin__ and
+                    self.__args__ == other.__args__ and
+                    self.__parameters__ == other.__parameters__)
+        else:
+            return self is other
 
     def __hash__(self):
         return hash((self.__name__, self.__parameters__))
@@ -953,37 +990,45 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
         if not isinstance(params, tuple):
             params = (params,)
         if not params:
-            raise TypeError("Cannot have empty parameter list")
+            raise TypeError(
+                "Parameter list to %s[...] cannot be empty" % _qualname(self))
         msg = "Parameters to generic types must be types."
         params = tuple(_type_check(p, msg) for p in params)
-        if self.__parameters__ is None:
-            for p in params:
-                if not isinstance(p, TypeVar):
-                    raise TypeError("Initial parameters must be "
-                                    "type variables; got %s" % p)
+        if self is Generic:
+            # Generic can only be subscripted with unique type variables.
+            if not all(isinstance(p, TypeVar) for p in params):
+                raise TypeError(
+                    "Parameters to Generic[...] must all be type variables")
             if len(set(params)) != len(params):
                 raise TypeError(
-                    "All type variables in Generic[...] must be distinct.")
+                    "Parameters to Generic[...] must all be unique")
+            tvars = params
+            args = None
+        elif self is _Protocol:
+            # _Protocol is internal, don't check anything.
+            tvars = params
+            args = None
+        elif self.__origin__ in (Generic, _Protocol):
+            # Can't subscript Generic[...] or _Protocol[...].
+            raise TypeError("Cannot subscript already-subscripted %s" %
+                            repr(self))
         else:
-            if len(params) != len(self.__parameters__):
-                raise TypeError("Cannot change parameter count from %d to %d" %
-                                (len(self.__parameters__), len(params)))
-            for new, old in zip(params, self.__parameters__):
-                if isinstance(old, TypeVar):
-                    if not old.__constraints__:
-                        # Substituting for an unconstrained TypeVar is OK.
-                        continue
-                    if issubclass(new, Union[old.__constraints__]):
-                        # Specializing a constrained type variable is OK.
-                        continue
-                if not issubclass(new, old):
-                    raise TypeError(
-                        "Cannot substitute %s for %s in %s" %
-                        (_type_repr(new), _type_repr(old), self))
-
-        return self.__class__(self.__name__, (self,) + self.__bases__,
+            # Subscripting a regular Generic subclass.
+            if not self.__parameters__:
+                raise TypeError("%s is not a generic class" % repr(self))
+            alen = len(params)
+            elen = len(self.__parameters__)
+            if alen != elen:
+                raise TypeError(
+                    "Too %s parameters for %s; actual %s, expected %s" %
+                    ("many" if alen > elen else "few", repr(self), alen, elen))
+            tvars = _type_vars(params)
+            args = params
+        return self.__class__(self.__name__,
+                              (self,) + self.__bases__,
                               dict(self.__dict__),
-                              parameters=params,
+                              tvars=tvars,
+                              args=args,
                               origin=self,
                               extra=self.__extra__)
 
@@ -1003,10 +1048,10 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
             # C[X] is a subclass of C[Y] iff X is a subclass of Y.
             origin = self.__origin__
             if origin is not None and origin is cls.__origin__:
-                assert len(self.__parameters__) == len(origin.__parameters__)
-                assert len(cls.__parameters__) == len(origin.__parameters__)
-                for p_self, p_cls, p_origin in zip(self.__parameters__,
-                                                   cls.__parameters__,
+                assert len(self.__args__) == len(origin.__parameters__)
+                assert len(cls.__args__) == len(origin.__parameters__)
+                for p_self, p_cls, p_origin in zip(self.__args__,
+                                                   cls.__args__,
                                                    origin.__parameters__):
                     if isinstance(p_origin, TypeVar):
                         if p_origin.__covariant__:
@@ -1036,6 +1081,10 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
         return issubclass(cls, self.__extra__)
 
 
+# Prevent checks for Generic to crash when defining Generic.
+Generic = None
+
+
 class Generic(metaclass=GenericMeta):
     """Abstract base class for generic types.
 
@@ -1050,29 +1099,23 @@ class Generic(metaclass=GenericMeta):
 
     This class can then be used as follows::
 
-      def lookup_name(mapping: Mapping, key: KT, default: VT) -> VT:
+      def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
           try:
               return mapping[key]
           except KeyError:
               return default
-
-    For clarity the type variables may be redefined, e.g.::
-
-      X = TypeVar('X')
-      Y = TypeVar('Y')
-      def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y:
-          # Same body as above.
     """
 
     __slots__ = ()
 
     def __new__(cls, *args, **kwds):
-        next_in_mro = object
-        # Look for the last occurrence of Generic or Generic[...].
-        for i, c in enumerate(cls.__mro__[:-1]):
-            if isinstance(c, GenericMeta) and _gorg(c) is Generic:
-                next_in_mro = cls.__mro__[i+1]
-        return next_in_mro.__new__(_gorg(cls))
+        if cls.__origin__ is None:
+            return cls.__next_in_mro__.__new__(cls)
+        else:
+            origin = _gorg(cls)
+            obj = cls.__next_in_mro__.__new__(origin)
+            obj.__init__(*args, **kwds)
+            return obj
 
 
 def cast(typ, val):
@@ -1090,9 +1133,7 @@ def _get_defaults(func):
     """Internal helper to extract the default arguments, by name."""
     code = func.__code__
     pos_count = code.co_argcount
-    kw_count = code.co_kwonlyargcount
     arg_names = code.co_varnames
-    kwarg_names = arg_names[pos_count:pos_count + kw_count]
     arg_names = arg_names[:pos_count]
     defaults = func.__defaults__ or ()
     kwdefaults = func.__kwdefaults__
@@ -1145,7 +1186,6 @@ def get_type_hints(obj, globalns=None, localns=None):
     return hints
 
 
-# TODO: Also support this as a class decorator.
 def no_type_check(arg):
     """Decorator to indicate that annotations are not type hints.
 
@@ -1180,8 +1220,42 @@ def no_type_check_decorator(decorator):
     return wrapped_decorator
 
 
+def _overload_dummy(*args, **kwds):
+    """Helper for @overload to raise when called."""
+    raise NotImplementedError(
+        "You should not call an overloaded function. "
+        "A series of @overload-decorated functions "
+        "outside a stub module should always be followed "
+        "by an implementation that is not @overload-ed.")
+
+
 def overload(func):
-    raise RuntimeError("Overloading is only supported in library stubs")
+    """Decorator for overloaded functions/methods.
+
+    In a stub file, place two or more stub definitions for the same
+    function in a row, each decorated with @overload.  For example:
+
+      @overload
+      def utf8(value: None) -> None: ...
+      @overload
+      def utf8(value: bytes) -> bytes: ...
+      @overload
+      def utf8(value: str) -> bytes: ...
+
+    In a non-stub file (i.e. a regular .py file), do the same but
+    follow it with an implementation.  The implementation should *not*
+    be decorated with @overload.  For example:
+
+      @overload
+      def utf8(value: None) -> None: ...
+      @overload
+      def utf8(value: bytes) -> bytes: ...
+      @overload
+      def utf8(value: str) -> bytes: ...
+      def utf8(value):
+          # implementation goes here
+    """
+    return _overload_dummy
 
 
 class _ProtocolMeta(GenericMeta):
@@ -1229,14 +1303,17 @@ class _ProtocolMeta(GenericMeta):
                         break
                 else:
                     if (not attr.startswith('_abc_') and
-                        attr != '__abstractmethods__' and
-                        attr != '_is_protocol' and
-                        attr != '__dict__' and
-                        attr != '__slots__' and
-                        attr != '_get_protocol_attrs' and
-                        attr != '__parameters__' and
-                        attr != '__origin__' and
-                        attr != '__module__'):
+                            attr != '__abstractmethods__' and
+                            attr != '_is_protocol' and
+                            attr != '__dict__' and
+                            attr != '__args__' and
+                            attr != '__slots__' and
+                            attr != '_get_protocol_attrs' and
+                            attr != '__next_in_mro__' and
+                            attr != '__parameters__' and
+                            attr != '__origin__' and
+                            attr != '__extra__' and
+                            attr != '__module__'):
                         attrs.add(attr)
 
         return attrs
@@ -1261,6 +1338,27 @@ class _Protocol(metaclass=_ProtocolMeta):
 Hashable = collections_abc.Hashable  # Not generic.
 
 
+if hasattr(collections_abc, 'Awaitable'):
+    class Awaitable(Generic[T_co], extra=collections_abc.Awaitable):
+        __slots__ = ()
+else:
+    Awaitable = None
+
+
+if hasattr(collections_abc, 'AsyncIterable'):
+
+    class AsyncIterable(Generic[T_co], extra=collections_abc.AsyncIterable):
+        __slots__ = ()
+
+    class AsyncIterator(AsyncIterable[T_co],
+                        extra=collections_abc.AsyncIterator):
+        __slots__ = ()
+
+else:
+    AsyncIterable = None
+    AsyncIterator = None
+
+
 class Iterable(Generic[T_co], extra=collections_abc.Iterable):
     __slots__ = ()
 
@@ -1317,12 +1415,16 @@ class SupportsRound(_Protocol[T_co]):
         pass
 
 
-class Reversible(_Protocol[T_co]):
-    __slots__ = ()
+if hasattr(collections_abc, 'Reversible'):
+    class Reversible(Iterable[T_co], extra=collections_abc.Reversible):
+        __slots__ = ()
+else:
+    class Reversible(_Protocol[T_co]):
+        __slots__ = ()
 
-    @abstractmethod
-    def __reversed__(self) -> 'Iterator[T_co]':
-        pass
+        @abstractmethod
+        def __reversed__(self) -> 'Iterator[T_co]':
+            pass
 
 
 Sized = collections_abc.Sized  # Not generic.
@@ -1345,7 +1447,7 @@ class MutableSet(AbstractSet[T], extra=collections_abc.MutableSet):
 
 
 # NOTE: Only the value type is covariant.
-class Mapping(Sized, Iterable[KT], Container[KT], Generic[VT_co],
+class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co],
               extra=collections_abc.Mapping):
     pass
 
@@ -1353,10 +1455,14 @@ class Mapping(Sized, Iterable[KT], Container[KT], Generic[VT_co],
 class MutableMapping(Mapping[KT, VT], extra=collections_abc.MutableMapping):
     pass
 
-
-class Sequence(Sized, Iterable[T_co], Container[T_co],
+if hasattr(collections_abc, 'Reversible'):
+    class Sequence(Sized, Reversible[T_co], Container[T_co],
                extra=collections_abc.Sequence):
-    pass
+        pass
+else:
+    class Sequence(Sized, Iterable[T_co], Container[T_co],
+                   extra=collections_abc.Sequence):
+        pass
 
 
 class MutableSequence(Sequence[T], extra=collections_abc.MutableSequence):
@@ -1370,7 +1476,7 @@ class ByteString(Sequence[int], extra=collections_abc.ByteString):
 ByteString.register(type(memoryview(b'')))
 
 
-class List(list, MutableSequence[T]):
+class List(list, MutableSequence[T], extra=list):
 
     def __new__(cls, *args, **kwds):
         if _geqv(cls, List):
@@ -1379,7 +1485,7 @@ class List(list, MutableSequence[T]):
         return list.__new__(cls, *args, **kwds)
 
 
-class Set(set, MutableSet[T]):
+class Set(set, MutableSet[T], extra=set):
 
     def __new__(cls, *args, **kwds):
         if _geqv(cls, Set):
@@ -1402,7 +1508,8 @@ class _FrozenSetMeta(GenericMeta):
         return super().__subclasscheck__(cls)
 
 
-class FrozenSet(frozenset, AbstractSet[T_co], metaclass=_FrozenSetMeta):
+class FrozenSet(frozenset, AbstractSet[T_co], metaclass=_FrozenSetMeta,
+                extra=frozenset):
     __slots__ = ()
 
     def __new__(cls, *args, **kwds):
@@ -1421,8 +1528,9 @@ class KeysView(MappingView[KT], AbstractSet[KT],
     pass
 
 
-# TODO: Enable Set[Tuple[KT, VT_co]] instead of Generic[KT, VT_co].
-class ItemsView(MappingView, Generic[KT, VT_co],
+class ItemsView(MappingView[Tuple[KT, VT_co]],
+                AbstractSet[Tuple[KT, VT_co]],
+                Generic[KT, VT_co],
                 extra=collections_abc.ItemsView):
     pass
 
@@ -1431,7 +1539,13 @@ class ValuesView(MappingView[VT_co], extra=collections_abc.ValuesView):
     pass
 
 
-class Dict(dict, MutableMapping[KT, VT]):
+if hasattr(contextlib, 'AbstractContextManager'):
+    class ContextManager(Generic[T_co], extra=contextlib.AbstractContextManager):
+        __slots__ = ()
+    __all__.append('ContextManager')
+
+
+class Dict(dict, MutableMapping[KT, VT], extra=dict):
 
     def __new__(cls, *args, **kwds):
         if _geqv(cls, Dict):
@@ -1439,6 +1553,14 @@ class Dict(dict, MutableMapping[KT, VT]):
                             "use dict() instead")
         return dict.__new__(cls, *args, **kwds)
 
+class DefaultDict(collections.defaultdict, MutableMapping[KT, VT],
+                  extra=collections.defaultdict):
+
+    def __new__(cls, *args, **kwds):
+        if _geqv(cls, DefaultDict):
+            raise TypeError("Type DefaultDict cannot be instantiated; "
+                            "use collections.defaultdict() instead")
+        return collections.defaultdict.__new__(cls, *args, **kwds)
 
 # Determine what base class to use for Generator.
 if hasattr(collections_abc, 'Generator'):
@@ -1460,6 +1582,36 @@ class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co],
         return super().__new__(cls, *args, **kwds)
 
 
+# Internal type variable used for Type[].
+CT = TypeVar('CT', covariant=True, bound=type)
+
+
+# This is not a real generic class.  Don't use outside annotations.
+class Type(type, Generic[CT], extra=type):
+    """A special construct usable to annotate class objects.
+
+    For example, suppose we have the following classes::
+
+      class User: ...  # Abstract base for User classes
+      class BasicUser(User): ...
+      class ProUser(User): ...
+      class TeamUser(User): ...
+
+    And a function that takes a class argument that's a subclass of
+    User and returns an instance of the corresponding class::
+
+      U = TypeVar('U', bound=User)
+      def new_user(user_class: Type[U]) -> U:
+          user = user_class()
+          # (Here we could write the user object to a database)
+          return user
+
+      joe = new_user(BasicUser)
+
+    At this point the type checker knows that joe has type BasicUser.
+    """
+
+
 def NamedTuple(typename, fields):
     """Typed version of namedtuple.
 
@@ -1487,6 +1639,41 @@ def NamedTuple(typename, fields):
     return cls
 
 
+def NewType(name, tp):
+    """NewType creates simple unique types with almost zero
+    runtime overhead. NewType(name, tp) is considered a subtype of tp
+    by static type checkers. At runtime, NewType(name, tp) returns
+    a dummy function that simply returns its argument. Usage::
+
+        UserId = NewType('UserId', int)
+
+        def name_by_id(user_id: UserId) -> str:
+            ...
+
+        UserId('user')          # Fails type check
+
+        name_by_id(42)          # Fails type check
+        name_by_id(UserId(42))  # OK
+
+        num = UserId(5) + 1     # type: int
+    """
+
+    def new_type(x):
+        return x
+
+    new_type.__name__ = name
+    new_type.__supertype__ = tp
+    return new_type
+
+
+# Python-version-specific alias (Python 2: unicode; Python 3: str)
+Text = str
+
+
+# Constant that's True when type checking, but False here.
+TYPE_CHECKING = False
+
+
 class IO(Generic[AnyStr]):
     """Generic base class for TextIO and BinaryIO.
 
index f6d7ae2..7f61a80 100644 (file)
@@ -1,6 +1,6 @@
 """
 Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
-Smalltalk testing framework.
+Smalltalk testing framework (used with permission).
 
 This module contains the core framework classes that form the basis of
 specific test cases and suites (TestCase, TestSuite etc.), and also a
index ac8d67d..524a7b1 100644 (file)
@@ -964,7 +964,7 @@ class TestCase(object):
 
                 if item1 != item2:
                     differing += ('\nFirst differing element %d:\n%s\n%s\n' %
-                                 (i, item1, item2))
+                                 ((i,) + _common_shorten_repr(item1, item2)))
                     break
             else:
                 if (len1 == len2 and seq_type is None and
@@ -977,7 +977,7 @@ class TestCase(object):
                              'elements.\n' % (seq_type_name, len1 - len2))
                 try:
                     differing += ('First extra element %d:\n%s\n' %
-                                  (len2, seq1[len2]))
+                                  (len2, safe_repr(seq1[len2])))
                 except (TypeError, IndexError, NotImplementedError):
                     differing += ('Unable to index element %d '
                                   'of first %s\n' % (len2, seq_type_name))
@@ -986,7 +986,7 @@ class TestCase(object):
                              'elements.\n' % (seq_type_name, len2 - len1))
                 try:
                     differing += ('First extra element %d:\n%s\n' %
-                                  (len1, seq2[len1]))
+                                  (len1, safe_repr(seq2[len1])))
                 except (TypeError, IndexError, NotImplementedError):
                     differing += ('Unable to index element %d '
                                   'of second %s\n' % (len1, seq_type_name))
index c776f16..eb447d7 100644 (file)
@@ -387,7 +387,7 @@ class TestLoader(object):
             if tests is not None:
                 yield tests
             if not should_recurse:
-                # Either an error occured, or load_tests was used by the
+                # Either an error occurred, or load_tests was used by the
                 # package.
                 return
         # Handle the contents.
@@ -479,6 +479,8 @@ class TestLoader(object):
                     return tests, True
                 finally:
                     self._loading_packages.discard(name)
+        else:
+            return None, False
 
 
 defaultTestLoader = TestLoader()
index 99ce1e2..86a5a3d 100644 (file)
@@ -1332,7 +1332,10 @@ class _patch(object):
             setattr(self.target, self.attribute, self.temp_original)
         else:
             delattr(self.target, self.attribute)
-            if not self.create and not hasattr(self.target, self.attribute):
+            if not self.create and (not hasattr(self.target, self.attribute) or
+                        self.attribute in ('__doc__', '__module__',
+                                           '__defaults__', '__annotations__',
+                                           '__kwdefaults__')):
                 # needed for proxy objects like django settings
                 setattr(self.target, self.attribute, self.temp_original)
 
@@ -2026,6 +2029,9 @@ class _Call(tuple):
         return (other_args, other_kwargs) == (self_args, self_kwargs)
 
 
+    __ne__ = object.__ne__
+
+
     def __call__(self, *args, **kwargs):
         if self.name is None:
             return _Call(('', args, kwargs), name='()')
@@ -2317,6 +2323,8 @@ def mock_open(mock=None, read_data=''):
                 yield handle.readline.return_value
         for line in _state[0]:
             yield line
+        while True:
+            yield type(read_data)()
 
 
     global file_spec
index a18f11b..c7e3206 100644 (file)
@@ -148,7 +148,7 @@ class TestResult(object):
         self.skipped.append((test, reason))
 
     def addExpectedFailure(self, test, err):
-        """Called when an expected failure/error occured."""
+        """Called when an expected failure/error occurred."""
         self.expectedFailures.append(
             (test, self._exc_info_to_string(err, test)))
 
index 76c4725..353d4a1 100644 (file)
@@ -71,7 +71,7 @@ class BaseTestSuite(object):
         try:
             test = self._tests[index]
         except TypeError:
-            # support for suite implementations that have overriden self._tests
+            # support for suite implementations that have overridden self._tests
             pass
         else:
             # Some unittest tests add non TestCase/TestSuite objects to
index ada733b..1fb95dc 100644 (file)
@@ -1121,6 +1121,82 @@ test case
             error = str(e).split('\n', 1)[1]
             self.assertEqual(sample_text_error, error)
 
+    def testEqualityBytesWarning(self):
+        if sys.flags.bytes_warning:
+            def bytes_warning():
+                return self.assertWarnsRegex(BytesWarning,
+                            'Comparison between bytes and string')
+        else:
+            def bytes_warning():
+                return contextlib.ExitStack()
+
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertEqual('a', b'a')
+        with bytes_warning():
+            self.assertNotEqual('a', b'a')
+
+        a = [0, 'a']
+        b = [0, b'a']
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertListEqual(a, b)
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertTupleEqual(tuple(a), tuple(b))
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertSequenceEqual(a, tuple(b))
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertSequenceEqual(tuple(a), b)
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertSequenceEqual('a', b'a')
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertSetEqual(set(a), set(b))
+
+        with self.assertRaises(self.failureException):
+            self.assertListEqual(a, tuple(b))
+        with self.assertRaises(self.failureException):
+            self.assertTupleEqual(tuple(a), b)
+
+        a = [0, b'a']
+        b = [0]
+        with self.assertRaises(self.failureException):
+            self.assertListEqual(a, b)
+        with self.assertRaises(self.failureException):
+            self.assertTupleEqual(tuple(a), tuple(b))
+        with self.assertRaises(self.failureException):
+            self.assertSequenceEqual(a, tuple(b))
+        with self.assertRaises(self.failureException):
+            self.assertSequenceEqual(tuple(a), b)
+        with self.assertRaises(self.failureException):
+            self.assertSetEqual(set(a), set(b))
+
+        a = [0]
+        b = [0, b'a']
+        with self.assertRaises(self.failureException):
+            self.assertListEqual(a, b)
+        with self.assertRaises(self.failureException):
+            self.assertTupleEqual(tuple(a), tuple(b))
+        with self.assertRaises(self.failureException):
+            self.assertSequenceEqual(a, tuple(b))
+        with self.assertRaises(self.failureException):
+            self.assertSequenceEqual(tuple(a), b)
+        with self.assertRaises(self.failureException):
+            self.assertSetEqual(set(a), set(b))
+
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertDictEqual({'a': 0}, {b'a': 0})
+        with self.assertRaises(self.failureException):
+            self.assertDictEqual({}, {b'a': 0})
+        with self.assertRaises(self.failureException):
+            self.assertDictEqual({b'a': 0}, {})
+
+        with self.assertRaises(self.failureException):
+            self.assertCountEqual([b'a', b'a'], [b'a', b'a', b'a'])
+        with bytes_warning():
+            self.assertCountEqual(['a', b'a'], ['a', b'a'])
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertCountEqual(['a', 'a'], [b'a', b'a'])
+        with bytes_warning(), self.assertRaises(self.failureException):
+            self.assertCountEqual(['a', 'a', []], [b'a', b'a', []])
+
     def testAssertIsNone(self):
         self.assertIsNone(None)
         self.assertRaises(self.failureException, self.assertIsNone, False)
index 55921fe..bb196e6 100644 (file)
@@ -90,6 +90,46 @@ class TestDiscovery(unittest.TestCase):
                     ('test3', 'test4')])
         self.assertEqual(suite, expected)
 
+    def test_find_tests_socket(self):
+        # A socket is neither a directory nor a regular file.
+        # https://bugs.python.org/issue25320
+        loader = unittest.TestLoader()
+
+        original_listdir = os.listdir
+        def restore_listdir():
+            os.listdir = original_listdir
+        original_isfile = os.path.isfile
+        def restore_isfile():
+            os.path.isfile = original_isfile
+        original_isdir = os.path.isdir
+        def restore_isdir():
+            os.path.isdir = original_isdir
+
+        path_lists = [['socket']]
+        os.listdir = lambda path: path_lists.pop(0)
+        self.addCleanup(restore_listdir)
+
+        os.path.isdir = lambda path: False
+        self.addCleanup(restore_isdir)
+
+        os.path.isfile = lambda path: False
+        self.addCleanup(restore_isfile)
+
+        loader._get_module_from_name = lambda path: path + ' module'
+        orig_load_tests = loader.loadTestsFromModule
+        def loadTestsFromModule(module, pattern=None):
+            # This is where load_tests is called.
+            base = orig_load_tests(module, pattern=pattern)
+            return base + [module + ' tests']
+        loader.loadTestsFromModule = loadTestsFromModule
+        loader.suiteClass = lambda thing: thing
+
+        top_level = os.path.abspath('/foo')
+        loader._top_level_dir = top_level
+        suite = list(loader._find_tests(top_level, 'test*.py'))
+
+        self.assertEqual(suite, [])
+
     def test_find_tests_with_package(self):
         loader = unittest.TestLoader()
 
index 68f1036..4b97882 100644 (file)
@@ -8,7 +8,7 @@ import unittest
 # test isolation and reproducibility.
 def warningregistry(func):
     def wrapper(*args, **kws):
-        missing = object()
+        missing = []
         saved = getattr(warnings, '__warningregistry__', missing).copy()
         try:
             return func(*args, **kws)
@@ -20,6 +20,7 @@ def warningregistry(func):
                     pass
             else:
                 warnings.__warningregistry__ = saved
+    return wrapper
 
 
 class Test_TestLoader(unittest.TestCase):
@@ -197,9 +198,9 @@ class Test_TestLoader(unittest.TestCase):
         # ignored (and deprecated).
         load_tests_args = []
         with warnings.catch_warnings(record=False):
-            warnings.simplefilter('never')
+            warnings.simplefilter('ignore')
             suite = loader.loadTestsFromModule(m, use_load_tests=False)
-            self.assertEqual(load_tests_args, [loader, suite, None])
+        self.assertEqual(load_tests_args, [loader, suite, None])
 
     @warningregistry
     def test_loadTestsFromModule__use_load_tests_deprecated_positional(self):
@@ -221,10 +222,10 @@ class Test_TestLoader(unittest.TestCase):
         with warnings.catch_warnings(record=True) as w:
             warnings.simplefilter('always')
             suite = loader.loadTestsFromModule(m, False)
-            self.assertIsInstance(suite, unittest.TestSuite)
-            # load_tests was still called because use_load_tests is deprecated
-            # and ignored.
-            self.assertEqual(load_tests_args, [loader, suite, None])
+        self.assertIsInstance(suite, unittest.TestSuite)
+        # load_tests was still called because use_load_tests is deprecated
+        # and ignored.
+        self.assertEqual(load_tests_args, [loader, suite, None])
         # We got a warning.
         self.assertIs(w[-1].category, DeprecationWarning)
         self.assertEqual(str(w[-1].message),
@@ -249,14 +250,14 @@ class Test_TestLoader(unittest.TestCase):
         with warnings.catch_warnings(record=True) as w:
             warnings.simplefilter('always')
             suite = loader.loadTestsFromModule(m, use_load_tests=False)
-            self.assertIsInstance(suite, unittest.TestSuite)
-            # load_tests was still called because use_load_tests is deprecated
-            # and ignored.
-            self.assertEqual(load_tests_args, [loader, suite, None])
-            # We got a warning.
-            self.assertIs(w[-1].category, DeprecationWarning)
-            self.assertEqual(str(w[-1].message),
-                                 'use_load_tests is deprecated and ignored')
+        self.assertIsInstance(suite, unittest.TestSuite)
+        # load_tests was still called because use_load_tests is deprecated
+        # and ignored.
+        self.assertEqual(load_tests_args, [loader, suite, None])
+        # We got a warning.
+        self.assertIs(w[-1].category, DeprecationWarning)
+        self.assertEqual(str(w[-1].message),
+                             'use_load_tests is deprecated and ignored')
 
     @warningregistry
     def test_loadTestsFromModule__too_many_positional_args(self):
@@ -274,17 +275,18 @@ class Test_TestLoader(unittest.TestCase):
         m.load_tests = load_tests
         loader = unittest.TestLoader()
         with self.assertRaises(TypeError) as cm, \
-             warnings.catch_warning(record=True) as w:
+             warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always')
             loader.loadTestsFromModule(m, False, 'testme.*')
-            # We still got the deprecation warning.
-            self.assertIs(w[-1].category, DeprecationWarning)
-            self.assertEqual(str(w[-1].message),
-                                 'use_load_tests is deprecated and ignored')
-            # We also got a TypeError for too many positional arguments.
-            self.assertEqual(type(cm.exception), TypeError)
-            self.assertEqual(
-                str(cm.exception),
-                'loadTestsFromModule() takes 1 positional argument but 3 were given')
+        # We still got the deprecation warning.
+        self.assertIs(w[-1].category, DeprecationWarning)
+        self.assertEqual(str(w[-1].message),
+                                'use_load_tests is deprecated and ignored')
+        # We also got a TypeError for too many positional arguments.
+        self.assertEqual(type(cm.exception), TypeError)
+        self.assertEqual(
+            str(cm.exception),
+            'loadTestsFromModule() takes 1 positional argument but 3 were given')
 
     @warningregistry
     def test_loadTestsFromModule__use_load_tests_other_bad_keyword(self):
@@ -302,7 +304,7 @@ class Test_TestLoader(unittest.TestCase):
         m.load_tests = load_tests
         loader = unittest.TestLoader()
         with warnings.catch_warnings():
-            warnings.simplefilter('never')
+            warnings.simplefilter('ignore')
             with self.assertRaises(TypeError) as cm:
                 loader.loadTestsFromModule(
                     m, use_load_tests=False, very_bad=True, worse=False)
index 9cbc260..ddc498c 100644 (file)
@@ -290,7 +290,8 @@ class Test_TextTestRunner(unittest.TestCase):
 
         # no args -> all the warnings are printed, unittest warnings only once
         p = subprocess.Popen([sys.executable, '_test_warnings.py'], **opts)
-        out, err = get_parse_out_err(p)
+        with p:
+            out, err = get_parse_out_err(p)
         self.assertIn(b'OK', err)
         # check that the total number of warnings in the output is correct
         self.assertEqual(len(out), 12)
@@ -311,7 +312,8 @@ class Test_TextTestRunner(unittest.TestCase):
         # in all these cases no warnings are printed
         for args in args_list:
             p = subprocess.Popen(args, **opts)
-            out, err = get_parse_out_err(p)
+            with p:
+                out, err = get_parse_out_err(p)
             self.assertIn(b'OK', err)
             self.assertEqual(len(out), 0)
 
@@ -320,7 +322,8 @@ class Test_TextTestRunner(unittest.TestCase):
         #                                     unittest warnings only once
         p = subprocess.Popen([sys.executable, '_test_warnings.py', 'always'],
                              **opts)
-        out, err = get_parse_out_err(p)
+        with p:
+            out, err = get_parse_out_err(p)
         self.assertIn(b'OK', err)
         self.assertEqual(len(out), 14)
         for msg in [b'dw', b'iw', b'uw', b'rw']:
index 2a6069f..5f82b82 100644 (file)
@@ -304,6 +304,17 @@ class MockTest(unittest.TestCase):
         # an exception. See issue 24857.
         self.assertFalse(mock.call_args == "a long sequence")
 
+
+    def test_calls_equal_with_any(self):
+        call1 = mock.call(mock.MagicMock())
+        call2 = mock.call(mock.ANY)
+
+        # Check that equality and non-equality is consistent even when
+        # comparing with mock.ANY
+        self.assertTrue(call1 == call2)
+        self.assertFalse(call1 != call2)
+
+
     def test_assert_called_with(self):
         mock = Mock()
         mock()
@@ -319,6 +330,12 @@ class MockTest(unittest.TestCase):
         mock.assert_called_with(1, 2, 3, a='fish', b='nothing')
 
 
+    def test_assert_called_with_any(self):
+        m = MagicMock()
+        m(MagicMock())
+        m.assert_called_with(mock.ANY)
+
+
     def test_assert_called_with_function_spec(self):
         def f(a, b, c, d=None):
             pass
@@ -1402,6 +1419,18 @@ class MockTest(unittest.TestCase):
         self.assertEqual('abc', first)
         self.assertEqual('abc', second)
 
+    def test_mock_open_after_eof(self):
+        # read, readline and readlines should work after end of file.
+        _open = mock.mock_open(read_data='foo')
+        h = _open('bar')
+        h.read()
+        self.assertEqual('', h.read())
+        self.assertEqual('', h.read())
+        self.assertEqual('', h.readline())
+        self.assertEqual('', h.readline())
+        self.assertEqual([], h.readlines())
+        self.assertEqual([], h.readlines())
+
     def test_mock_parents(self):
         for Klass in Mock, MagicMock:
             m = Klass()
index 28fe86b..dfce369 100644 (file)
@@ -1817,5 +1817,31 @@ class PatchTest(unittest.TestCase):
         self.assertEqual(stopped, ["three", "two", "one"])
 
 
+    def test_special_attrs(self):
+        def foo(x=0):
+            """TEST"""
+            return x
+        with patch.object(foo, '__defaults__', (1, )):
+            self.assertEqual(foo(), 1)
+        self.assertEqual(foo(), 0)
+
+        with patch.object(foo, '__doc__', "FUN"):
+            self.assertEqual(foo.__doc__, "FUN")
+        self.assertEqual(foo.__doc__, "TEST")
+
+        with patch.object(foo, '__module__', "testpatch2"):
+            self.assertEqual(foo.__module__, "testpatch2")
+        self.assertEqual(foo.__module__, 'unittest.test.testmock.testpatch')
+
+        with patch.object(foo, '__annotations__', dict([('s', 1, )])):
+            self.assertEqual(foo.__annotations__, dict([('s', 1, )]))
+        self.assertEqual(foo.__annotations__, dict())
+
+        def foo(*a, x=0):
+            return x
+        with patch.object(foo, '__kwdefaults__', dict([('x', 1, )])):
+            self.assertEqual(foo(), 1)
+        self.assertEqual(foo(), 0)
+
 if __name__ == '__main__':
     unittest.main()
index 01c9e58..4d7fcec 100644 (file)
@@ -830,21 +830,6 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None,
                         l.append(k + '=' + elt)
     return '&'.join(l)
 
-# Utilities to parse URLs (most of these return None for missing parts):
-# unwrap('<URL:type://host/path>') --> 'type://host/path'
-# splittype('type:opaquestring') --> 'type', 'opaquestring'
-# splithost('//host[:port]/path') --> 'host[:port]', '/path'
-# splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'
-# splitpasswd('user:passwd') -> 'user', 'passwd'
-# splitport('host:port') --> 'host', 'port'
-# splitquery('/path?query') --> '/path', 'query'
-# splittag('/path#tag') --> '/path', 'tag'
-# splitattr('/path;attr1=value1;attr2=value2;...') ->
-#   '/path', ['attr1=value1', 'attr2=value2', ...]
-# splitvalue('attr=value') --> 'attr', 'value'
-# urllib.parse.unquote('abc%20def') -> 'abc def'
-# quote('abc def') -> 'abc%20def')
-
 def to_bytes(url):
     """to_bytes(u"URL") --> 'URL'."""
     # Most URL schemes require ASCII. If that changes, the conversion
index a7fd017..1731fe3 100644 (file)
@@ -91,6 +91,7 @@ import os
 import posixpath
 import re
 import socket
+import string
 import sys
 import time
 import collections
@@ -616,8 +617,12 @@ class HTTPRedirectHandler(BaseHandler):
         # from the user (of urllib.request, in this case).  In practice,
         # essentially all clients do redirect in this case, so we do
         # the same.
-        # be conciliant with URIs containing a space
+
+        # Be conciliant with URIs containing a space.  This is mainly
+        # redundant with the more complete encoding done in http_error_302(),
+        # but it is kept for compatibility with other callers.
         newurl = newurl.replace(' ', '%20')
+
         CONTENT_HEADERS = ("content-length", "content-type")
         newheaders = dict((k, v) for k, v in req.headers.items()
                           if k.lower() not in CONTENT_HEADERS)
@@ -652,11 +657,16 @@ class HTTPRedirectHandler(BaseHandler):
                 "%s - Redirection to url '%s' is not allowed" % (msg, newurl),
                 headers, fp)
 
-        if not urlparts.path:
+        if not urlparts.path and urlparts.netloc:
             urlparts = list(urlparts)
             urlparts[2] = "/"
         newurl = urlunparse(urlparts)
 
+        # http.client.parse_headers() decodes as ISO-8859-1.  Recover the
+        # original bytes and percent-encode non-ASCII bytes, and any special
+        # characters such as the space.
+        newurl = quote(
+            newurl, encoding="iso-8859-1", safe=string.punctuation)
         newurl = urljoin(req.full_url, newurl)
 
         # XXX Probably want to forget about the state of the current
@@ -1111,6 +1121,9 @@ class AbstractDigestAuthHandler:
         elif algorithm == 'SHA':
             H = lambda x: hashlib.sha1(x.encode("ascii")).hexdigest()
         # XXX MD5-sess
+        else:
+            raise ValueError("Unsupported digest authentication "
+                             "algorithm %r" % algorithm)
         KD = lambda s, d: H("%s:%s" % (s, d))
         return H, KD
 
@@ -1208,6 +1221,7 @@ class AbstractHTTPHandler(BaseHandler):
 
         # will parse host:port
         h = http_class(host, timeout=req.timeout, **http_conn_args)
+        h.set_debuglevel(self._debuglevel)
 
         headers = dict(req.unredirected_hdrs)
         headers.update(dict((k, v) for k, v in req.headers.items()
@@ -2050,18 +2064,20 @@ class FancyURLopener(URLopener):
     def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
         """Error 302 -- relocated (temporarily)."""
         self.tries += 1
-        if self.maxtries and self.tries >= self.maxtries:
-            if hasattr(self, "http_error_500"):
-                meth = self.http_error_500
-            else:
-                meth = self.http_error_default
+        try:
+            if self.maxtries and self.tries >= self.maxtries:
+                if hasattr(self, "http_error_500"):
+                    meth = self.http_error_500
+                else:
+                    meth = self.http_error_default
+                return meth(url, fp, 500,
+                            "Internal Server Error: Redirect Recursion",
+                            headers)
+            result = self.redirect_internal(url, fp, errcode, errmsg,
+                                            headers, data)
+            return result
+        finally:
             self.tries = 0
-            return meth(url, fp, 500,
-                        "Internal Server Error: Redirect Recursion", headers)
-        result = self.redirect_internal(url, fp, errcode, errmsg, headers,
-                                        data)
-        self.tries = 0
-        return result
 
     def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
         if 'location' in headers:
@@ -2390,19 +2406,35 @@ def getproxies_environment():
 
     """
     proxies = {}
+    # in order to prefer lowercase variables, process environment in
+    # two passes: first matches any, second pass matches lowercase only
     for name, value in os.environ.items():
         name = name.lower()
         if value and name[-6:] == '_proxy':
             proxies[name[:-6]] = value
+    for name, value in os.environ.items():
+        if name[-6:] == '_proxy':
+            name = name.lower()
+            if value:
+                proxies[name[:-6]] = value
+            else:
+                proxies.pop(name[:-6], None)
     return proxies
 
-def proxy_bypass_environment(host):
+def proxy_bypass_environment(host, proxies=None):
     """Test if proxies should not be used for a particular host.
 
-    Checks the environment for a variable named no_proxy, which should
-    be a list of DNS suffixes separated by commas, or '*' for all hosts.
+    Checks the proxy dict for the value of no_proxy, which should
+    be a list of comma separated DNS suffixes, or '*' for all hosts.
+
     """
-    no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
+    if proxies is None:
+        proxies = getproxies_environment()
+    # don't bypass, if no_proxy isn't specified
+    try:
+        no_proxy = proxies['no']
+    except KeyError:
+        return 0
     # '*' is special case for always bypass
     if no_proxy == '*':
         return 1
@@ -2411,8 +2443,12 @@ def proxy_bypass_environment(host):
     # check if the host ends with any of the DNS suffixes
     no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')]
     for name in no_proxy_list:
-        if name and (hostonly.endswith(name) or host.endswith(name)):
-            return 1
+        if name:
+            name = re.escape(name)
+            pattern = r'(.+\.)?%s$' % name
+            if (re.match(pattern, hostonly, re.I)
+                    or re.match(pattern, host, re.I)):
+                return 1
     # otherwise, don't bypass
     return 0
 
@@ -2497,8 +2533,15 @@ if sys.platform == 'darwin':
 
 
     def proxy_bypass(host):
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
+        """Return True, if host should be bypassed.
+
+        Checks proxy settings gathered from the environment, if specified,
+        or from the MacOSX framework SystemConfiguration.
+
+        """
+        proxies = getproxies_environment()
+        if proxies:
+            return proxy_bypass_environment(host, proxies)
         else:
             return proxy_bypass_macosx_sysconf(host)
 
@@ -2612,14 +2655,15 @@ elif os.name == 'nt':
         return 0
 
     def proxy_bypass(host):
-        """Return a dictionary of scheme -> proxy server URL mappings.
+        """Return True, if host should be bypassed.
 
-        Returns settings gathered from the environment, if specified,
+        Checks proxy settings gathered from the environment, if specified,
         or the registry.
 
         """
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
+        proxies = getproxies_environment()
+        if proxies:
+            return proxy_bypass_environment(host, proxies)
         else:
             return proxy_bypass_registry(host)
 
index 4fbb0cb..8b69fd9 100644 (file)
@@ -132,7 +132,7 @@ class RobotFileParser:
             return True
         # Until the robots.txt file has been read or found not
         # to exist, we must assume that no url is allowable.
-        # This prevents false positives when a user erronenously
+        # This prevents false positives when a user erroneously
         # calls can_fetch() before calling read().
         if not self.last_checked:
             return False
index 5b24e2c..e96e7e0 100644 (file)
@@ -131,7 +131,8 @@ class UUID(object):
         """
 
         if [hex, bytes, bytes_le, fields, int].count(None) != 4:
-            raise TypeError('need one of hex, bytes, bytes_le, fields, or int')
+            raise TypeError('one of the hex, bytes, bytes_le, fields, '
+                            'or int arguments must be given')
         if hex is not None:
             hex = hex.replace('urn:', '').replace('uuid:', '')
             hex = hex.strip('{}').replace('-', '')
index 3d606ef..74245ab 100644 (file)
@@ -19,9 +19,8 @@ optional arguments:
                         Give the virtual environment access to the system
                         site-packages dir.
   --symlinks            Attempt to symlink rather than copy.
-  --clear               Delete the environment directory if it already exists.
-                        If not specified and the directory exists, an error is
-                        raised.
+  --clear               Delete the contents of the environment directory if it
+                        already exists, before environment creation.
   --upgrade             Upgrade the environment directory to use this version
                         of Python, assuming Python has been upgraded in-place.
   --without-pip         Skips installing or upgrading pip in the virtual
@@ -52,9 +51,8 @@ class EnvBuilder:
 
     :param system_site_packages: If True, the system (global) site-packages
                                  dir is available to created environments.
-    :param clear: If True and the target directory exists, it is deleted.
-                  Otherwise, if the target directory exists, an error is
-                  raised.
+    :param clear: If True, delete the contents of the environment directory if
+                  it already exists, before environment creation.
     :param symlinks: If True, attempt to symlink rather than copy files into
                      virtual environment.
     :param upgrade: If True, upgrade an existing virtual environment.
@@ -361,9 +359,8 @@ def create(env_dir, system_site_packages=False, clear=False,
     :param env_dir: The target directory to create an environment in.
     :param system_site_packages: If True, the system (global) site-packages
                                  dir is available to the environment.
-    :param clear: If True and the target directory exists, it is deleted.
-                  Otherwise, if the target directory exists, an error is
-                  raised.
+    :param clear: If True, delete the contents of the environment directory if
+                  it already exists, before environment creation.
     :param symlinks: If True, attempt to symlink rather than copy files into
                      virtual environment.
     :param with_pip: If True, ensure pip is installed in the virtual
index 45391aa..fb7f5c0 100644 (file)
@@ -55,8 +55,8 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
     # with the original prompt function renamed, we can override with our own.
     function fish_prompt
         # Prompt override?
-        if test -n "__VENV_PROMPT__"
-            printf "%s%s%s" "__VENV_PROMPT__" (set_color normal) (_old_fish_prompt)
+        if test -n "$__VENV_PROMPT__"
+            printf "%s%s%s" "$__VENV_PROMPT__" (set_color normal) (_old_fish_prompt)
             return
         end
         # ...Otherwise, prepend env
index 1d4fb20..c6631fc 100644 (file)
@@ -21,9 +21,15 @@ def showwarning(message, category, filename, lineno, file=None, line=None):
 
 def formatwarning(message, category, filename, lineno, line=None):
     """Function to format a warning the standard way."""
-    import linecache
     s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
-    line = linecache.getline(filename, lineno) if line is None else line
+    if line is None:
+        try:
+            import linecache
+            line = linecache.getline(filename, lineno)
+        except Exception:
+            # When a warning is logged during Python shutdown, linecache
+            # and the import machinery don't work anymore
+            line = None
     if line:
         line = line.strip()
         s += "  %s\n" % line
@@ -50,13 +56,8 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0,
     assert isinstance(module, str), "module must be a string"
     assert isinstance(lineno, int) and lineno >= 0, \
            "lineno must be an int >= 0"
-    item = (action, re.compile(message, re.I), category,
-            re.compile(module), lineno)
-    if append:
-        filters.append(item)
-    else:
-        filters.insert(0, item)
-    _filters_mutated()
+    _add_filter(action, re.compile(message, re.I), category,
+            re.compile(module), lineno, append=append)
 
 def simplefilter(action, category=Warning, lineno=0, append=False):
     """Insert a simple entry into the list of warnings filters (at the front).
@@ -72,11 +73,20 @@ def simplefilter(action, category=Warning, lineno=0, append=False):
                       "once"), "invalid action: %r" % (action,)
     assert isinstance(lineno, int) and lineno >= 0, \
            "lineno must be an int >= 0"
-    item = (action, None, category, None, lineno)
-    if append:
-        filters.append(item)
-    else:
+    _add_filter(action, None, category, None, lineno, append=append)
+
+def _add_filter(*item, append):
+    # Remove possible duplicate filters, so new one will be placed
+    # in correct place. If append=True and duplicate exists, do nothing.
+    if not append:
+        try:
+            filters.remove(item)
+        except ValueError:
+            pass
         filters.insert(0, item)
+    else:
+        if item not in filters:
+            filters.append(item)
     _filters_mutated()
 
 def resetwarnings():
index 63d5993..f4300b8 100644 (file)
@@ -226,7 +226,7 @@ class BaseHandler:
         self.headers = self.headers_class(headers)
         status = self._convert_string_type(status, "Status")
         assert len(status)>=4,"Status must be at least 4 characters"
-        assert int(status[:3]),"Status message must begin w/3-digit code"
+        assert status[:3].isdigit(), "Status message must begin w/3-digit code"
         assert status[3]==" ", "Status message must have a space after code"
 
         if __debug__:
@@ -450,7 +450,17 @@ class SimpleHandler(BaseHandler):
         self.environ.update(self.base_env)
 
     def _write(self,data):
-        self.stdout.write(data)
+        result = self.stdout.write(data)
+        if result is None or result == len(data):
+            return
+        from warnings import warn
+        warn("SimpleHandler.stdout.write() should not do partial writes",
+            DeprecationWarning)
+        while True:
+            data = data[result:]
+            if not data:
+                break
+            result = self.stdout.write(data)
 
     def _flush(self):
         self.stdout.flush()
index 7e670b3..fab851c 100644 (file)
@@ -69,7 +69,7 @@ class Headers:
         Return None if the header is missing instead of raising an exception.
 
         Note that if the header appeared multiple times, the first exactly which
-        occurrance gets returned is undefined.  Use getall() to get all
+        occurrence gets returned is undefined.  Use getall() to get all
         the values matching a header field name.
         """
         return self.get(name)
index 378b316..7fddbe8 100644 (file)
@@ -11,6 +11,7 @@ module.  See also the BaseHTTPServer module docs for other API information.
 """
 
 from http.server import BaseHTTPRequestHandler, HTTPServer
+from io import BufferedWriter
 import sys
 import urllib.parse
 from wsgiref.handlers import SimpleHandler
@@ -82,7 +83,7 @@ class WSGIRequestHandler(BaseHTTPRequestHandler):
         else:
             path,query = self.path,''
 
-        env['PATH_INFO'] = urllib.parse.unquote_to_bytes(path).decode('iso-8859-1')
+        env['PATH_INFO'] = urllib.parse.unquote(path, 'iso-8859-1')
         env['QUERY_STRING'] = query
 
         host = self.address_string()
@@ -126,11 +127,17 @@ class WSGIRequestHandler(BaseHTTPRequestHandler):
         if not self.parse_request(): # An error code has been sent, just exit
             return
 
-        handler = ServerHandler(
-            self.rfile, self.wfile, self.get_stderr(), self.get_environ()
-        )
-        handler.request_handler = self      # backpointer for logging
-        handler.run(self.server.get_app())
+        # Avoid passing the raw file object wfile, which can do partial
+        # writes (Issue 24291)
+        stdout = BufferedWriter(self.wfile)
+        try:
+            handler = ServerHandler(
+                self.rfile, stdout, self.get_stderr(), self.get_environ()
+            )
+            handler.request_handler = self      # backpointer for logging
+            handler.run(self.server.get_app())
+        finally:
+            stdout.detach()
 
 
 
index 1244500..5d6fae9 100644 (file)
@@ -64,10 +64,10 @@ class NodeList(list):
     length = property(_get_length, _set_length,
                       doc="The number of nodes in the NodeList.")
 
-    def __getstate__(self):
-        return list(self)
-
+    # For backward compatibility
     def __setstate__(self, state):
+        if state is None:
+            state = []
         self[:] = state
 
 
index bb32a8f..6d1b0ab 100644 (file)
@@ -428,12 +428,14 @@ class Element:
         tag = self.tag
         if not isinstance(tag, str) and tag is not None:
             return
-        if self.text:
-            yield self.text
+        t = self.text
+        if t:
+            yield t
         for e in self:
             yield from e.itertext()
-            if e.tail:
-                yield e.tail
+            t = e.tail
+            if t:
+                yield t
 
 
 def SubElement(parent, tag, attrib={}, **extra):
@@ -1202,7 +1204,12 @@ def iterparse(source, events=None, parser=None):
     if not hasattr(source, "read"):
         source = open(source, "rb")
         close_source = True
-    return _IterParseIterator(source, events, parser, close_source)
+    try:
+        return _IterParseIterator(source, events, parser, close_source)
+    except:
+        if close_source:
+            source.close()
+        raise
 
 
 class XMLPullParser:
@@ -1285,20 +1292,26 @@ class _IterParseIterator:
         self.root = self._root = None
 
     def __next__(self):
-        while 1:
-            for event in self._parser.read_events():
-                return event
-            if self._parser._parser is None:
-                self.root = self._root
-                if self._close_file:
-                    self._file.close()
-                raise StopIteration
-            # load event buffer
-            data = self._file.read(16 * 1024)
-            if data:
-                self._parser.feed(data)
-            else:
-                self._root = self._parser._close_and_return_root()
+        try:
+            while 1:
+                for event in self._parser.read_events():
+                    return event
+                if self._parser._parser is None:
+                    break
+                # load event buffer
+                data = self._file.read(16 * 1024)
+                if data:
+                    self._parser.feed(data)
+                else:
+                    self._root = self._parser._close_and_return_root()
+            self.root = self._root
+        except:
+            if self._close_file:
+                self._file.close()
+            raise
+        if self._close_file:
+            self._file.close()
+        raise StopIteration
 
     def __iter__(self):
         return self
@@ -1441,7 +1454,7 @@ class TreeBuilder:
 class XMLParser:
     """Element structure builder for XML source data based on the expat parser.
 
-    *html* are predefined HTML entities (not supported currently),
+    *html* are predefined HTML entities (deprecated and not supported),
     *target* is an optional target object which defaults to an instance of the
     standard TreeBuilder class, *encoding* is an optional encoding string
     which if given, overrides the encoding specified in the XML file:
index 25e684f..bbf9ee6 100644 (file)
@@ -640,6 +640,7 @@ class Unmarshaller:
         self._stack = []
         self._marks = []
         self._data = []
+        self._value = False
         self._methodname = None
         self._encoding = "utf-8"
         self.append = self._stack.append
@@ -669,6 +670,8 @@ class Unmarshaller:
         if tag == "array" or tag == "struct":
             self._marks.append(len(self._stack))
         self._data = []
+        if self._value and tag not in self.dispatch:
+            raise ResponseError("unknown tag %r" % tag)
         self._value = (tag == "value")
 
     def data(self, text):
@@ -955,8 +958,6 @@ def dumps(params, methodname=None, methodresponse=None, encoding=None,
     # standard XML-RPC wrappings
     if methodname:
         # a method call
-        if not isinstance(methodname, str):
-            methodname = methodname.encode(encoding)
         data = (
             xmlheader,
             "<methodCall>\n"
@@ -1131,13 +1132,13 @@ class Transport:
         for i in (0, 1):
             try:
                 return self.single_request(host, handler, request_body, verbose)
+            except http.client.RemoteDisconnected:
+                if i:
+                    raise
             except OSError as e:
                 if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED,
                                         errno.EPIPE):
                     raise
-            except http.client.RemoteDisconnected:
-                if i:
-                    raise
 
     def single_request(self, host, handler, request_body, verbose=False):
         # issue XML-RPC request
@@ -1422,7 +1423,7 @@ class ServerProxy:
         # call a method on the remote server
 
         request = dumps(params, methodname, encoding=self.__encoding,
-                        allow_none=self.__allow_none).encode(self.__encoding)
+                        allow_none=self.__allow_none).encode(self.__encoding, 'xmlcharrefreplace')
 
         response = self.__transport.request(
             self.__host,
@@ -1448,7 +1449,7 @@ class ServerProxy:
         # magic method dispatcher
         return _Method(self.__request, name)
 
-    # note: to call a remote object with an non-standard name, use
+    # note: to call a remote object with a non-standard name, use
     # result getattr(server, "strange-python-name")(args)
 
     def __call__(self, attr):
index 304e218..5b5bf7c 100644 (file)
@@ -269,7 +269,7 @@ class SimpleXMLRPCDispatcher:
                 encoding=self.encoding, allow_none=self.allow_none,
                 )
 
-        return response.encode(self.encoding)
+        return response.encode(self.encoding, 'xmlcharrefreplace')
 
     def system_listMethods(self):
         """system.listMethods() => ['add', 'subtract', 'multiple']
@@ -622,7 +622,7 @@ class MultiPathXMLRPCServer(SimpleXMLRPCServer):
             response = dumps(
                 Fault(1, "%s:%s" % (exc_type, exc_value)),
                 encoding=self.encoding, allow_none=self.allow_none)
-            response = response.encode(self.encoding)
+            response = response.encode(self.encoding, 'xmlcharrefreplace')
         return response
 
 class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher):
index c8380bf..eceb91d 100644 (file)
@@ -89,9 +89,10 @@ def create_archive(source, target=None, interpreter=None, main=None):
     The created application archive will have a shebang line specifying
     that it should run with INTERPRETER (there will be no shebang line if
     INTERPRETER is None), and a __main__.py which runs MAIN (if MAIN is
-    not specified, an existing __main__.py will be used). It is an to specify
-    MAIN for anything other than a directory source with no __main__.py, and it
-    is an error to omit MAIN if the directory has no __main__.py.
+    not specified, an existing __main__.py will be used).  It is an error
+    to specify MAIN for anything other than a directory source with no
+    __main__.py, and it is an error to omit MAIN if the directory has no
+    __main__.py.
     """
     # Are we copying an existing archive?
     source_is_file = False
index 2bd1007..56a2479 100644 (file)
@@ -734,7 +734,7 @@ class ZipExtFile(io.BufferedIOBase):
 
         if hasattr(zipinfo, 'CRC'):
             self._expected_crc = zipinfo.CRC
-            self._running_crc = crc32(b'') & 0xffffffff
+            self._running_crc = crc32(b'')
         else:
             self._expected_crc = None
 
@@ -856,7 +856,7 @@ class ZipExtFile(io.BufferedIOBase):
         if self._expected_crc is None:
             # No need to compute the CRC if we don't have a reference value
             return
-        self._running_crc = crc32(newdata, self._running_crc) & 0xffffffff
+        self._running_crc = crc32(newdata, self._running_crc)
         # Check the CRC if we're at the end of the file
         if self._eof and self._running_crc != self._expected_crc:
             raise BadZipFile("Bad CRC-32 for file %r" % self.name)
@@ -1444,7 +1444,9 @@ class ZipFile:
             arcname += '/'
         zinfo = ZipInfo(arcname, date_time)
         zinfo.external_attr = (st[0] & 0xFFFF) << 16      # Unix attributes
-        if compress_type is None:
+        if isdir:
+            zinfo.compress_type = ZIP_STORED
+        elif compress_type is None:
             zinfo.compress_type = self.compression
         else:
             zinfo.compress_type = compress_type
@@ -1490,7 +1492,7 @@ class ZipFile:
                     if not buf:
                         break
                     file_size = file_size + len(buf)
-                    CRC = crc32(buf, CRC) & 0xffffffff
+                    CRC = crc32(buf, CRC)
                     if cmpr:
                         buf = cmpr.compress(buf)
                         compress_size = compress_size + len(buf)
@@ -1565,7 +1567,7 @@ class ZipFile:
 
             self._writecheck(zinfo)
             self._didModify = True
-            zinfo.CRC = crc32(data) & 0xffffffff       # CRC-32 checksum
+            zinfo.CRC = crc32(data)       # CRC-32 checksum
             co = _get_compressor(zinfo.compress_type)
             if co:
                 data = co.compress(data) + co.flush()
index e8a1126..d09da2f 100755 (executable)
@@ -206,7 +206,7 @@ def library_recipes():
 
     LT_10_5 = bool(getDeptargetTuple() < (10, 5))
 
-    if getDeptargetTuple() < (10, 6):
+    if not (10, 5) < getDeptargetTuple() < (10, 10):
         # The OpenSSL libs shipped with OS X 10.5 and earlier are
         # hopelessly out-of-date and do not include Apple's tie-in to
         # the root certificates in the user and system keychains via TEA
@@ -226,7 +226,8 @@ def library_recipes():
         # now more obvious with cert checking enabled by default in the
         # standard library.
         #
-        # For builds with 10.6+ SDKs, continue to use the deprecated but
+        # For builds with 10.6 through 10.9 SDKs,
+        # continue to use the deprecated but
         # less out-of-date Apple 0.9.8 libs for now.  While they are less
         # secure than using an up-to-date 1.0.1 version, doing so
         # avoids the big problems of forcing users to have to manage
@@ -234,12 +235,16 @@ def library_recipes():
         # APIs for cert validation from keychains if validation using the
         # standard OpenSSL locations (/System/Library/OpenSSL, normally empty)
         # fails.
+        #
+        # Since Apple removed the header files for the deprecated system
+        # OpenSSL as of the Xcode 7 release (for OS X 10.10+), we do not
+        # have much choice but to build our own copy here, too.
 
         result.extend([
           dict(
-              name="OpenSSL 1.0.2d",
-              url="https://www.openssl.org/source/openssl-1.0.2d.tar.gz",
-              checksum='38dd619b2e77cbac69b99f52a053d25a',
+              name="OpenSSL 1.0.2h",
+              url="https://www.openssl.org/source/openssl-1.0.2h.tar.gz",
+              checksum='9392e65072ce4b614c1392eefc1f23d0',
               patches=[
                   "openssl_sdk_makedepend.patch",
                    ],
index 86a0f2f..96a8841 100644 (file)
@@ -1,18 +1,17 @@
 # HG changeset patch
-# Parent  25a9af415e8c3faf591c360d5f0e361d049b2b43
+# Parent  d377390f787c0739a3e89f669def72d7167e5108
 # openssl_sdk_makedepend.patch
 #
-#      using openssl 1.0.2d
+#      using openssl 1.0.2f
 #
 # - support building with an OS X SDK
-# - allow "make depend" to use compilers with names other than "gcc"
 
 diff Configure
 
 diff --git a/Configure b/Configure
 --- a/Configure
 +++ b/Configure
-@@ -617,12 +617,12 @@
+@@ -638,12 +638,12 @@
  
  ##### MacOS X (a.k.a. Rhapsody or Darwin) setup
  "rhapsody-ppc-cc","cc:-O3 -DB_ENDIAN::(unknown):MACOSX_RHAPSODY::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}::",
@@ -31,24 +30,13 @@ diff --git a/Configure b/Configure
  "debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
  # iPhoneOS/iOS
  "iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
-@@ -1685,7 +1685,7 @@
+@@ -1717,8 +1717,7 @@
                s/^CC=.*$/CC= $cc/;
                s/^AR=\s*ar/AR= $ar/;
                s/^RANLIB=.*/RANLIB= $ranlib/;
 -              s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $cc eq "gcc";
-+              s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/;
+-              s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $ecc eq "gcc" || $ecc eq "clang";
++              s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/
                }
        s/^CFLAG=.*$/CFLAG= $cflags/;
        s/^DEPFLAG=.*$/DEPFLAG=$depflags/;
-diff --git a/util/domd b/util/domd
---- a/util/domd
-+++ b/util/domd
-@@ -14,7 +14,7 @@
- cp Makefile Makefile.save
- # fake the presence of Kerberos
- touch $TOP/krb5.h
--if expr "$MAKEDEPEND" : '.*gcc$' > /dev/null; then
-+if true ; then  # was: if expr "$MAKEDEPEND" : '.*gcc$' > /dev/null; then
-     args=""
-     while [ $# -gt 0 ]; do
-       if [ "$1" != "--" ]; then args="$args $1"; fi
index fff4d5b..20982a4 100644 (file)
@@ -54,7 +54,7 @@ Thanks to the many outside volunteers who have worked under Guido's direction to
 \b0 \
 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation.\
 \
-2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\
+2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\
 \
 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python.\
 \
index 36d0a3e..0a62e32 100755 (executable)
@@ -58,7 +58,7 @@ case "${BSH}" in
        fi
        echo "" >> "${RC}"
        echo "# Setting PATH for Python ${PYVER}" >> "${RC}"
-       echo "# The orginal version is saved in .cshrc.pysave" >> "${RC}"
+       echo "# The original version is saved in .cshrc.pysave" >> "${RC}"
        echo "set path=(${PYTHON_ROOT}/bin "'$path'")" >> "${RC}"
        if [ `id -ur` = 0 ]; then
                chown "${USER}" "${RC}"
@@ -90,7 +90,7 @@ if [ -f "${PR}" ]; then
 fi
 echo "" >> "${PR}"
 echo "# Setting PATH for Python ${PYVER}" >> "${PR}"
-echo "# The orginal version is saved in `basename ${PR}`.pysave" >> "${PR}"
+echo "# The original version is saved in `basename ${PR}`.pysave" >> "${PR}"
 echo 'PATH="'"${PYTHON_ROOT}/bin"':${PATH}"' >> "${PR}"
 echo 'export PATH' >> "${PR}"
 if [ `id -ur` = 0 ]; then
index 9538c06..f7c3b35 100644 (file)
@@ -36,7 +36,7 @@
        <key>CFBundleExecutable</key>
        <string>IDLE</string>
        <key>CFBundleGetInfoString</key>
-       <string>%version%, © 2001-2015 Python Software Foundation</string>
+       <string>%version%, © 2001-2016 Python Software Foundation</string>
        <key>CFBundleIconFile</key>
        <string>IDLE.icns</string>
        <key>CFBundleIdentifier</key>
index b4ade1d..4a5eeb5 100644 (file)
@@ -40,7 +40,7 @@
        <key>CFBundleExecutable</key>
        <string>Python Launcher</string>
        <key>CFBundleGetInfoString</key>
-       <string>%VERSION%, © 2001-2015 Python Software Foundation</string>
+       <string>%VERSION%, © 2001-2016 Python Software Foundation</string>
        <key>CFBundleIconFile</key>
        <string>PythonLauncher.icns</string>
        <key>CFBundleIdentifier</key>
index d9622a6..07f09fa 100644 (file)
@@ -46,12 +46,17 @@ OS X specific arguments to configure
   The optional argument specifies which OS X SDK should be used to perform the
   build.  If xcodebuild is available and configured, this defaults to
   the Xcode default MacOS X SDK, otherwise ``/Developer/SDKs/MacOSX.10.4u.sdk``
-  if available or ``/`` if not.
+  if available or ``/`` if not.  When building on OS X 10.5 or later, you can
+  specify ``/`` to use the installed system headers rather than an SDK.  As of
+  OS X 10.9, you should install the optional system headers from the Command
+  Line Tools component using ``xcode-select``::
+
+     $ sudo xcode-select --install
 
   See the section _`Building and using a universal binary of Python on Mac OS X`
   for more information.
 
-* ``--with-univeral-archs=VALUE``
+* ``--with-universal-archs=VALUE``
 
   Specify the kind of universal binary that should be created. This option is
   only valid when ``--enable-universalsdk`` is specified.  The default is
@@ -121,7 +126,7 @@ values are available:
 
 To build a universal binary that includes a 64-bit architecture, you must build
 on a system running OS X 10.5 or later.  The ``all`` and ``64-bit`` flavors can
-only be built with an 10.5 SDK because ``ppc64`` support was only included with
+only be built with a 10.5 SDK because ``ppc64`` support was only included with
 OS X 10.5.  Although legacy ``ppc`` support was included with Xcode 3 on OS X
 10.6, it was removed in Xcode 4, versions of which were released on OS X 10.6
 and which is the standard for OS X 10.7.  To summarize, the
index cb7e8d7..a0bb971 100644 (file)
@@ -20,7 +20,7 @@
        <key>CFBundleExecutable</key>
        <string>Python</string>
        <key>CFBundleGetInfoString</key>
-       <string>%version%, (c) 2001-2015 Python Software Foundation.</string>
+       <string>%version%, (c) 2001-2016 Python Software Foundation.</string>
        <key>CFBundleHelpBookFolder</key>
        <array>
                <string>Documentation</string>
@@ -37,7 +37,7 @@
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>%version%, (c) 2001-2015 Python Software Foundation.</string>
+       <string>%version%, (c) 2001-2016 Python Software Foundation.</string>
        <key>CFBundleName</key>
        <string>Python</string>
        <key>CFBundlePackageType</key>
@@ -55,7 +55,7 @@
        <key>NSAppleScriptEnabled</key>
        <true/>
        <key>NSHumanReadableCopyright</key>
-       <string>(c) 2001-2015 Python Software Foundation.</string>
+       <string>(c) 2001-2016 Python Software Foundation.</string>
        <key>NSHighResolutionCapable</key>
        <true/>
 </dict>
index a97cc1f..fcba7d9 100644 (file)
@@ -17,9 +17,9 @@
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>%VERSION%, (c) 2001-2015 Python Software Foundation.</string>
+       <string>%VERSION%, (c) 2001-2016 Python Software Foundation.</string>
        <key>CFBundleLongVersionString</key>
-       <string>%VERSION%, (c) 2001-2015 Python Software Foundation.</string>
+       <string>%VERSION%, (c) 2001-2016 Python Software Foundation.</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 823def3..87528a0 100644 (file)
@@ -221,6 +221,7 @@ LIBOBJS=    @LIBOBJS@
 PYTHON=                python$(EXE)
 BUILDPYTHON=   python$(BUILDEXE)
 
+cross_compiling=@cross_compiling@
 PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@
 _PYTHON_HOST_PLATFORM=@_PYTHON_HOST_PLATFORM@
 BUILD_GNU_TYPE=        @build@
@@ -230,8 +231,10 @@ HOST_GNU_TYPE=     @host@
 TCLTK_INCLUDES=        @TCLTK_INCLUDES@
 TCLTK_LIBS=    @TCLTK_LIBS@
 
-# The task to run while instrument when building the profile-opt target
-PROFILE_TASK=-m test.regrtest --pgo
+# The task to run while instrumented when building the profile-opt target.
+# We exclude unittests with -x that take a rediculious amount of time to
+# run in the instrumented training build or do not provide much value.
+PROFILE_TASK=-m test.regrtest --pgo -x test_asyncore test_gdb test_multiprocessing_fork test_multiprocessing_forkserver test_multiprocessing_main_handling test_multiprocessing_spawn test_subprocess
 
 # report files for gcov / lcov coverage report
 COVERAGE_INFO= $(abs_builddir)/coverage.info
@@ -483,7 +486,7 @@ build_all:  $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks Programs/_testembed
 
 # Compile a binary with profile guided optimization.
 profile-opt:
-       @if [ $(LLVM_PROF_ERR) == yes ]; then \
+       @if [ $(LLVM_PROF_ERR) = yes ]; then \
                echo "Error: Cannot perform PGO build because llvm-profdata was not found in PATH" ;\
                echo "Please add it to PATH and run ./configure again" ;\
                exit 1;\
@@ -502,7 +505,7 @@ profile-opt:
        $(MAKE) profile-removal
 
 build_all_generate_profile:
-       $(MAKE) all CFLAGS_NODIST="$(CFLAGS) $(PGO_PROF_GEN_FLAG)" LDFLAGS="$(LDFLAGS) $(PGO_PROF_GEN_FLAG)" LIBS="$(LIBS)"
+       $(MAKE) all CFLAGS_NODIST="$(CFLAGS) $(PGO_PROF_GEN_FLAG) @LTOFLAGS@" LDFLAGS="$(LDFLAGS) $(PGO_PROF_GEN_FLAG) @LTOFLAGS@" LIBS="$(LIBS)"
 
 run_profile_task:
        : # FIXME: can't run for a cross build
@@ -512,7 +515,7 @@ build_all_merge_profile:
        $(LLVM_PROF_MERGER)
 
 build_all_use_profile:
-       $(MAKE) all CFLAGS_NODIST="$(CFLAGS) $(PGO_PROF_USE_FLAG)"
+       $(MAKE) all CFLAGS_NODIST="$(CFLAGS) $(PGO_PROF_USE_FLAG) @LTOFLAGS@" LDFLAGS="$(LDFLAGS) @LTOFLAGS@"
 
 # Compile and run with gcov
 .PHONY=coverage coverage-lcov coverage-report
@@ -586,11 +589,15 @@ pybuilddir.txt: $(BUILDPYTHON)
                exit 1 ; \
        fi
 
+# This is shared by the math and cmath modules
+Modules/_math.o: Modules/_math.c Modules/_math.h
+       $(CC) -c $(CCSHARED) $(PY_CORE_CFLAGS) -o $@ $<
+
 # Build the shared modules
 # Under GNU make, MAKEFLAGS are sorted and normalized; the 's' for
 # -s, --silent or --quiet is always the first char.
 # Under BSD make, MAKEFLAGS might be " -s -v x=y".
-sharedmods: $(BUILDPYTHON) pybuilddir.txt
+sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o
        @case "$$MAKEFLAGS" in \
            *\ -s*|s*) quiet="-q";; \
            *) quiet="";; \
@@ -712,12 +719,16 @@ Programs/_freeze_importlib: Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FRO
        $(LINKCC) $(PY_LDFLAGS) -o $@ Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
 
 Python/importlib_external.h: $(srcdir)/Lib/importlib/_bootstrap_external.py Programs/_freeze_importlib
-       ./Programs/_freeze_importlib \
-               $(srcdir)/Lib/importlib/_bootstrap_external.py Python/importlib_external.h
+       if test "$(cross_compiling)" != "yes"; then \
+           ./Programs/_freeze_importlib \
+               $(srcdir)/Lib/importlib/_bootstrap_external.py Python/importlib_external.h; \
+       fi
 
 Python/importlib.h: $(srcdir)/Lib/importlib/_bootstrap.py Programs/_freeze_importlib
-       ./Programs/_freeze_importlib \
-               $(srcdir)/Lib/importlib/_bootstrap.py Python/importlib.h
+       if test "$(cross_compiling)" != "yes"; then \
+           ./Programs/_freeze_importlib \
+               $(srcdir)/Lib/importlib/_bootstrap.py Python/importlib.h; \
+       fi
 
 
 ############################################################################
@@ -778,10 +789,21 @@ Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile
 $(IO_OBJS): $(IO_H)
 
 $(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGEN)
-               @$(MKDIR_P) Include
-               $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
+       @$(MKDIR_P) Include
+       # Avoid copying the file onto itself for an in-tree build
+       if test "$(cross_compiling)" != "yes"; then \
+               $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C); \
+       else \
+               cp $(srcdir)/Include/graminit.h $(GRAMMAR_H).tmp; \
+               mv $(GRAMMAR_H).tmp $(GRAMMAR_H); \
+       fi
 $(GRAMMAR_C): $(GRAMMAR_H)
-               touch $(GRAMMAR_C)
+       if test "$(cross_compiling)" != "yes"; then \
+               touch $(GRAMMAR_C); \
+       else \
+               cp $(srcdir)/Python/graminit.c $(GRAMMAR_C).tmp; \
+               mv $(GRAMMAR_C).tmp $(GRAMMAR_C); \
+       fi
 
 $(PGEN): $(PGENOBJS)
                $(CC) $(OPT) $(PY_LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
@@ -1110,6 +1132,10 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@
        fi
 
 bininstall: altbininstall
+       if test ! -d $(DESTDIR)$(LIBPC); then \
+               echo "Creating directory $(LIBPC)"; \
+               $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(LIBPC); \
+       fi
        -if test -f $(DESTDIR)$(BINDIR)/python3$(EXE) -o -h $(DESTDIR)$(BINDIR)/python3$(EXE); \
        then rm -f $(DESTDIR)$(BINDIR)/python3$(EXE); \
        else true; \
@@ -1429,7 +1455,7 @@ sharedinstall: sharedmods
 # the Makefile in Mac
 #
 #
-# This target is here for backward compatiblity, previous versions of Python
+# This target is here for backward compatibility, previous versions of Python
 # hadn't integrated framework installation in the normal install process.
 frameworkinstall: install
 
@@ -1588,6 +1614,7 @@ clean: pycremoval
 profile-removal:
        find . -name '*.gc??' -exec rm -f {} ';'
        find . -name '*.profclang?' -exec rm -f {} ';'
+       find . -name '*.dyn' -exec rm -f {} ';'
        rm -f $(COVERAGE_INFO)
        rm -rf $(COVERAGE_REPORT)
 
index 1102ff3..632c85c 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -50,8 +50,8 @@ Fabrice Aneche
 Juancarlo Añez
 Chris Angelico
 Jérémy Anger
-Ankur Ankan
 Jon Anglin
+Ankur Ankan
 Heidi Annexstad
 Ramchandra Apte
 Éric Araujo
@@ -90,6 +90,7 @@ Matthew Barnett
 Richard Barran
 Cesar Eduardo Barros
 Des Barry
+Emanuel Barry
 Ulf Bartelt
 Campbell Barton
 Don Bashford
@@ -101,6 +102,7 @@ Michael R Bax
 Anthony Baxter
 Mike Bayer
 Samuel L. Bayer
+Tommy Beadle
 Donald Beaudry
 David Beazley
 John Beck
@@ -109,6 +111,7 @@ Neal Becker
 Robin Becker
 Torsten Becker
 Bill Bedford
+Michał Bednarski
 Ian Beer
 Stefan Behnel
 Reimer Behrends
@@ -172,8 +175,9 @@ Monty Brandenberg
 Georg Brandl
 Christopher Brannon
 Terrence Brannon
-Germán M. Bravo
+Erin Braswell
 Sven Brauch
+Germán M. Bravo
 Erik Bray
 Brian Brazil
 Demian Brecht
@@ -196,6 +200,7 @@ Ian Bruntlett
 Floris Bruynooghe
 Matt Bryant
 Stan Bubrouski
+Colm Buckley
 Erik de Bueger
 Jan-Hein Bührman
 Lars Buitinck
@@ -210,6 +215,7 @@ Tarn Weisner Burton
 Lee Busby
 Katherine Busch
 Ralph Butler
+Laurent De Buyst
 Zach Byrne
 Nicolas Cadou
 Jp Calderone
@@ -289,8 +295,8 @@ David M. Cooke
 Jason R. Coombs
 Garrett Cooper
 Greg Copeland
-Aldo Cortesi
 Ian Cordasco
+Aldo Cortesi
 David Costanzo
 Scott Cotton
 Greg Couch
@@ -372,8 +378,8 @@ Virgil Dupras
 Bruno Dupuis
 Andy Dustman
 Gary Duzan
-Karmen Dykstra
 Eugene Dvurechenski
+Karmen Dykstra
 Josip Dzolonga
 Maxim Dzumanenko
 Walter Dörwald
@@ -392,6 +398,7 @@ Lance Ellinghaus
 Daniel Ellis
 Phil Elson
 David Ely
+Victor van den Elzen
 Jeff Epler
 Tom Epperly
 Gökcen Eraslan
@@ -442,6 +449,7 @@ Arnaud Fontaine
 Michael Foord
 Amaury Forgeot d'Arc
 Doug Fort
+Evens Fortuné
 Chris Foster
 John Fouhy
 Andrew Francis
@@ -450,6 +458,7 @@ Stefan Franke
 Martin Franklin
 Kent Frazier
 Bruce Frederiksen
+Jason Fried
 Robin Friedrich
 Bradley Froehle
 Ivan Frohne
@@ -475,12 +484,14 @@ Raymund Galvin
 Nitin Ganatra
 Fred Gansevles
 Lars Marius Garshol
+Jake Garver
 Dan Gass
 Andrew Gaul
 Matthieu Gautier
 Stephen M. Gava
 Xavier de Gaye
 Harry Henry Gebel
+Tamás Bence Gedai
 Marius Gedminas
 Jan-Philip Gehrcke
 Thomas Gellekum
@@ -642,6 +653,7 @@ Catalin Iacob
 Mihai Ibanescu
 Ali Ikinci
 Aaron Iles
+Thomas Ilsche
 Lars Immisch
 Bobby Impollonia
 Naoki Inada
@@ -663,6 +675,7 @@ Kjetil Jacobsen
 Bertrand Janin
 Geert Jansen
 Jack Jansen
+Hans-Peter Jansen
 Bill Janssen
 Thomas Jarosch
 Juhana Jauhiainen
@@ -676,8 +689,8 @@ Flemming Kjær Jensen
 Philip H. Jensen
 Philip Jenvey
 MunSic Jeong
-Joe Jevnik
 Chris Jerdonek
+Joe Jevnik
 Jim Jewett
 Pedro Diaz Jimenez
 Orjan Johansen
@@ -759,15 +772,17 @@ Pat Knight
 Jeff Knupp
 Kubilay Kocak
 Greg Kochanski
+Manvisha Kodali
 Damon Kohler
 Marko Kohtala
 Vajrasky Kok
 Guido Kollerie
 Jacek Konieczny
-Марк Коренберг
 Arkady Koplyarov
 Peter A. Koren
+Марк Коренберг
 Vlad Korolev
+Susumu Koshiba
 Joseph Koshy
 Daniel Kozan
 Jerzy Kozera
@@ -787,6 +802,7 @@ Steven Kryskalla
 Andrew Kuchling
 Dave Kuhlman
 Jon Kuhn
+Upendra Kumar
 Toshio Kuratomi
 Ilia Kurenkov
 Vladimir Kushnir
@@ -809,6 +825,7 @@ Soren Larsen
 Amos Latteier
 Piers Lauder
 Ben Laurie
+Yoni Lavi
 Simon Law
 Julia Lawall
 Chris Lawrence
@@ -867,6 +884,7 @@ Mirko Liss
 Nick Lockwood
 Stephanie Lockwood
 Hugo Lopes Tavares
+Guillermo López-Anglada
 Anne Lord
 Tom Loredo
 Justin Love
@@ -874,6 +892,7 @@ Ned Jackson Lovely
 Peter Lovett
 Chalmer Lowe
 Jason Lowe
+Martin von Löwis
 Tony Lownds
 Ray Loyzaga
 Kang-Hao (Kenny) Lu
@@ -885,8 +904,6 @@ Mark Lutz
 Taras Lyapun
 Jim Lynch
 Mikael Lyngvig
-Martin von Löwis
-Guillermo López-Anglada
 Jeff MacDonald
 John Machin
 Andrew I MacIntyre
@@ -911,9 +928,9 @@ Sven Marnach
 Alex Martelli
 Anthony Martin
 Owen Martin
+Sidney San Martín
 Westley Martínez
 Sébastien Martini
-Sidney San Martín
 Roger Masse
 Nick Mathewson
 Simon Mathieu
@@ -950,16 +967,16 @@ Lucas Prado Melo
 Ezio Melotti
 Doug Mennella
 Brian Merrell
+Alexis Métaireau
 Luke Mewburn
 Carl Meyer
 Mike Meyer
 Piotr Meyer
-Alexis Métaireau
 Steven Miale
-Trent Mick
 Jason Michalski
 Franck Michea
 Vincent Michel
+Trent Mick
 Tom Middleton
 Thomas Miedema
 Stan Mihai
@@ -986,6 +1003,7 @@ Peter Moody
 Paul Moore
 Ross Moore
 Ben Morgan
+Emily Morehouse
 Derek Morr
 James A Morrison
 Martin Morrison
@@ -1004,6 +1022,7 @@ Louis Munro
 R. David Murray
 Matti Mäki
 Jörg Müller
+Kaushik N
 Dale Nagata
 John Nagle
 Takahiro Nakayama
@@ -1034,6 +1053,7 @@ Neal Norwitz
 Mikhail Novikov
 Michal Nowikowski
 Steffen Daode Nurpmeso
+Thomas Nyberg
 Nigel O'Brian
 John O'Connor
 Kevin O'Connor
@@ -1060,15 +1080,18 @@ Oleg Oshmyan
 Denis S. Otkidach
 Peter Otten
 Michael Otteneder
-R. M. Oudkerk
+Richard Oudkerk
 Russel Owen
 Joonas Paalasmaa
 Martin Packman
 Shriphani Palakodety
+Julien Palard
+Aviv Palivoda
 Ondrej Palkovsky
 Mike Pall
 Todd R. Palmer
 Juan David Ibáñez Palomar
+Nicola Palumbo
 Jan Palus
 Yongzhi Pan
 Martin Panter
@@ -1078,6 +1101,7 @@ M. Papillon
 Peter Parente
 Alexandre Parenteau
 Dan Parisien
+HyeSoo Park
 William Park
 Claude Paroz
 Heikki Partanen
@@ -1102,6 +1126,7 @@ Gabriel de Perthuis
 Tim Peters
 Benjamin Peterson
 Joe Peterson
+Ulrich Petri
 Chris Petrilli
 Roumen Petrov
 Bjorn Pettersen
@@ -1112,6 +1137,7 @@ Geoff Philbrick
 Gavrie Philipson
 Adrian Phillips
 Christopher J. Phoenix
+James Pickering
 Neale Pickett
 Jim St. Pierre
 Dan Pierson
@@ -1120,8 +1146,8 @@ Anand B. Pillai
 François Pinard
 Tom Pinckney
 Zach Pincus
-Zero Piraeus
 Michael Piotrowski
+Zero Piraeus
 Antoine Pitrou
 Jean-François Piéronne
 Oleg Plakhotnyuk
@@ -1142,6 +1168,7 @@ Florian Preinstorfer
 Amrit Prem
 Paul Prescod
 Donovan Preston
+Eric Price
 Paul Price
 Iuliia Proskurnia
 Dorian Pula
@@ -1149,9 +1176,9 @@ Jyrki Pulliainen
 Steve Purcell
 Eduardo Pérez
 Fernando Pérez
+Kevin Jing Qiu
 Pierre Quentel
 Brian Quinlan
-Kevin Jing Qiu
 Anders Qvist
 Thomas Rachel
 Ram Rachum
@@ -1160,6 +1187,7 @@ Burton Radons
 Abhilash Raj
 Shorya Raj
 Jeff Ramnani
+Varpu Rantala
 Brodie Rao
 Senko Rasic
 Antti Rasinen
@@ -1187,9 +1215,9 @@ Antoine Reversat
 Flávio Ribeiro
 Francesco Ricciardi
 Tim Rice
+Martin Richard
 Jan Pieter Riegel
 Armin Rigo
-Martin Richard
 Arc Riley
 Nicholas Riley
 Jean-Claude Rimbault
@@ -1205,6 +1233,8 @@ Ben Roberts
 Mark Roberts
 Andy Robinson
 Jim Robinson
+Yolanda Robla
+Daniel Rocco
 Mark Roddy
 Kevin Rodgers
 Sean Rodman
@@ -1221,6 +1251,7 @@ Mark Roseman
 Josh Rosenberg
 Jim Roskind
 Brian Rosner
+Ignacio Rossi
 Guido van Rossum
 Just van Rossum
 Hugo van Rossum
@@ -1266,7 +1297,6 @@ Hugh Sasse
 Bob Savage
 Dave Sawyer
 Ben Sayer
-sbt
 Luca Sbardella
 Marco Scataglini
 Andrew Schaaf
@@ -1282,6 +1312,7 @@ Ralf Schmitt
 Michael Schneider
 Peter Schneider-Kamp
 Arvin Schnell
+Nofar Schnider
 Scott Schram
 Robin Schreiber
 Chad J. Schroeder
@@ -1306,11 +1337,13 @@ Pete Sevander
 Denis Severson
 Ian Seyer
 Dmitry Shachnev
+Anish Shah
 Daniel Shahaf
-Ha Shao
 Mark Shannon
+Ha Shao
 Richard Shapiro
 Varun Sharma
+Daniel Shaulov
 Vlad Shcherbina
 Justin Sheehy
 Charlie Shepherd
@@ -1358,6 +1391,7 @@ Nir Soffer
 Paul Sokolovsky
 Evgeny Sologubov
 Cody Somerville
+Anthony Sottile
 Edoardo Spadolini
 Geoffrey Spear
 Clay Spence
@@ -1489,6 +1523,7 @@ Dmitry Vasiliev
 Sebastian Ortiz Vasquez
 Alexandre Vassalotti
 Nadeem Vawda
+Sye van der Veen
 Frank Vercruesse
 Mike Verdone
 Jaap Vermeulen
@@ -1507,9 +1542,10 @@ Johannes Vogel
 Michael Vogt
 Radu Voicilas
 Alex Volkov
+Guido Vranken
 Martijn Vries
 Sjoerd de Vries
-Guido Vranken
+Jonas Wagner
 Daniel Wagner-Hall
 Niki W. Waibel
 Wojtek Walczak
@@ -1518,11 +1554,12 @@ Richard Walker
 Larry Wall
 Kevin Walzer
 Rodrigo Steinmuller Wanderley
+Dingyuan Wang
 Ke Wang
+Liang-Bo Wang
 Greg Ward
 Tom Wardill
 Zachary Ware
-Jonas Wagner
 Barry Warsaw
 Steve Waterbury
 Bob Watson
@@ -1549,6 +1586,7 @@ Felix Wiemann
 Gerry Wiener
 Frank Wierzbicki
 Santoso Wijaya
+Chris Wilcox
 Bryce "Zooko" Wilcox-O'Hearn
 Timothy Wild
 Jakub Wilk
@@ -1559,6 +1597,7 @@ Sue Williams
 Carol Willing
 Steven Willis
 Frank Willison
+Alex Willmer
 David Wilson
 Geoff Wilson
 Greg V. Wilson
@@ -1591,8 +1630,8 @@ Doug Wyatt
 Xiang Zhang
 Robert Xiao
 Florent Xicluna
-Hirokazu Yamamoto
 Arnon Yaari
+Hirokazu Yamamoto
 Ka-Ping Yee
 Jason Yeo
 EungJun Yi
@@ -1619,7 +1658,4 @@ Tarek Ziadé
 Gennadiy Zlobin
 Doug Zongker
 Peter Åstrand
-Ignacio Rossi
-Laurent De Buyst
-Nicola Palumbo
 evilzero
index 5e5bc60..6782333 100644 (file)
@@ -187,7 +187,7 @@ Library
 
 - Issue #15777: Fix a refleak in _posixsubprocess.
 
-- Issue ##665194: Update `email.utils.localtime` to use datetime.astimezone and
+- Issue #665194: Update `email.utils.localtime` to use datetime.astimezone and
   correctly handle historic changes in UTC offsets.
 
 - Issue #15199: Fix JavaScript's default MIME type to application/javascript.
@@ -782,7 +782,7 @@ Library
 - Issue #15008: Implement PEP 362 "Signature Objects".
   Patch by Yury Selivanov.
 
-- Issue: #15138: base64.urlsafe_{en,de}code() are now 3-4x faster.
+- Issue #15138: base64.urlsafe_{en,de}code() are now 3-4x faster.
 
 - Issue #444582: Add shutil.which, for finding programs on the system path.
   Original patch by Erik Demaine, with later iterations by Jan Killian
@@ -1095,7 +1095,7 @@ Library
   functions to support PEP 3115 compliant dynamic class creation. Patch by
   Daniel Urban and Nick Coghlan.
 
-- Issue #13152: Allow to specify a custom tabsize for expanding tabs in
+- Issue #13152: Allow specifying a custom tabsize for expanding tabs in
   textwrap. Patch by John Feuerstein.
 
 - Issue #14721: Send the correct 'Content-length: 0' header when the body is an
@@ -1834,7 +1834,7 @@ Core and Builtins
   objects.  Initial patch by Matthias Troffaes.
 
 - Fix OSError.__init__ and OSError.__new__ so that each of them can be
-  overriden and take additional arguments (followup to issue #12555).
+  overridden and take additional arguments (followup to issue #12555).
 
 - Fix the fix for issue #12149: it was incorrect, although it had the side
   effect of appearing to resolve the issue.  Thanks to Mark Shannon for
@@ -2053,7 +2053,7 @@ Core and Builtins
   given, produce an informative error message which includes the name(s) of the
   missing arguments.
 
-- Issue #12370: Fix super with no arguments when __class__ is overriden in the
+- Issue #12370: Fix super with no arguments when __class__ is overridden in the
   class body.
 
 - Issue #12084: os.stat on Windows now works properly with relative symbolic
@@ -2234,10 +2234,10 @@ Library
   fixed.
 
 - Issue #14166: Pickler objects now have an optional ``dispatch_table``
-  attribute which allows to set custom per-pickler reduction functions.
+  attribute which allows setting custom per-pickler reduction functions.
   Patch by sbt.
 
-- Issue #14177: marshal.loads() now raises TypeError when given an unicode
+- Issue #14177: marshal.loads() now raises TypeError when given a unicode
   string.  Patch by Guilherme Gonçalves.
 
 - Issue #13550: Remove the debug machinery from the threading module: remove
@@ -2482,11 +2482,11 @@ Library
 - Issue #13591: A bug in importlib has been fixed that caused import_module
   to load a module twice.
 
-- Issue #13449 sched.scheduler.run() method has a new "blocking" parameter which
+- Issue #13449: sched.scheduler.run() method has a new "blocking" parameter which
   when set to False makes run() execute the scheduled events due to expire
   soonest (if any) and then return.  Patch by Giampaolo Rodolà.
 
-- Issue #8684 sched.scheduler class can be safely used in multi-threaded
+- Issue #8684: sched.scheduler class can be safely used in multi-threaded
   environments.  Patch by Josiah Carlson and Giampaolo Rodolà.
 
 - Alias resource.error to OSError ala PEP 3151.
@@ -3185,7 +3185,7 @@ Library
   binary mode, but ensure that the shebang is decodable from UTF-8 and from the
   encoding of the script.
 
-- Issue #8498: In socket.accept(), allow to specify 0 as a backlog value in
+- Issue #8498: In socket.accept(), allow specifying 0 as a backlog value in
   order to accept exactly one connection.  Patch by Daniel Evers.
 
 - Issue #12011: signal.signal() and signal.siginterrupt() raise an OSError,
@@ -3885,7 +3885,7 @@ Tests
 - Issue #12331: The test suite for lib2to3 can now run from an installed
   Python.
 
-- Issue #12626: In regrtest, allow to filter tests using a glob filter
+- Issue #12626: In regrtest, allow filtering tests using a glob filter
   with the ``-m`` (or ``--match``) option.  This works with all test cases
   using the unittest module.  This is useful with long test suites
   such as test_io or test_subprocess.
@@ -4221,7 +4221,7 @@ What's New in Python 3.2 Release Candidate 2?
 Core and Builtins
 -----------------
 
-- Issue #10451: memoryview objects could allow to mutate a readable buffer.
+- Issue #10451: memoryview objects could allow mutating a readable buffer.
   Initial patch by Ross Lagerwall.
 
 Library
@@ -4765,7 +4765,7 @@ Library
 
 - Add the "display" and "undisplay" pdb commands.
 
-- Issue #7245: Add a SIGINT handler in pdb that allows to break a program again
+- Issue #7245: Add a SIGINT handler in pdb that allows breaking a program again
   after a "continue" command.
 
 - Add the "interact" pdb command.
@@ -6633,7 +6633,7 @@ C-API
   PyErr_Format, on machines with HAVE_LONG_LONG defined.
 
 - Issue #6151: Made PyDescr_COMMON conform to standard C (like PyObject_HEAD in
-  PEP 3123).  The PyDescr_TYPE and PyDescr_NAME macros should be should used for
+  PEP 3123).  The PyDescr_TYPE and PyDescr_NAME macros should be used for
   accessing the d_type and d_name members of structures using PyDescr_COMMON.
 
 - Issue #6405: Remove duplicate type declarations in descrobject.h.
@@ -6916,7 +6916,7 @@ Library
   correct encoding.
 
 - Issue #4870: Add an `options` attribute to SSL contexts, as well as several
-  ``OP_*`` constants to the `ssl` module.  This allows to selectively disable
+  ``OP_*`` constants to the `ssl` module.  This allows selectively disabling
   protocol versions, when used in combination with `PROTOCOL_SSLv23`.
 
 - Issue #8759: Fixed user paths in sysconfig for posix and os2 schemes.
@@ -7220,7 +7220,7 @@ Library
   cElementTree module is updated too.
 
 - Issue #7774: Set sys.executable to an empty string if argv[0] has been set to
-  an non existent program name and Python is unable to retrieve the real program
+  a non existent program name and Python is unable to retrieve the real program
   name.
 
 - Issue #7880: Fix sysconfig when the python executable is a symbolic link.
@@ -7273,7 +7273,7 @@ Library
   messages parsed by email.Parser.HeaderParser.
 
 - Issue #7361: Importlib was not properly checking the number of bytes in
-  bytecode file when it was less then 8 bytes.
+  bytecode file when it was less than 8 bytes.
 
 - Issue #7633: In the decimal module, Context class methods (with the exception
   of canonical and is_canonical) now accept instances of int and long wherever a
@@ -7709,7 +7709,7 @@ Extension Modules
 
 - Issue #7900: The getgroups(2) system call on MacOSX behaves rather oddly
   compared to other unix systems. In particular, os.getgroups() does not reflect
-  any changes made using os.setgroups() but basicly always returns the same
+  any changes made using os.setgroups() but basically always returns the same
   information as the id command. os.getgroups() can now return more than 16
   groups on MacOSX.
 
@@ -7728,7 +7728,7 @@ Extension Modules
 - Issue #1578269: Implement os.symlink for Windows 6.0+.  Patch by Jason
   R. Coombs.
 
-- In struct.pack, correctly propogate exceptions from computing the truth of an
+- In struct.pack, correctly propagate exceptions from computing the truth of an
   object in the '?' format.
 
 - Issue #9000: datetime.timezone objects now have eval-friendly repr.
@@ -8215,7 +8215,7 @@ Build
   added LIBS to OS X framework builds.
 
 - Issue #5809: Specifying both --enable-framework and --enable-shared is
-  an error. Configure now explicity tells you about this.
+  an error. Configure now explicitly tells you about this.
 
 
 
@@ -8304,7 +8304,7 @@ Library
 - Issue #1664: Make nntplib IPv6-capable. Patch by Derek Morr.
 
 - Issue #5006: Better handling of unicode byte-order marks (BOM) in the io
-  library. This means, for example, that opening an UTF-16 text file in
+  library. This means, for example, that opening a UTF-16 text file in
   append mode doesn't add a BOM at the end of the file if the file isn't
   empty.
 
@@ -9209,7 +9209,7 @@ Library
   been backported to help facilitate transitions from 2.7 to 3.1.
 
 - Issue #1885: distutils. When running sdist with --formats=tar,gztar
-  the tar file was overriden by the gztar one.
+  the tar file was overridden by the gztar one.
 
 - Issue #4863: distutils.mwerkscompiler has been removed.
 
@@ -9328,7 +9328,7 @@ Library
 - Issue #4756: zipfile.is_zipfile() now supports file-like objects. Patch by
   Gabriel Genellina.
 
-- Issue #4574: reading an UTF16-encoded text file crashes if \r on 64-char
+- Issue #4574: reading a UTF16-encoded text file crashes if \r on 64-char
   boundary.
 
 - Issue #4223: inspect.getsource() will now correctly display source code
@@ -9497,8 +9497,8 @@ Extension Modules
 
 - Issue #4051: Prevent conflict of UNICODE macros in cPickle.
 
-- Issue #4738: Each zlib object now has a separate lock, allowing to compress
-  or decompress several streams at once on multi-CPU systems. Also, the GIL
+- Issue #4738: Each zlib object now has a separate lock, allowing several streams
+  to be compressed or decompressed at once on multi-CPU systems. Also, the GIL
   is now released when computing the CRC of a large buffer. Patch by ebfe.
 
 - Issue #4228: Pack negative values the same way as 2.4 in struct's L format.
@@ -9822,7 +9822,7 @@ Core and Builtins
   the recursion limit checking code, due to bogus handling of recursion
   limit when USE_STACKCHEK was enabled.
 
-- Issue 3639: The _warnings module could segfault the interpreter when
+- Issue #3639: The _warnings module could segfault the interpreter when
   unexpected types were passed in as arguments.
 
 - Issue #3712: The memoryview object had a reference leak and didn't support
@@ -9901,14 +9901,14 @@ Library
   It is now maintained outside of the standard library at
   http://www.jcea.es/programacion/pybsddb.htm.
 
-- Issue 600362:  Relocated parse_qs() and parse_qsl(), from the cgi module
+- Issue #600362:  Relocated parse_qs() and parse_qsl(), from the cgi module
   to the urlparse one.  Added a DeprecationWarning in the old module, it
   will be deprecated in the future.
 
 - Issue #3719: platform.architecture() fails if there are spaces in the
   path to the Python binary.
 
-- Issue 3602: As part of the merge of r66135, make the parameters on
+- Issue #3602: As part of the merge of r66135, make the parameters on
   warnings.catch_warnings() keyword-only. Also remove a DeprecationWarning.
 
 - The deprecation warnings for the camelCase threading API names were removed.
@@ -9929,7 +9929,7 @@ Extension Modules
   exploitation of poor argument checking.
 
 - bsddb code updated to version 4.7.3pre2. This code is the same than
-  Python 2.6 one, since the intention is to keep an unified 2.x/3.x codebase.
+  Python 2.6 one, since the intention is to keep a unified 2.x/3.x codebase.
   The Python code is automatically translated using "2to3". Please, do not
   update this code in Python 3.0 by hand. Update the 2.6 one and then
   do "2to3".
@@ -9996,7 +9996,7 @@ Core and Builtins
   as bytes string, please use PyUnicode_AsUTF8String() instead.
 
 - Issue #3460: PyUnicode_Join() implementation is 10% to 80% faster thanks
-  to Python 3.0's stricter semantics which allow to avoid successive
+  to Python 3.0's stricter semantics which allow avoiding successive
   reallocations of the result string (this also affects str.join()).
 
 
@@ -10639,8 +10639,8 @@ Core and Builtins
   certain operations between bytes/buffer and str like str(b'') and
   comparison.
 
-- The standards streams sys.stdin, stdout and stderr may be None when
-  the when the C runtime library returns an invalid file descriptor
+- The standard streams sys.stdin, stdout and stderr may be None
+  when the C runtime library returns an invalid file descriptor
   for the streams (fileno(stdin) < 0). For now this happens only for
   Windows GUI apps and scripts started with `pythonw.exe`.
 
@@ -10679,7 +10679,7 @@ Library
 
 - Removed the 'new' module.
 
-- Removed all types from the 'types' module that are easily accessable
+- Removed all types from the 'types' module that are easily accessible
   through builtins.
 
 
@@ -12762,7 +12762,7 @@ Library
 
 - Patch #1110248: SYNC_FLUSH the zlib buffer for GZipFile.flush.
 
-- Patch #1107973: Allow to iterate over the lines of a tarfile.ExFileObject.
+- Patch #1107973: Allow iterating over the lines of a tarfile.ExFileObject.
 
 - Patch #1104111: Alter setup.py --help and --help-commands.
 
@@ -13739,7 +13739,7 @@ Library
   same as when the argument is omitted).
   [SF bug 658254, patch 663482]
 
-- nntplib does now allow to ignore a .netrc file.
+- nntplib does now allow ignoring a .netrc file.
 
 - urllib2 now recognizes Basic authentication even if other authentication
   schemes are offered.
@@ -14013,7 +14013,7 @@ Core and builtins
   would not be removed while allocating a new weakref object.  Since
   GC could be invoked at that time, however, that assumption was
   invalid.  In a truly obscure case of GC being triggered during
-  creation for a new weakref object for an referent which already
+  creation for a new weakref object for a referent which already
   has a weakref without a callback which is only referenced from
   cyclic trash, a memory error can occur.  This consistently created a
   segfault in a debug build, but provided less predictable behavior in
@@ -14157,7 +14157,7 @@ Extension modules
 
 - fcntl.ioctl now warns if the mutate flag is not specified.
 
-- nt now properly allows to refer to UNC roots, e.g. in nt.stat().
+- nt now properly allows referring to UNC roots, e.g. in nt.stat().
 
 - the weakref module now supports additional objects:  array.array,
   sre.pattern_objects, file objects, and sockets.
@@ -16065,7 +16065,7 @@ Core and builtins
 - All standard iterators now ensure that, once StopIteration has been
   raised, all future calls to next() on the same iterator will also
   raise StopIteration.  There used to be various counterexamples to
-  this behavior, which could caused confusion or subtle program
+  this behavior, which could have caused confusion or subtle program
   breakage, without any benefits.  (Note that this is still an
   iterator's responsibility; the iterator framework does not enforce
   this.)
@@ -16715,7 +16715,7 @@ C API
 - New functions PyErr_SetExcFromWindowsErr() and
   PyErr_SetExcFromWindowsErrWithFilename(). Similar to
   PyErr_SetFromWindowsErrWithFilename() and
-  PyErr_SetFromWindowsErr(), but they allow to specify
+  PyErr_SetFromWindowsErr(), but they allow specifying
   the exception type to raise. Available on Windows.
 
 - Py_FatalError() is now declared as taking a const char* argument.  It
@@ -17590,8 +17590,8 @@ Type/class unification and new-style classes
 - property() now takes 4 keyword arguments:  fget, fset, fdel and doc.
   These map to read-only attributes 'fget', 'fset', 'fdel', and '__doc__'
   in the constructed property object.  fget, fset and fdel weren't
-  discoverable from Python in 2.2a3.  __doc__ is new, and allows to
-  associate a docstring with a property.
+  discoverable from Python in 2.2a3.  __doc__ is new, and allows
+  associating a docstring with a property.
 
 - Comparison overloading is now more completely implemented.  For
   example, a str subclass instance can properly be compared to a str
@@ -18006,7 +18006,7 @@ Tests
 -----
 
 - regrtest.py now knows which tests are expected to be skipped on some
-  platforms, allowing to give clearer test result output.  regrtest
+  platforms, allowing clearer test result output to be given.  regrtest
   also has optional --use/-u switch to run normally disabled tests
   which require network access or consume significant disk resources.
 
@@ -18737,7 +18737,7 @@ Standard library
 
 - xml.dom.minidom offers a toprettyxml method. A number of DOM
   conformance issues have been resolved. In particular, Element now
-  has an hasAttributes method, and the handling of namespaces was
+  has a hasAttributes method, and the handling of namespaces was
   improved.
 
 - Ka-Ping Yee contributed two new modules: inspect.py, a module for
@@ -18936,7 +18936,7 @@ Core language, builtins, and interpreter
 
 - There is a new Unicode companion to the PyObject_Str() API
   called PyObject_Unicode(). It behaves in the same way as the
-  former, but assures that the returned value is an Unicode object
+  former, but assures that the returned value is a Unicode object
   (applying the usual coercion if necessary).
 
 - The comparison operators support "rich comparison overloading" (PEP
@@ -20227,7 +20227,7 @@ list of all new modules is included below.
 
 Probably the most pervasive change is the addition of Unicode support.
 We've added a new fundamental datatype, the Unicode string, a new
-build-in function unicode(), an numerous C APIs to deal with Unicode
+built-in function unicode(), and numerous C APIs to deal with Unicode
 and encodings.  See the file Misc/unicode.txt for details, or
 http://starship.python.net/crew/lemburg/unicode-proposal.txt.
 
@@ -20921,7 +20921,7 @@ Fri Mar 26 22:36:00 1999  Fred Drake  <fdrake@eric.cnri.reston.va.us>
 
        * Tools/scripts/dutree.py:
        During display, if EPIPE is raised, it's probably because a pager was
-       killed.  Discard the error in that case, but propogate it otherwise.
+       killed.  Discard the error in that case, but propagate it otherwise.
 
 Fri Mar 26 16:20:45 1999  Guido van Rossum  <guido@eric.cnri.reston.va.us>
 
@@ -21712,7 +21712,7 @@ real list objects.
 - The uu module now deals better with trailing garbage generated by
 some broke uuencoders.
 
-- The telnet module now has an my_interact() method which uses threads
+- The telnet module now has a my_interact() method which uses threads
 instead of select.  The interact() method uses this by default on
 Windows (where the single-threaded version doesn't work).
 
@@ -22769,7 +22769,7 @@ PyEval_CallMethod().
 - New macros to access object members for PyFunction, PyCFunction
 objects.
 
-- New APIs PyImport_AppendInittab() an PyImport_ExtendInittab() to
+- New APIs PyImport_AppendInittab() and PyImport_ExtendInittab() to
 dynamically add one or many entries to the table of built-in modules.
 
 - New macro Py_InitModule3(name, methods, doc) which calls
@@ -23743,7 +23743,7 @@ the first class with an applicable hook wins.  Makes more sense.
 - Changed the checks made in Py_Initialize() and Py_Finalize().  It is
 now legal to call these more than once.  The first call to
 Py_Initialize() initializes, the first call to Py_Finalize()
-finalizes.  There's also a new API, Py_IsInitalized() which checks
+finalizes.  There's also a new API, Py_IsInitialized() which checks
 whether we are already initialized (in case you want to leave things
 as they were).
 
@@ -26799,7 +26799,7 @@ the first time it is imported.
 python parser.  Corresponding standard library modules token and symbol
 defines the numeric values of tokens and non-terminal symbols.
 
-* The posix module has aquired new functions setuid(), setgid(),
+* The posix module has acquired new functions setuid(), setgid(),
 execve(), and exec() has been renamed to execv().
 
 * The array module is extended with 8-byte object swaps, the 'i'
@@ -26813,7 +26813,7 @@ module can't be decoded by the new version.
 * For select.select(), a timeout (4th) argument of None means the same
 as leaving the timeout argument out.
 
-* Module strop (and hence standard library module string) has aquired
+* Module strop (and hence standard library module string) has acquired
 a new function: rindex().  Thanks to Amrit Prem!
 
 * Module regex defines a new function symcomp() which uses an extended
@@ -27179,7 +27179,7 @@ a string it is returned unchanged, otherwise it returns `x`.
 * repr(x) returns the same as `x`.  (Some users found it easier to
 have this as a function.)
 
-* round(x) returns the floating point number x rounded to an whole
+* round(x) returns the floating point number x rounded to a whole
 number, represented as a floating point number.  round(x, n) returns x
 rounded to n digits.
 
@@ -27959,7 +27959,7 @@ New features in 0.9.6:
   to give more useful results for negative operands
 - Changed/added range checks for long/plain integer shifts
 - Options found after "-c command" are now passed to the command in sys.argv
-  (note subtle incompatiblity with "python -c command -- -options"!)
+  (note subtle incompatibility with "python -c command -- -options"!)
 - Module stdwin is better protected against touching objects after they've
   been closed; menus can now also be closed explicitly
 - Stdwin now uses its own exception (stdwin.error)
index 0addd80..4ad2551 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,755 @@
 Python News
 +++++++++++
 
+What's New in Python 3.5.2 final?
+=================================
+
+Release date: 2016-06-26
+
+Core and Builtins
+-----------------
+
+- Issue #26930: Update Windows builds to use OpenSSL 1.0.2h.
+
+Tests
+-----
+
+- Issue #26867: Ubuntu's openssl OP_NO_SSLv3 is forced on by default; fix test.
+
+IDLE
+----
+
+- Issue #27365: Allow non-ascii in idlelib/NEWS.txt - minimal part for 3.5.2.
+
+
+What's New in Python 3.5.2 release candidate 1?
+===============================================
+
+Release date: 2016-06-12
+
+Core and Builtins
+-----------------
+
+- Issue #27066: Fixed SystemError if a custom opener (for open()) returns a
+  negative number without setting an exception.
+
+- Issue #20041: Fixed TypeError when frame.f_trace is set to None.
+  Patch by Xavier de Gaye.
+
+- Issue #26168: Fixed possible refleaks in failing Py_BuildValue() with the "N"
+  format unit.
+
+- Issue #26991: Fix possible refleak when creating a function with annotations.
+
+- Issue #27039: Fixed bytearray.remove() for values greater than 127.  Patch by
+  Joe Jevnik.
+
+- Issue #23640: int.from_bytes() no longer bypasses constructors for subclasses.
+
+- Issue #26811: gc.get_objects() no longer contains a broken tuple with NULL
+  pointer.
+
+- Issue #20120: Use RawConfigParser for .pypirc parsing,
+  removing support for interpolation unintentionally added
+  with move to Python 3. Behavior no longer does any
+  interpolation in .pypirc files, matching behavior in Python
+  2.7 and Setuptools 19.0.
+
+- Issue #26659: Make the builtin slice type support cycle collection.
+
+- Issue #26718: super.__init__ no longer leaks memory if called multiple times.
+  NOTE: A direct call of super.__init__ is not endorsed!
+
+- Issue #25339: PYTHONIOENCODING now has priority over locale in setting the
+  error handler for stdin and stdout.
+
+- Issue #26494: Fixed crash on iterating exhausting iterators.
+  Affected classes are generic sequence iterators, iterators of str, bytes,
+  bytearray, list, tuple, set, frozenset, dict, OrderedDict, corresponding
+  views and os.scandir() iterator.
+
+- Issue #26581: If coding cookie is specified multiple times on a line in
+  Python source code file, only the first one is taken to account.
+
+- Issue #26464: Fix str.translate() when string is ASCII and first replacements
+  removes character, but next replacement uses a non-ASCII character or a
+  string longer than 1 character. Regression introduced in Python 3.5.0.
+
+- Issue #22836: Ensure exception reports from PyErr_Display() and
+  PyErr_WriteUnraisable() are sensible even when formatting them produces
+  secondary errors.  This affects the reports produced by
+  sys.__excepthook__() and when __del__() raises an exception.
+
+- Issue #26302: Correct behavior to reject comma as a legal character for
+  cookie names.
+
+- Issue #4806: Avoid masking the original TypeError exception when using star
+  (*) unpacking in function calls.  Based on patch by Hagen Fürstenau and
+  Daniel Urban.
+
+- Issue #27138: Fix the doc comment for FileFinder.find_spec().
+
+- Issue #26154: Add a new private _PyThreadState_UncheckedGet() function to get
+  the current Python thread state, but don't issue a fatal error if it is NULL.
+  This new function must be used instead of accessing directly the
+  _PyThreadState_Current variable.  The variable is no more exposed since
+  Python 3.5.1 to hide the exact implementation of atomic C types, to avoid
+  compiler issues.
+
+- Issue #26194:  Deque.insert() gave odd results for bounded deques that had
+  reached their maximum size.  Now an IndexError will be raised when attempting
+  to insert into a full deque.
+
+- Issue #25843: When compiling code, don't merge constants if they are equal
+  but have a different types. For example, ``f1, f2 = lambda: 1, lambda: 1.0``
+  is now correctly compiled to two different functions: ``f1()`` returns ``1``
+  (``int``) and ``f2()`` returns ``1.0`` (``int``), even if ``1`` and ``1.0``
+  are equal.
+
+- Issue #22995: [UPDATE] Comment out the one of the pickleability tests in
+  _PyObject_GetState() due to regressions observed in Cython-based projects.
+
+- Issue #25961: Disallowed null characters in the type name.
+
+- Issue #25973: Fix segfault when an invalid nonlocal statement binds a name
+  starting with two underscores.
+
+- Issue #22995: Instances of extension types with a state that aren't
+  subclasses of list or dict and haven't implemented any pickle-related
+  methods (__reduce__, __reduce_ex__, __getnewargs__, __getnewargs_ex__,
+  or __getstate__), can no longer be pickled.  Including memoryview.
+
+- Issue #20440: Massive replacing unsafe attribute setting code with special
+  macro Py_SETREF.
+
+- Issue #25766: Special method __bytes__() now works in str subclasses.
+
+- Issue #25421: __sizeof__ methods of builtin types now use dynamic basic size.
+  This allows sys.getsize() to work correctly with their subclasses with
+  __slots__ defined.
+
+- Issue #25709: Fixed problem with in-place string concatenation and utf-8 cache.
+
+- Issue #27147: Mention PEP 420 in the importlib docs.
+
+- Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside
+  __getattr__.
+
+- Issue #24731: Fixed crash on converting objects with special methods
+  __bytes__, __trunc__, and __float__ returning instances of subclasses of
+  bytes, int, and float to subclasses of bytes, int, and float correspondingly.
+
+- Issue #26478: Fix semantic bugs when using binary operators with dictionary
+  views and tuples.
+
+- Issue #26171: Fix possible integer overflow and heap corruption in
+  zipimporter.get_data().
+
+- Issue #25660: Fix TAB key behaviour in REPL with readline.
+
+- Issue #25887: Raise a RuntimeError when a coroutine object is awaited
+  more than once.
+
+- Issue #27243: Update the __aiter__ protocol: instead of returning
+  an awaitable that resolves to an asynchronous iterator, the asynchronous
+  iterator should be returned directly.  Doing the former will trigger a
+  PendingDeprecationWarning.
+
+
+Library
+-------
+
+- Issue #26556: Update expat to 2.1.1, fixes CVE-2015-1283.
+
+- Fix TLS stripping vulnerability in smptlib, CVE-2016-0772.  Reported by Team
+  Oststrom
+
+- Issue #21386: Implement missing IPv4Address.is_global property.  It was
+  documented since 07a5610bae9d.  Initial patch by Roger Luethi.
+
+- Issue #20900: distutils register command now decodes HTTP responses
+  correctly.  Initial patch by ingrid.
+
+- A new version of typing.py provides several new classes and
+  features: @overload outside stubs, Reversible, DefaultDict, Text,
+  ContextManager, Type[], NewType(), TYPE_CHECKING, and numerous bug
+  fixes (note that some of the new features are not yet implemented in
+  mypy or other static analyzers).  Also classes for PEP 492
+  (Awaitable, AsyncIterable, AsyncIterator) have been added (in fact
+  they made it into 3.5.1 but were never mentioned).
+
+- Issue #25738: Stop http.server.BaseHTTPRequestHandler.send_error() from
+  sending a message body for 205 Reset Content.  Also, don't send Content
+  header fields in responses that don't have a body.  Patch by Susumu
+  Koshiba.
+
+- Issue #21313: Fix the "platform" module to tolerate when sys.version
+  contains truncated build information.
+
+- Issue #26839: On Linux, :func:`os.urandom` now calls ``getrandom()`` with
+  ``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom
+  entropy pool is not initialized yet. Patch written by Colm Buckley.
+
+- Issue #27164: In the zlib module, allow decompressing raw Deflate streams
+  with a predefined zdict.  Based on patch by Xiang Zhang.
+
+- Issue #24291: Fix wsgiref.simple_server.WSGIRequestHandler to completely
+  write data to the client.  Previously it could do partial writes and
+  truncate data.  Also, wsgiref.handler.ServerHandler can now handle stdout
+  doing partial writes, but this is deprecated.
+
+- Issue #26809: Add ``__all__`` to :mod:`string`.  Patch by Emanuel Barry.
+
+- Issue #26373: subprocess.Popen.communicate now correctly ignores
+  BrokenPipeError when the child process dies before .communicate()
+  is called in more/all circumstances.
+
+- Issue #21776: distutils.upload now correctly handles HTTPError.
+  Initial patch by Claudiu Popa.
+
+- Issue #27114: Fix SSLContext._load_windows_store_certs fails with
+  PermissionError
+
+- Issue #18383: Avoid creating duplicate filters when using filterwarnings
+  and simplefilter.  Based on patch by Alex Shkop.
+
+- Issue #27057: Fix os.set_inheritable() on Android, ioctl() is blocked by
+  SELinux and fails with EACCESS. The function now falls back to fcntl().
+  Patch written by Michał Bednarski.
+
+- Issue #27014: Fix infinite recursion using typing.py.  Thanks to Kalle Tuure!
+
+- Issue #14132: Fix urllib.request redirect handling when the target only has
+  a query string.  Original fix by Ján Janech.
+
+- Issue #17214: The "urllib.request" module now percent-encodes non-ASCII
+  bytes found in redirect target URLs.  Some servers send Location header
+  fields with non-ASCII bytes, but "http.client" requires the request target
+  to be ASCII-encodable, otherwise a UnicodeEncodeError is raised.  Based on
+  patch by Christian Heimes.
+
+- Issue #26892: Honor debuglevel flag in urllib.request.HTTPHandler. Patch
+  contributed by Chi Hsuan Yen.
+
+- Issue #22274: In the subprocess module, allow stderr to be redirected to
+  stdout even when stdout is not redirected.  Patch by Akira Li.
+
+- Issue #26807: mock_open 'files' no longer error on readline at end of file.
+  Patch from Yolanda Robla.
+
+- Issue #25745: Fixed leaking a userptr in curses panel destructor.
+
+- Issue #26977: Removed unnecessary, and ignored, call to sum of squares helper
+  in statistics.pvariance.
+
+- Issue #26881: The modulefinder module now supports extended opcode arguments.
+
+- Issue #23815: Fixed crashes related to directly created instances of types in
+  _tkinter and curses.panel modules.
+
+- Issue #17765: weakref.ref() no longer silently ignores keyword arguments.
+  Patch by Georg Brandl.
+
+- Issue #26873: xmlrpc now raises ResponseError on unsupported type tags
+  instead of silently return incorrect result.
+
+- Issue #26711: Fixed the comparison of plistlib.Data with other types.
+
+- Issue #24114: Fix an uninitialized variable in `ctypes.util`.
+
+  The bug only occurs on SunOS when the ctypes implementation searches
+  for the `crle` program.  Patch by Xiang Zhang.  Tested on SunOS by
+  Kees Bos.
+
+- Issue #26864: In urllib.request, change the proxy bypass host checking
+  against no_proxy to be case-insensitive, and to not match unrelated host
+  names that happen to have a bypassed hostname as a suffix.  Patch by Xiang
+  Zhang.
+
+- Issue #26634: recursive_repr() now sets __qualname__ of wrapper.  Patch by
+  Xiang Zhang.
+
+- Issue #26804: urllib.request will prefer lower_case proxy environment
+  variables over UPPER_CASE or Mixed_Case ones. Patch contributed by Hans-Peter
+  Jansen.
+
+- Issue #26837: assertSequenceEqual() now correctly outputs non-stringified
+  differing items (like bytes in the -b mode).  This affects assertListEqual()
+  and assertTupleEqual().
+
+- Issue #26041: Remove "will be removed in Python 3.7" from deprecation
+  messages of platform.dist() and platform.linux_distribution().
+  Patch by Kumaripaba Miyurusara Athukorala.
+
+- Issue #26822: itemgetter, attrgetter and methodcaller objects no longer
+  silently ignore keyword arguments.
+
+- Issue #26733: Disassembling a class now disassembles class and static methods.
+  Patch by Xiang Zhang.
+
+- Issue #26801: Fix error handling in :func:`shutil.get_terminal_size`, catch
+  :exc:`AttributeError` instead of :exc:`NameError`. Patch written by Emanuel
+  Barry.
+
+- Issue #24838: tarfile's ustar and gnu formats now correctly calculate name
+  and link field limits for multibyte character encodings like utf-8.
+
+- Issue #26657: Fix directory traversal vulnerability with http.server on
+  Windows.  This fixes a regression that was introduced in 3.3.4rc1 and
+  3.4.0rc1.  Based on patch by Philipp Hagemeister.
+
+- Issue #26717: Stop encoding Latin-1-ized WSGI paths with UTF-8.  Patch by
+  Anthony Sottile.
+
+- Issue #26735: Fix :func:`os.urandom` on Solaris 11.3 and newer when reading
+  more than 1,024 bytes: call ``getrandom()`` multiple times with a limit of
+  1024 bytes per call.
+
+- Issue #16329: Add .webm to mimetypes.types_map.  Patch by Giampaolo Rodola'.
+
+- Issue #13952: Add .csv to mimetypes.types_map.  Patch by Geoff Wilson.
+
+- Issue #26709: Fixed Y2038 problem in loading binary PLists.
+
+- Issue #23735: Handle terminal resizing with Readline 6.3+ by installing our
+  own SIGWINCH handler.  Patch by Eric Price.
+
+- Issue #26586: In http.server, respond with "413 Request header fields too
+  large" if there are too many header fields to parse, rather than killing
+  the connection and raising an unhandled exception.  Patch by Xiang Zhang.
+
+- Issue #22854: Change BufferedReader.writable() and
+  BufferedWriter.readable() to always return False.
+
+- Issue #25195: Fix a regression in mock.MagicMock. _Call is a subclass of
+  tuple (changeset 3603bae63c13 only works for classes) so we need to
+  implement __ne__ ourselves.  Patch by Andrew Plummer.
+
+- Issue #26644: Raise ValueError rather than SystemError when a negative
+  length is passed to SSLSocket.recv() or read().
+
+- Issue #23804: Fix SSL recv(0) and read(0) methods to return zero bytes
+  instead of up to 1024.
+
+- Issue #26616: Fixed a bug in datetime.astimezone() method.
+
+- Issue #21925: :func:`warnings.formatwarning` now catches exceptions on
+  ``linecache.getline(...)`` to be able to log :exc:`ResourceWarning` emitted
+  late during the Python shutdown process.
+
+- Issue #24266: Ctrl+C during Readline history search now cancels the search
+  mode when compiled with Readline 7.
+
+- Issue #26560: Avoid potential ValueError in BaseHandler.start_response.
+  Initial patch by Peter Inglesby.
+
+- Issue #26313: ssl.py _load_windows_store_certs fails if windows cert store
+  is empty. Patch by Baji.
+
+- Issue #26569: Fix :func:`pyclbr.readmodule` and :func:`pyclbr.readmodule_ex`
+  to support importing packages.
+
+- Issue #26499: Account for remaining Content-Length in
+  HTTPResponse.readline() and read1().  Based on patch by Silent Ghost.
+  Also document that HTTPResponse now supports these methods.
+
+- Issue #25320: Handle sockets in directories unittest discovery is scanning.
+  Patch from Victor van den Elzen.
+
+- Issue #16181: cookiejar.http2time() now returns None if year is higher than
+  datetime.MAXYEAR.
+
+- Issue #26513: Fixes platform module detection of Windows Server
+
+- Issue #23718: Fixed parsing time in week 0 before Jan 1.  Original patch by
+  Tamás Bence Gedai.
+
+- Issue #20589: Invoking Path.owner() and Path.group() on Windows now raise
+  NotImplementedError instead of ImportError.
+
+- Issue #26177: Fixed the keys() method for Canvas and Scrollbar widgets.
+
+- Issue #15068: Got rid of excessive buffering in the fileinput module.
+  The bufsize parameter is no longer used.
+
+- Issue #2202: Fix UnboundLocalError in
+  AbstractDigestAuthHandler.get_algorithm_impls.  Initial patch by Mathieu Dupuy.
+
+- Issue #25718: Fixed pickling and copying the accumulate() iterator with
+  total is None.
+
+- Issue #26475: Fixed debugging output for regular expressions with the (?x)
+  flag.
+
+- Issue #26457: Fixed the subnets() methods in IP network classes for the case
+  when resulting prefix length is equal to maximal prefix length.
+  Based on patch by Xiang Zhang.
+
+- Issue #26385: Remove the file if the internal open() call in
+  NamedTemporaryFile() fails.  Patch by Silent Ghost.
+
+- Issue #26402: Fix XML-RPC client to retry when the server shuts down a
+  persistent connection.  This was a regression related to the new
+  http.client.RemoteDisconnected exception in 3.5.0a4.
+
+- Issue #25913: Leading ``<~`` is optional now in base64.a85decode() with
+  adobe=True.  Patch by Swati Jaiswal.
+
+- Issue #26186: Remove an invalid type check in importlib.util.LazyLoader.
+
+- Issue #26367: importlib.__import__() raises SystemError like
+  builtins.__import__() when ``level`` is specified but without an accompanying
+  package specified.
+
+- Issue #26309: In the "socketserver" module, shut down the request (closing
+  the connected socket) when verify_request() returns false.  Patch by Aviv
+  Palivoda.
+
+- Issue #25939: On Windows open the cert store readonly in ssl.enum_certificates.
+
+- Issue #25995: os.walk() no longer uses FDs proportional to the tree depth.
+
+- Issue #26117: The os.scandir() iterator now closes file descriptor not only
+  when the iteration is finished, but when it was failed with error.
+
+- Issue #25911: Restored support of bytes paths in os.walk() on Windows.
+
+- Issue #26045: Add UTF-8 suggestion to error message when posting a
+  non-Latin-1 string with http.client.
+
+- Issue #12923: Reset FancyURLopener's redirect counter even if there is an
+  exception.  Based on patches by Brian Brazil and Daniel Rocco.
+
+- Issue #25945: Fixed a crash when unpickle the functools.partial object with
+  wrong state.  Fixed a leak in failed functools.partial constructor.
+  "args" and "keywords" attributes of functools.partial have now always types
+  tuple and dict correspondingly.
+
+- Issue #26202: copy.deepcopy() now correctly copies range() objects with
+  non-atomic attributes.
+
+- Issue #23076: Path.glob() now raises a ValueError if it's called with an
+  invalid pattern.  Patch by Thomas Nyberg.
+
+- Issue #19883: Fixed possible integer overflows in zipimport.
+
+- Issue #26227: On Windows, getnameinfo(), gethostbyaddr() and
+  gethostbyname_ex() functions of the socket module now decode the hostname
+  from the ANSI code page rather than UTF-8.
+
+- Issue #26147: xmlrpc now works with strings not encodable with used
+  non-UTF-8 encoding.
+
+- Issue #25935: Garbage collector now breaks reference loops with OrderedDict.
+
+- Issue #16620: Fixed AttributeError in msilib.Directory.glob().
+
+- Issue #26013: Added compatibility with broken protocol 2 pickles created
+  in old Python 3 versions (3.4.3 and lower).
+
+- Issue #25850: Use cross-compilation by default for 64-bit Windows.
+
+- Issue #17633: Improve zipimport's support for namespace packages.
+
+- Issue #24705: Fix sysconfig._parse_makefile not expanding ${} vars
+  appearing before $() vars.
+
+- Issue #22138: Fix mock.patch behavior when patching descriptors. Restore
+  original values after patching. Patch contributed by Sean McCully.
+
+- Issue #25672: In the ssl module, enable the SSL_MODE_RELEASE_BUFFERS mode
+  option if it is safe to do so.
+
+- Issue #26012: Don't traverse into symlinks for ** pattern in
+  pathlib.Path.[r]glob().
+
+- Issue #24120: Ignore PermissionError when traversing a tree with
+  pathlib.Path.[r]glob().  Patch by Ulrich Petri.
+
+- Issue #25447: fileinput now uses sys.stdin as-is if it does not have a
+  buffer attribute (restores backward compatibility).
+
+- Issue #25447: Copying the lru_cache() wrapper object now always works,
+  independedly from the type of the wrapped object (by returning the original
+  object unchanged).
+
+- Issue #24103: Fixed possible use after free in ElementTree.XMLPullParser.
+
+- Issue #25860: os.fwalk() no longer skips remaining directories when error
+  occurs.  Original patch by Samson Lee.
+
+- Issue #25914: Fixed and simplified OrderedDict.__sizeof__.
+
+- Issue #25902: Fixed various refcount issues in ElementTree iteration.
+
+- Issue #25717: Restore the previous behaviour of tolerating most fstat()
+  errors when opening files.  This was a regression in 3.5a1, and stopped
+  anonymous temporary files from working in special cases.
+
+- Issue #24903: Fix regression in number of arguments compileall accepts when
+  '-d' is specified.  The check on the number of arguments has been dropped
+  completely as it never worked correctly anyway.
+
+- Issue #25764: In the subprocess module, preserve any exception caused by
+  fork() failure when preexec_fn is used.
+
+- Issue #6478: _strptime's regexp cache now is reset after changing timezone
+  with time.tzset().
+
+- Issue #14285: When executing a package with the "python -m package" option,
+  and package initialization fails, a proper traceback is now reported.  The
+  "runpy" module now lets exceptions from package initialization pass back to
+  the caller, rather than raising ImportError.
+
+- Issue #19771: Also in runpy and the "-m" option, omit the irrelevant
+  message ". . . is a package and cannot be directly executed" if the package
+  could not even be initialized (e.g. due to a bad ``*.pyc`` file).
+
+- Issue #25177: Fixed problem with the mean of very small and very large
+  numbers. As a side effect, statistics.mean and statistics.variance should
+  be significantly faster.
+
+- Issue #25718: Fixed copying object with state with boolean value is false.
+
+- Issue #10131: Fixed deep copying of minidom documents.  Based on patch
+  by Marian Ganisin.
+
+- Issue #25725: Fixed a reference leak in pickle.loads() when unpickling
+  invalid data including tuple instructions.
+
+- Issue #25663: In the Readline completer, avoid listing duplicate global
+  names, and search the global namespace before searching builtins.
+
+- Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.
+
+- Issue #23914: Fixed SystemError raised by unpickler on broken pickle data.
+
+- Issue #25691: Fixed crash on deleting ElementTree.Element attributes.
+
+- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory
+  entries.  Patch by Dingyuan Wang.
+
+- Skip getaddrinfo if host is already resolved.
+  Patch by A. Jesse Jiryu Davis.
+
+- Issue #26050: Add asyncio.StreamReader.readuntil() method.
+  Patch by Марк Коренберг.
+
+- Issue #25924: Avoid unnecessary serialization of getaddrinfo(3) calls on
+  OS X versions 10.5 or higher.  Original patch by A. Jesse Jiryu Davis.
+
+- Issue #26406: Avoid unnecessary serialization of getaddrinfo(3) calls on
+  current versions of OpenBSD and NetBSD.  Patch by A. Jesse Jiryu Davis.
+
+- Issue #26848: Fix asyncio/subprocess.communicate() to handle empty input.
+  Patch by Jack O'Connor.
+
+- Issue #27040: Add loop.get_exception_handler method
+
+- Issue #27041: asyncio: Add loop.create_future method
+
+- Issue #27223: asyncio: Fix _read_ready and _write_ready to respect
+  _conn_lost.
+  Patch by Łukasz Langa.
+
+- Issue #22970: asyncio: Fix inconsistency cancelling Condition.wait.
+  Patch by David Coles.
+
+IDLE
+----
+
+- Issue #5124: Paste with text selected now replaces the selection on X11.
+  This matches how paste works on Windows, Mac, most modern Linux apps,
+  and ttk widgets.  Original patch by Serhiy Storchaka.
+
+- Issue #24759: Make clear in idlelib.idle_test.__init__ that the directory
+  is a private implementation of test.test_idle and tool for maintainers.
+
+- Issue #27196: Stop 'ThemeChanged' warnings when running IDLE tests.
+  These persisted after other warnings were suppressed in #20567.
+  Apply Serhiy Storchaka's update_idletasks solution to four test files.
+  Record this additional advice in idle_test/README.txt
+
+- Issue #20567: Revise idle_test/README.txt with advice about avoiding
+  tk warning messages from tests.  Apply advice to several IDLE tests.
+
+- Issue #27117: Make colorizer htest and turtledemo work with dark themes.
+  Move code for configuring text widget colors to a new function.
+
+- Issue #26673: When tk reports font size as 0, change to size 10.
+  Such fonts on Linux prevented the configuration dialog from opening.
+
+- Issue #21939: Add test for IDLE's percolator.
+  Original patch by Saimadhav Heblikar.
+
+- Issue #21676: Add test for IDLE's replace dialog.
+  Original patch by Saimadhav Heblikar.
+
+- Issue #18410: Add test for IDLE's search dialog.
+  Original patch by Westley Martínez.
+
+- Issue #21703: Add test for IDLE's undo delegator.
+  Original patch by Saimadhav Heblikar .
+
+- Issue #27044: Add ConfigDialog.remove_var_callbacks to stop memory leaks.
+
+- Issue #23977: Add more asserts to test_delegator.
+
+- Issue #20640: Add tests for idlelib.configHelpSourceEdit.
+  Patch by Saimadhav Heblikar.
+
+- In the 'IDLE-console differences' section of the IDLE doc, clarify
+  how running with IDLE affects sys.modules and the standard streams.
+
+- Issue #25507: fix incorrect change in IOBinding that prevented printing.
+  Augment IOBinding htest to include all major IOBinding functions.
+
+- Issue #25905: Revert unwanted conversion of ' to ’ RIGHT SINGLE QUOTATION
+  MARK in README.txt and open this and NEWS.txt with 'ascii'.
+  Re-encode CREDITS.txt to utf-8 and open it with 'utf-8'.
+
+Documentation
+-------------
+
+- Issue #24136: Document the new PEP 448 unpacking syntax of 3.5.
+
+- Issue #26736: Used HTTPS for external links in the documentation if possible.
+
+- Issue #6953: Rework the Readline module documentation to group related
+  functions together, and add more details such as what underlying Readline
+  functions and variables are accessed.
+
+- Issue #23606: Adds note to ctypes documentation regarding cdll.msvcrt.
+
+- Issue #25500: Fix documentation to not claim that __import__ is searched for
+  in the global scope.
+
+- Issue #26014: Update 3.x packaging documentation:
+  * "See also" links to the new docs are now provided in the legacy pages
+  * links to setuptools documentation have been updated
+
+Tests
+-----
+
+- Issue #21916: Added tests for the turtle module.  Patch by ingrid,
+  Gregory Loyse and Jelle Zijlstra.
+
+- Issue #26523: The multiprocessing thread pool (multiprocessing.dummy.Pool)
+  was untested.
+
+- Issue #26015: Added new tests for pickling iterators of mutable sequences.
+
+- Issue #26325: Added test.support.check_no_resource_warning() to check that
+  no ResourceWarning is emitted.
+
+- Issue #25940: Changed test_ssl to use self-signed.pythontest.net.  This
+  avoids relying on svn.python.org, which recently changed root certificate.
+
+- Issue #25616: Tests for OrderedDict are extracted from test_collections
+  into separate file test_ordered_dict.
+
+- Issue #26583: Skip test_timestamp_overflow in test_import if bytecode
+  files cannot be written.
+
+Build
+-----
+
+- Issue #26884: Fix linking extension modules for cross builds.
+  Patch by Xavier de Gaye.
+
+- Issue #22359: Disable the rules for running _freeze_importlib and pgen when
+  cross-compiling.  The output of these programs is normally saved with the
+  source code anyway, and is still regenerated when doing a native build.
+  Patch by Xavier de Gaye.
+
+- Issue #27229: Fix the cross-compiling pgen rule for in-tree builds.  Patch
+  by Xavier de Gaye.
+
+- Issue #21668: Link audioop, _datetime, _ctypes_test modules to libm,
+  except on Mac OS X. Patch written by Xavier de Gaye.
+
+- Issue #25702: A --with-lto configure option has been added that will
+  enable link time optimizations at build time during a make profile-opt.
+  Some compilers and toolchains are known to not produce stable code when
+  using LTO, be sure to test things thoroughly before relying on it.
+  It can provide a few % speed up over profile-opt alone.
+
+- Issue #26624: Adds validation of ucrtbase[d].dll version with warning
+  for old versions.
+
+- Issue #17603: Avoid error about nonexistant fileblocks.o file by using a
+  lower-level check for st_blocks in struct stat.
+
+- Issue #26079: Fixing the build output folder for tix-8.4.3.6. Patch by
+  Bjoern Thiel.
+
+- Issue #26465: Update Windows builds to use OpenSSL 1.0.2g.
+
+- Issue #24421: Compile Modules/_math.c once, before building extensions.
+  Previously it could fail to compile properly if the math and cmath builds
+  were concurrent.
+
+- Issue #25348: Added ``--pgo`` and ``--pgo-job`` arguments to
+  ``PCbuild\build.bat`` for building with Profile-Guided Optimization.  The
+  old ``PCbuild\build_pgo.bat`` script is now deprecated, and simply calls
+  ``PCbuild\build.bat --pgo %*``.
+
+- Issue #25827: Add support for building with ICC to ``configure``, including
+  a new ``--with-icc`` flag.
+
+- Issue #25696: Fix installation of Python on UNIX with make -j9.
+
+- Issue #26930: Update OS X 10.5+ 32-bit-only installer to build
+  and link with OpenSSL 1.0.2h.
+
+- Issue #26268: Update Windows builds to use OpenSSL 1.0.2f.
+
+- Issue #25136: Support Apple Xcode 7's new textual SDK stub libraries.
+
+- Issue #24324: Do not enable unreachable code warnings when using
+  gcc as the option does not work correctly in older versions of gcc
+  and has been silently removed as of gcc-4.5.
+
+Windows
+-------
+
+- Issue #27053: Updates make_zip.py to correctly generate library ZIP file.
+
+- Issue #26268: Update the prepare_ssl.py script to handle OpenSSL releases
+  that don't include the contents of the include directory (that is, 1.0.2e
+  and later).
+
+- Issue #26071: bdist_wininst created binaries fail to start and find
+  32bit Python
+
+- Issue #26073: Update the list of magic numbers in launcher
+
+- Issue #26065: Excludes venv from library when generating embeddable
+  distro.
+
+Tools/Demos
+-----------
+
+- Issue #26799: Fix python-gdb.py: don't get C types once when the Python code
+  is loaded, but get C types on demand. The C types can change if
+  python-gdb.py is loaded before the Python executable. Patch written by Thomas
+  Ilsche.
+
+- Issue #26271: Fix the Freeze tool to properly use flags passed through
+  configure. Patch by Daniel Shaulov.
+
+- Issue #26489: Add dictionary unpacking support to Tools/parser/unparse.py.
+  Patch by Guo Ci Teo.
+
+- Issue #26316: Fix variable name typo in Argument Clinic.
+
+Misc
+----
+
+- Issue #17500, and https://github.com/python/pythondotorg/issues/945: Remove
+  unused and outdated icons.
+
+
 What's New in Python 3.5.1 final?
 =================================
 
@@ -199,7 +948,7 @@ Library
 
 - Issue #25111: Fixed comparison of traceback.FrameSummary.
 
-- Issue #25262. Added support for BINBYTES8 opcode in Python implementation of
+- Issue #25262: Added support for BINBYTES8 opcode in Python implementation of
   unpickler.  Highest 32 bits of 64-bit size for BINUNICODE8 and BINBYTES8
   opcodes no longer silently ignored on 32-bit platforms in C implementation.
 
@@ -324,7 +1073,7 @@ Library
 IDLE
 ----
 
-- Issue 15348: Stop the debugger engine (normally in a user process)
+- Issue #15348: Stop the debugger engine (normally in a user process)
   before closing the debugger window (running in the IDLE process).
   This prevents the RuntimeErrors that were being caught and ignored.
 
@@ -348,7 +1097,7 @@ IDLE
   Consistently use the revised idleConf.CurrentTheme everywhere in idlelib.
 
 - Issue #24782: Extension configuration is now a tab in the IDLE Preferences
-  dialog rather than a separate dialog.   The former tabs are now a sorted
+  dialog rather than a separate dialog.  The former tabs are now a sorted
   list.  Patch by Mark Roseman.
 
 - Issue #22726: Re-activate the config dialog help button with some content
@@ -421,6 +1170,9 @@ IDLE
 Documentation
 -------------
 
+- Issue #22558: Add remaining doc links to source code for Python-coded modules.
+  Patch by Yoni Lavi.
+
 - Issue #12067: Rewrite Comparisons section in the Expressions chapter of the
   language reference. Some of the details of comparing mixed types were
   incorrect or ambiguous. NotImplemented is only relevant at a lower level
@@ -709,7 +1461,7 @@ Core and Builtins
 - Issue #24407: Fix crash when dict is mutated while being updated.
 
 - Issue #24619: New approach for tokenizing async/await. As a consequence,
-  is is now possible to have one-line 'async def foo(): await ..' functions.
+  it is now possible to have one-line 'async def foo(): await ..' functions.
 
 - Issue #24687: Plug refleak on SyntaxError in function parameters
   annotations.
@@ -1386,7 +2138,7 @@ Library
 Build
 -----
 
-- Issue #23817: FreeBSD now uses "1.0" the the SOVERSION as other operating
+- Issue #23817: FreeBSD now uses "1.0" in the SOVERSION as other operating
   systems, instead of just "1".
 
 - Issue #23501: Argument Clinic now generates code into separate files by default.
@@ -1483,8 +2235,8 @@ Library
   and ASCII letter now raise a deprecation warning and will be forbidden in
   Python 3.6.
 
-- Issue #23671: string.Template now allows to specify the "self" parameter as
-  keyword argument.  string.Formatter now allows to specify the "self" and
+- Issue #23671: string.Template now allows specifying the "self" parameter as
+  a keyword argument.  string.Formatter now allows specifying the "self" and
   the "format_string" parameters as keyword arguments.
 
 - Issue #23502: The pprint module now supports mapping proxies.
@@ -1523,7 +2275,7 @@ Library
 
 - Issue #23704: collections.deque() objects now support methods for index(),
   insert(), and copy().  This allows deques to be registered as a
-  MutableSequence and it improves their substitutablity for lists.
+  MutableSequence and it improves their substitutability for lists.
 
 - Issue #23715: :func:`signal.sigwaitinfo` and :func:`signal.sigtimedwait` are
   now retried when interrupted by a signal not in the *sigset* parameter, if
@@ -1778,7 +2530,7 @@ Core and Builtins
   static type in some cases.
 
 - Issue #15859: PyUnicode_EncodeFSDefault(), PyUnicode_EncodeMBCS() and
-  PyUnicode_EncodeCodePage() now raise an exception if the object is not an
+  PyUnicode_EncodeCodePage() now raise an exception if the object is not a
   Unicode object. For PyUnicode_EncodeFSDefault(), it was already the case on
   platforms other than Windows. Patch written by Campbell Barton.
 
@@ -2139,7 +2891,7 @@ Library
   is run with pythonw.exe.
 
 - Issue #21775: shutil.copytree(): fix crash when copying to VFAT. An exception
-  handler assumed that that OSError objects always have a 'winerror' attribute.
+  handler assumed that OSError objects always have a 'winerror' attribute.
   That is not the case, so the exception handler itself raised AttributeError
   when run on Linux (and, presumably, any other non-Windows OS).
   Patch by Greg Ward.
@@ -2172,7 +2924,7 @@ Library
 
 - Issue #21971: Update turtledemo doc and add module to the index.
 
-- Issue #21032. Fixed socket leak if HTTPConnection.getresponse() fails.
+- Issue #21032: Fixed socket leak if HTTPConnection.getresponse() fails.
   Original patch by Martin Panter.
 
 - Issue #22407: Deprecated the use of re.LOCALE flag with str patterns or
@@ -2426,7 +3178,7 @@ Library
 - Issue #22247: Add NNTPError to nntplib.__all__.
 
 - Issue #22366: urllib.request.urlopen will accept a context object
-  (SSLContext) as an argument which will then used be for HTTPS connection.
+  (SSLContext) as an argument which will then be used for HTTPS connection.
   Patch by Alex Gaynor.
 
 - Issue #4180: The warnings registries are now reset when the filters
@@ -2613,7 +3365,7 @@ Library
 - Issue #22085: Dropped support of Tk 8.3 in Tkinter.
 
 - Issue #21580: Now Tkinter correctly handles bytes arguments passed to Tk.
-  In particular this allows to initialize images from binary data.
+  In particular this allows initializing images from binary data.
 
 - Issue #22003: When initialized from a bytes object, io.BytesIO() now
   defers making a copy until it is mutated, improving performance and
@@ -2758,7 +3510,7 @@ Library
 - Issue #21711: support for "site-python" directories has now been removed
   from the site module (it was deprecated in 3.4).
 
-- Issue #17552: new socket.sendfile() method allowing to send a file over a
+- Issue #17552: new socket.sendfile() method allowing a file to be sent over a
   socket by using high-performance os.sendfile() on UNIX.
   Patch by Giampaolo Rodola'.
 
@@ -2869,7 +3621,7 @@ Library
 - Issue #21226: Set up modules properly in PyImport_ExecCodeModuleObject
   (and friends).
 
-- Issue #21398: Fix an unicode error in the pydoc pager when the documentation
+- Issue #21398: Fix a unicode error in the pydoc pager when the documentation
   contains characters not encodable to the stdout encoding.
 
 - Issue #16531: ipaddress.IPv4Network and ipaddress.IPv6Network now accept
@@ -2991,8 +3743,9 @@ Library
 - Issue #20968: unittest.mock.MagicMock now supports division.
   Patch by Johannes Baiter.
 
-- Fix arbitrary memory access in JSONDecoder.raw_decode with a negative second
-  parameter. Bug reported by Guido Vranken.
+- Issue #21529 (CVE-2014-4616): Fix arbitrary memory access in
+  JSONDecoder.raw_decode with a negative second parameter. Bug reported by Guido
+  Vranken.
 
 - Issue #21169: getpass now handles non-ascii characters that the
   input stream encoding cannot encode by re-encoding using the
@@ -3054,7 +3807,7 @@ Library
 - Issue #21000: Improve the command-line interface of json.tool.
 
 - Issue #20995: Enhance default ciphers used by the ssl module to enable
-  better security an prioritize perfect forward secrecy.
+  better security and prioritize perfect forward secrecy.
 
 - Issue #20884: Don't assume that __file__ is defined on importlib.__init__.
 
@@ -3201,7 +3954,7 @@ IDLE
   move version to end.
 
 - Issue #14105: Idle debugger breakpoints no longer disappear
-  when inseting or deleting lines.
+  when inserting or deleting lines.
 
 - Issue #17172: Turtledemo can now be run from Idle.
   Currently, the entry is on the Help menu, but it may move to Run.
@@ -4763,8 +5516,8 @@ Library
 - Issue #19448: Add private API to SSL module to lookup ASN.1 objects by OID,
   NID, short name and long name.
 
-- Issue #19282: dbm.open now supports the context management protocol. (Inital
-  patch by Claudiu Popa)
+- Issue #19282: dbm.open now supports the context management protocol.
+  (Initial patch by Claudiu Popa)
 
 - Issue #8311: Added support for writing any bytes-like objects in the aifc,
   sunau, and wave modules.
@@ -4858,7 +5611,7 @@ Library
 - Issue #19227: Remove pthread_atfork() handler. The handler was added to
   solve #18747 but has caused issues.
 
-- Issue #19420: Fix reference leak in module initalization code of
+- Issue #19420: Fix reference leak in module initialization code of
   _hashopenssl.c
 
 - Issue #19329: Optimized compiling charsets in regular expressions.
@@ -5872,7 +6625,7 @@ Core and Builtins
 - Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.)
   in the interpreter.
 
-- Issue #17137: When an Unicode string is resized, the internal wide character
+- Issue #17137: When a Unicode string is resized, the internal wide character
   string (wstr) format is now cleared.
 
 - Issue #17043: The unicode-internal decoder no longer read past the end of
@@ -6399,7 +7152,7 @@ Library
   Thomas Barlow.
 
 - Issue #17358: Modules loaded by imp.load_source() and load_compiled() (and by
-  extention load_module()) now have a better chance of working when reloaded.
+  extension load_module()) now have a better chance of working when reloaded.
 
 - Issue #17804: New function ``struct.iter_unpack`` allows for streaming
   struct unpacking.
@@ -6512,8 +7265,8 @@ Library
   error message has been removed.  Patch by Ram Rachum.
 
 - Issue #18080: When building a C extension module on OS X, if the compiler
-  is overriden with the CC environment variable, use the new compiler as
-  the default for linking if LDSHARED is not also overriden.  This restores
+  is overridden with the CC environment variable, use the new compiler as
+  the default for linking if LDSHARED is not also overridden.  This restores
   Distutils behavior introduced in 3.2.3 and inadvertently dropped in 3.3.0.
 
 - Issue #18113: Fixed a refcount leak in the curses.panel module's
@@ -6720,7 +7473,7 @@ Library
   symlinks on POSIX platforms.
 
 - Issue #13773: sqlite3.connect() gets a new `uri` parameter to pass the
-  filename as a URI, allowing to pass custom options.
+  filename as a URI, allowing custom options to be passed.
 
 - Issue #16564: Fixed regression relative to Python2 in the operation of
   email.encoders.encode_noop when used with binary data.
@@ -6759,7 +7512,7 @@ Library
   internal XML encoding is not UTF-8 or US-ASCII.  It also now accepts bytes
   and strings larger than 2 GiB.
 
-- Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple
+- Issue #6083: Fix multiple segmentation faults occurred when PyArg_ParseTuple
   parses nested mutating sequence.
 
 - Issue #5289: Fix ctypes.util.find_library on Solaris.
@@ -6981,7 +7734,7 @@ Library
 - Issue #7719: Make distutils ignore ``.nfs*`` files instead of choking later
   on.  Initial patch by SilentGhost and Jeff Ramnani.
 
-- Issue #13120: Allow to call pdb.set_trace() from thread.
+- Issue #13120: Allow calling pdb.set_trace() from thread.
   Patch by Ilya Sandler.
 
 - Issue #16585: Make CJK encoders support error handlers that return bytes per
@@ -7082,7 +7835,7 @@ Library
 - Issue #16284: Prevent keeping unnecessary references to worker functions
   in concurrent.futures ThreadPoolExecutor.
 
-- Issue #16230: Fix a crash in select.select() when one the lists changes
+- Issue #16230: Fix a crash in select.select() when one of the lists changes
   size while iterated on.  Patch by Serhiy Storchaka.
 
 - Issue #16228: Fix a crash in the json module where a list changes size
@@ -7111,7 +7864,7 @@ Library
 
 - Issue #16245: Fix the value of a few entities in html.entities.html5.
 
-- Issue #16301: Fix the localhost verification in urllib/request.py for file://
+- Issue #16301: Fix the localhost verification in urllib/request.py for ``file://``
   urls.
 
 - Issue #16250: Fix the invocations of URLError which had misplaced filename
@@ -7142,7 +7895,7 @@ Library
 - Issue #16176: Properly identify Windows 8 via platform.platform()
 
 - Issue #16088: BaseHTTPRequestHandler's send_error method includes a
-  Content-Length header in it's response now. Patch by Antoine Pitrou.
+  Content-Length header in its response now. Patch by Antoine Pitrou.
 
 - Issue #16114: The subprocess module no longer provides a misleading error
   message stating that args[0] did not exist when either the cwd or executable
index 6dbdba9..3d530d7 100644 (file)
@@ -1,4 +1,4 @@
-.TH PYTHON "1" "$Date$"
+.TH PYTHON "1"
 
 .\" To view this file while editing, run it through groff:
 .\"   groff -Tascii -man python.man | less
@@ -143,7 +143,7 @@ raises an exception.
 .TP
 .B \-I
 Run Python in isolated mode. This also implies \fB\-E\fP and \fB\-s\fP. In
-isolated mode sys.path contains neither the script’s directory nor the user’s
+isolated mode sys.path contains neither the script's directory nor the user's
 site-packages directory. All PYTHON* environment variables are ignored, too.
 Further restrictions may be imposed to prevent the user from injecting
 malicious code.
index 7dfd307..e3e0eb1 100644 (file)
@@ -540,9 +540,8 @@ decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length)
     if (d->eof) {
         d->needs_input = 0;
         if (d->bzs_avail_in_real > 0) {
-            Py_CLEAR(d->unused_data);
-            d->unused_data = PyBytes_FromStringAndSize(
-                bzs->next_in, d->bzs_avail_in_real);
+            Py_XSETREF(d->unused_data,
+                      PyBytes_FromStringAndSize(bzs->next_in, d->bzs_avail_in_real));
             if (d->unused_data == NULL)
                 goto error;
         }
index 214872b..10fbcfe 100644 (file)
@@ -9,8 +9,6 @@
 
 /* collections module implementation of a deque() datatype
    Written and maintained by Raymond D. Hettinger <python@rcn.com>
-   Copyright (c) 2004-2015 Python Software Foundation.
-   All rights reserved.
 */
 
 /* The block length may be set to any number over 1.  Larger numbers
@@ -979,6 +977,10 @@ deque_insert(dequeobject *deque, PyObject *args)
 
     if (!PyArg_ParseTuple(args, "nO:insert", &index, &value))
         return NULL;
+    if (deque->maxlen == Py_SIZE(deque)) {
+        PyErr_SetString(PyExc_IndexError, "deque already at its maximum size");
+        return NULL;
+    }
     if (index >= n)
         return deque_append(deque, value);
     if (index <= -n || index == 0)
@@ -1443,7 +1445,7 @@ deque_sizeof(dequeobject *deque, void *unused)
     Py_ssize_t res;
     Py_ssize_t blocks;
 
-    res = sizeof(dequeobject);
+    res = _PyObject_SIZE(Py_TYPE(deque));
     blocks = (deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN;
     assert(deque->leftindex + Py_SIZE(deque) - 1 ==
            (blocks - 1) * BLOCKLEN + deque->rightindex);
index af901e2..101f449 100644 (file)
@@ -276,9 +276,8 @@ _set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
         else {
             if (PyUnicode_READY(src) == -1)
                 return -1;
-            Py_XDECREF(*target);
             Py_INCREF(src);
-            *target = src;
+            Py_XSETREF(*target, src);
         }
     }
     return 0;
@@ -732,7 +731,7 @@ parse_process_char(ReaderObj *self, Py_UCS4 c)
         break;
 
     case QUOTE_IN_QUOTED_FIELD:
-        /* doublequote - seen a quote in an quoted field */
+        /* doublequote - seen a quote in a quoted field */
         if (dialect->quoting != QUOTE_NONE &&
             c == dialect->quotechar) {
             /* save "" as " */
@@ -784,8 +783,7 @@ parse_process_char(ReaderObj *self, Py_UCS4 c)
 static int
 parse_reset(ReaderObj *self)
 {
-    Py_XDECREF(self->fields);
-    self->fields = PyList_New(0);
+    Py_XSETREF(self->fields, PyList_New(0));
     if (self->fields == NULL)
         return -1;
     self->field_len = 0;
index 00eb700..2e01323 100644 (file)
@@ -49,7 +49,7 @@ from_address(addr)
 
 from_param(obj)
     - typecheck and convert a Python object into a C function call parameter
-      the result may be an instance of the type, or an integer or tuple
+      The result may be an instance of the type, or an integer or tuple
       (typecode, value[, obj])
 
 instance methods/properties
@@ -391,8 +391,7 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
         Py_DECREF((PyObject *)dict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)dict;
+    Py_SETREF(result->tp_dict, (PyObject *)dict);
     dict->format = _ctypes_alloc_format_string(NULL, "B");
     if (dict->format == NULL) {
         Py_DECREF(result);
@@ -871,8 +870,7 @@ PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
         return -1;
     }
     Py_INCREF(proto);
-    Py_XDECREF(stgdict->proto);
-    stgdict->proto = proto;
+    Py_XSETREF(stgdict->proto, proto);
     return 0;
 }
 
@@ -962,8 +960,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         Py_DECREF((PyObject *)stgdict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);
 
     return (PyObject *)result;
 }
@@ -1406,8 +1403,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     /* replace the class dict by our updated spam dict */
     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict))
         goto error;
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;  /* steal the reference */
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);  /* steal the reference */
     stgdict = NULL;
 
     /* Special case for character arrays.
@@ -1820,8 +1816,7 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
         Py_DECREF((PyObject *)stgdict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);
 
     return (PyObject *)result;
 }
@@ -1949,8 +1944,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         Py_DECREF((PyObject *)stgdict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);
 
     /* Install from_param class methods in ctypes base classes.
        Overrides the PyCSimpleType_from_param generic method.
@@ -2313,8 +2307,7 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         Py_DECREF((PyObject *)stgdict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);
 
     if (-1 == make_funcptrtype_dict(stgdict)) {
         Py_DECREF(result);
@@ -2458,8 +2451,7 @@ KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
         return -1;
     }
     if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
-        Py_XDECREF(ob->b_objects);
-        ob->b_objects = keep; /* refcount consumed */
+        Py_XSETREF(ob->b_objects, keep); /* refcount consumed */
         return 0;
     }
     key = unique_key(target, index);
@@ -2962,9 +2954,8 @@ PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob)
                         "the errcheck attribute must be callable");
         return -1;
     }
-    Py_XDECREF(self->errcheck);
     Py_XINCREF(ob);
-    self->errcheck = ob;
+    Py_XSETREF(self->errcheck, ob);
     return 0;
 }
 
@@ -2992,11 +2983,9 @@ PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob)
                         "restype must be a type, a callable, or None");
         return -1;
     }
-    Py_XDECREF(self->checker);
-    Py_XDECREF(self->restype);
     Py_INCREF(ob);
-    self->restype = ob;
-    self->checker = PyObject_GetAttrString(ob, "_check_retval_");
+    Py_XSETREF(self->restype, ob);
+    Py_XSETREF(self->checker, PyObject_GetAttrString(ob, "_check_retval_"));
     if (self->checker == NULL)
         PyErr_Clear();
     return 0;
@@ -3033,11 +3022,9 @@ PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob)
         converters = converters_from_argtypes(ob);
         if (!converters)
             return -1;
-        Py_XDECREF(self->converters);
-        self->converters = converters;
-        Py_XDECREF(self->argtypes);
+        Py_XSETREF(self->converters, converters);
         Py_INCREF(ob);
-        self->argtypes = ob;
+        Py_XSETREF(self->argtypes, ob);
     }
     return 0;
 }
@@ -3415,7 +3402,7 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         return NULL;
     }
 
-    /* XXX XXX This would allow to pass additional options.  For COM
+    /* XXX XXX This would allow passing additional options.  For COM
        method *implementations*, we would probably want different
        behaviour than in 'normal' callback functions: return a HRESULT if
        an exception occurs in the callback, and print the traceback not
@@ -3815,7 +3802,7 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
             return NULL;
         }
         /* there should be more checks? No, in Python */
-        /* First arg is an pointer to an interface instance */
+        /* First arg is a pointer to an interface instance */
         if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
             PyErr_SetString(PyExc_ValueError,
                             "NULL COM pointer access");
@@ -5164,9 +5151,8 @@ comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
         return -1;
 
     bself = (PyBaseExceptionObject *)self;
-    Py_DECREF(bself->args);
-    bself->args = args;
-    Py_INCREF(bself->args);
+    Py_INCREF(args);
+    Py_SETREF(bself->args, args);
 
     return 0;
 }
index 3c7a52a..8cb6d66 100644 (file)
@@ -1375,7 +1375,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size)
         Py_INCREF(value);
         return value;
     }
-    if (PyLong_Check(value) || PyLong_Check(value)) {
+    if (PyLong_Check(value)) {
 #if SIZEOF_VOID_P == SIZEOF_LONG_LONG
         *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value);
 #else
@@ -1491,7 +1491,7 @@ P_set(void *ptr, PyObject *value, Py_ssize_t size)
         _RET(value);
     }
 
-    if (!PyLong_Check(value) && !PyLong_Check(value)) {
+    if (!PyLong_Check(value)) {
         PyErr_SetString(PyExc_TypeError,
                         "cannot be converted to pointer");
         return NULL;
index d8bf904..54cdde9 100644 (file)
@@ -1,7 +1,3 @@
-/*****************************************************************
-  This file should be kept compatible with Python 2.3, see PEP 291.
- *****************************************************************/
-
 #ifndef _CTYPES_DLFCN_H_
 #define _CTYPES_DLFCN_H_
 
index 4bc6b22..d9cc77b 100644 (file)
@@ -1121,7 +1121,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
 # If we don't find anything, use the default library path according
 # to the aix ld manual.
 # Store the results from the different compilers for each TAGNAME.
-# Allow to override them for all tags through lt_cv_aix_libpath.
+# Allow overriding them for all tags through lt_cv_aix_libpath.
 m4_defun([_LT_SYS_MODULE_PATH_AIX],
 [m4_require([_LT_DECL_SED])dnl
 if test set = "${lt_cv_aix_libpath+set}"; then
index 87b9c05..228f497 100644 (file)
@@ -220,6 +220,11 @@ PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo)
 static void
 PyCursesPanel_Dealloc(PyCursesPanelObject *po)
 {
+    PyObject *obj = (PyObject *) panel_userptr(po->pan);
+    if (obj) {
+        (void)set_panel_userptr(po->pan, NULL);
+        Py_DECREF(obj);
+    }
     (void)del_panel(po->pan);
     if (po->wo != NULL) {
         Py_DECREF(po->wo);
@@ -312,9 +317,8 @@ PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args)
         PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR");
         return NULL;
     }
-    Py_DECREF(po->wo);
-    po->wo = temp;
-    Py_INCREF(po->wo);
+    Py_INCREF(temp);
+    Py_SETREF(po->wo, temp);
     Py_INCREF(Py_None);
     return Py_None;
 }
@@ -507,10 +511,11 @@ PyInit__curses_panel(void)
     d = PyModule_GetDict(m);
 
     /* Initialize object type */
-    _curses_panelstate(m)->PyCursesPanel_Type = \
-        PyType_FromSpec(&PyCursesPanel_Type_spec);
-    if (_curses_panelstate(m)->PyCursesPanel_Type == NULL)
+    v = PyType_FromSpec(&PyCursesPanel_Type_spec);
+    if (v == NULL)
         goto fail;
+    ((PyTypeObject *)v)->tp_new = NULL;
+    _curses_panelstate(m)->PyCursesPanel_Type = v;
 
     import_curses();
     if (PyErr_Occurred())
index e3de537..f419cb2 100644 (file)
@@ -219,7 +219,7 @@ days_in_month(int year, int month)
         return _days_in_month[month];
 }
 
-/* year, month -> number of days in year preceeding first day of month */
+/* year, month -> number of days in year preceding first day of month */
 static int
 days_before_month(int year, int month)
 {
@@ -1073,7 +1073,7 @@ format_utcoffset(char *buf, size_t buflen, const char *sep,
     minutes = divmod(seconds, 60, &seconds);
     hours = divmod(minutes, 60, &minutes);
     assert(seconds == 0);
-    /* XXX ignore sub-minute data, curently not allowed. */
+    /* XXX ignore sub-minute data, currently not allowed. */
     PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
 
     return 0;
@@ -3304,7 +3304,7 @@ timezone_str(PyDateTime_TimeZone *self)
     Py_DECREF(offset);
     minutes = divmod(seconds, 60, &seconds);
     hours = divmod(minutes, 60, &minutes);
-    /* XXX ignore sub-minute data, curently not allowed. */
+    /* XXX ignore sub-minute data, currently not allowed. */
     assert(seconds == 0);
     return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
 }
@@ -4749,7 +4749,12 @@ local_timezone(PyDateTime_DateTime *utc_time)
     PyObject *nameo = NULL;
     const char *zone = NULL;
 
-    delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
+    delta = new_delta(ymd_to_ord(GET_YEAR(utc_time), GET_MONTH(utc_time),
+                                 GET_DAY(utc_time)) - 719163,
+                      60 * (60 * DATE_GET_HOUR(utc_time) +
+                            DATE_GET_MINUTE(utc_time)) +
+                      DATE_GET_SECOND(utc_time),
+                      0, 0);
     if (delta == NULL)
         return NULL;
     one_second = new_delta(0, 1, 0, 0);
index 169914c..112b44f 100644 (file)
@@ -4529,7 +4529,7 @@ dec_sizeof(PyObject *v, PyObject *dummy UNUSED)
 {
     Py_ssize_t res;
 
-    res = sizeof(PyDecObject);
+    res = _PyObject_SIZE(Py_TYPE(v));
     if (mpd_isdynamic_data(MPD(v))) {
         res += MPD(v)->alloc * sizeof(mpd_uint_t);
     }
index 911b5ac..0f1d6a1 100644 (file)
@@ -847,7 +847,7 @@ static Py_ssize_t
 _elementtree_Element___sizeof___impl(ElementObject *self)
 /*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/
 {
-    Py_ssize_t result = sizeof(ElementObject);
+    Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self));
     if (self->extra) {
         result += sizeof(ElementObjectExtra);
         if (self->extra->children != self->extra->_children)
@@ -935,9 +935,8 @@ element_setstate_from_attributes(ElementObject *self,
         return NULL;
     }
 
-    Py_CLEAR(self->tag);
-    self->tag = tag;
-    Py_INCREF(self->tag);
+    Py_INCREF(tag);
+    Py_XSETREF(self->tag, tag);
 
     _clear_joined_ptr(&self->text);
     self->text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None;
@@ -980,9 +979,8 @@ element_setstate_from_attributes(ElementObject *self,
 
     /* Stash attrib. */
     if (attrib) {
-        Py_CLEAR(self->extra->attrib);
-        self->extra->attrib = attrib;
         Py_INCREF(attrib);
+        Py_XSETREF(self->extra->attrib, attrib);
     }
 
     Py_RETURN_NONE;
@@ -1373,6 +1371,17 @@ static PyObject *
 _elementtree_Element_iter_impl(ElementObject *self, PyObject *tag)
 /*[clinic end generated code: output=3f49f9a862941cc5 input=774d5b12e573aedd]*/
 {
+    if (PyUnicode_Check(tag)) {
+        if (PyUnicode_READY(tag) < 0)
+            return NULL;
+        if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*')
+            tag = Py_None;
+    }
+    else if (PyBytes_Check(tag)) {
+        if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*')
+            tag = Py_None;
+    }
+
     return create_elementiter(self, tag, 0);
 }
 
@@ -1711,7 +1720,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
         Py_ssize_t start, stop, step, slicelen, newlen, cur, i;
 
         PyObject* recycle = NULL;
-        PyObject* seq = NULL;
+        PyObject* seq;
 
         if (!self->extra) {
             if (create_extra(self, NULL) < 0)
@@ -1790,21 +1799,21 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
             Py_XDECREF(recycle);
             return 0;
         }
-        else {
-            /* A new slice is actually being assigned */
-            seq = PySequence_Fast(value, "");
-            if (!seq) {
-                PyErr_Format(
-                    PyExc_TypeError,
-                    "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name
-                    );
-                return -1;
-            }
-            newlen = PySequence_Size(seq);
+
+        /* A new slice is actually being assigned */
+        seq = PySequence_Fast(value, "");
+        if (!seq) {
+            PyErr_Format(
+                PyExc_TypeError,
+                "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name
+                );
+            return -1;
         }
+        newlen = PySequence_Size(seq);
 
         if (step !=  1 && newlen != slicelen)
         {
+            Py_DECREF(seq);
             PyErr_Format(PyExc_ValueError,
                 "attempt to assign sequence of size %zd "
                 "to extended slice of size %zd",
@@ -1816,9 +1825,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
         /* Resize before creating the recycle bin, to prevent refleaks. */
         if (newlen > slicelen) {
             if (element_resize(self, newlen - slicelen) < 0) {
-                if (seq) {
-                    Py_DECREF(seq);
-                }
+                Py_DECREF(seq);
                 return -1;
             }
         }
@@ -1829,9 +1836,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
                we're done modifying the element */
             recycle = PyList_New(slicelen);
             if (!recycle) {
-                if (seq) {
-                    Py_DECREF(seq);
-                }
+                Py_DECREF(seq);
                 return -1;
             }
             for (cur = start, i = 0; i < slicelen;
@@ -1859,9 +1864,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
 
         self->extra->length += newlen - slicelen;
 
-        if (seq) {
-            Py_DECREF(seq);
-        }
+        Py_DECREF(seq);
 
         /* discard the recycle bin, and everything in it */
         Py_XDECREF(recycle);
@@ -1927,15 +1930,20 @@ static int
 element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value)
 {
     char *name = "";
+
+    if (value == NULL) {
+        PyErr_SetString(PyExc_AttributeError,
+            "can't delete attribute");
+        return -1;
+    }
     if (PyUnicode_Check(nameobj))
         name = _PyUnicode_AsString(nameobj);
     if (name == NULL)
         return -1;
 
     if (strcmp(name, "tag") == 0) {
-        Py_DECREF(self->tag);
-        self->tag = value;
-        Py_INCREF(self->tag);
+        Py_INCREF(value);
+        Py_SETREF(self->tag, value);
     } else if (strcmp(name, "text") == 0) {
         Py_DECREF(JOIN_OBJ(self->text));
         self->text = value;
@@ -1949,9 +1957,8 @@ element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value)
             if (create_extra(self, NULL) < 0)
                 return -1;
         }
-        Py_DECREF(self->extra->attrib);
-        self->extra->attrib = value;
-        Py_INCREF(self->extra->attrib);
+        Py_INCREF(value);
+        Py_SETREF(self->extra->attrib, value);
     } else {
         PyErr_SetString(PyExc_AttributeError,
             "Can't set arbitrary attributes on Element");
@@ -2061,6 +2068,7 @@ elementiter_next(ElementIterObject *it)
     ElementObject *cur_parent;
     Py_ssize_t child_index;
     int rc;
+    ElementObject *elem;
 
     while (1) {
         /* Handle the case reached in the beginning and end of iteration, where
@@ -2074,38 +2082,47 @@ elementiter_next(ElementIterObject *it)
                 PyErr_SetNone(PyExc_StopIteration);
                 return NULL;
             } else {
+                elem = it->root_element;
                 it->parent_stack = parent_stack_push_new(it->parent_stack,
-                                                         it->root_element);
+                                                         elem);
                 if (!it->parent_stack) {
                     PyErr_NoMemory();
                     return NULL;
                 }
 
+                Py_INCREF(elem);
                 it->root_done = 1;
                 rc = (it->sought_tag == Py_None);
                 if (!rc) {
-                    rc = PyObject_RichCompareBool(it->root_element->tag,
+                    rc = PyObject_RichCompareBool(elem->tag,
                                                   it->sought_tag, Py_EQ);
-                    if (rc < 0)
+                    if (rc < 0) {
+                        Py_DECREF(elem);
                         return NULL;
+                    }
                 }
                 if (rc) {
                     if (it->gettext) {
-                        PyObject *text = element_get_text(it->root_element);
-                        if (!text)
+                        PyObject *text = element_get_text(elem);
+                        if (!text) {
+                            Py_DECREF(elem);
                             return NULL;
+                        }
+                        Py_INCREF(text);
+                        Py_DECREF(elem);
                         rc = PyObject_IsTrue(text);
+                        if (rc > 0)
+                            return text;
+                        Py_DECREF(text);
                         if (rc < 0)
                             return NULL;
-                        if (rc) {
-                            Py_INCREF(text);
-                            return text;
-                        }
                     } else {
-                        Py_INCREF(it->root_element);
-                        return (PyObject *)it->root_element;
+                        return (PyObject *)elem;
                     }
                 }
+                else {
+                    Py_DECREF(elem);
+                }
             }
         }
 
@@ -2115,54 +2132,68 @@ elementiter_next(ElementIterObject *it)
         cur_parent = it->parent_stack->parent;
         child_index = it->parent_stack->child_index;
         if (cur_parent->extra && child_index < cur_parent->extra->length) {
-            ElementObject *child = (ElementObject *)
-                cur_parent->extra->children[child_index];
+            elem = (ElementObject *)cur_parent->extra->children[child_index];
             it->parent_stack->child_index++;
             it->parent_stack = parent_stack_push_new(it->parent_stack,
-                                                     child);
+                                                     elem);
             if (!it->parent_stack) {
                 PyErr_NoMemory();
                 return NULL;
             }
 
+            Py_INCREF(elem);
             if (it->gettext) {
-                PyObject *text = element_get_text(child);
-                if (!text)
+                PyObject *text = element_get_text(elem);
+                if (!text) {
+                    Py_DECREF(elem);
                     return NULL;
+                }
+                Py_INCREF(text);
+                Py_DECREF(elem);
                 rc = PyObject_IsTrue(text);
+                if (rc > 0)
+                    return text;
+                Py_DECREF(text);
                 if (rc < 0)
                     return NULL;
-                if (rc) {
-                    Py_INCREF(text);
-                    return text;
-                }
             } else {
                 rc = (it->sought_tag == Py_None);
                 if (!rc) {
-                    rc = PyObject_RichCompareBool(child->tag,
+                    rc = PyObject_RichCompareBool(elem->tag,
                                                   it->sought_tag, Py_EQ);
-                    if (rc < 0)
+                    if (rc < 0) {
+                        Py_DECREF(elem);
                         return NULL;
+                    }
                 }
                 if (rc) {
-                    Py_INCREF(child);
-                    return (PyObject *)child;
+                    return (PyObject *)elem;
                 }
+                Py_DECREF(elem);
             }
         }
         else {
             PyObject *tail;
-            ParentLocator *next = it->parent_stack->next;
+            ParentLocator *next;
             if (it->gettext) {
+                Py_INCREF(cur_parent);
                 tail = element_get_tail(cur_parent);
-                if (!tail)
+                if (!tail) {
+                    Py_DECREF(cur_parent);
                     return NULL;
+                }
+                Py_INCREF(tail);
+                Py_DECREF(cur_parent);
             }
-            else
+            else {
                 tail = Py_None;
-            Py_XDECREF(it->parent_stack->parent);
+                Py_INCREF(tail);
+            }
+            next = it->parent_stack->next;
+            cur_parent = it->parent_stack->parent;
             PyObject_Free(it->parent_stack);
             it->parent_stack = next;
+            Py_XDECREF(cur_parent);
 
             /* Note that extra condition on it->parent_stack->parent here;
              * this is because itertext() is supposed to only return *inner*
@@ -2170,12 +2201,14 @@ elementiter_next(ElementIterObject *it)
              */
             if (it->parent_stack->parent) {
                 rc = PyObject_IsTrue(tail);
+                if (rc > 0)
+                    return tail;
+                Py_DECREF(tail);
                 if (rc < 0)
                     return NULL;
-                if (rc) {
-                    Py_INCREF(tail);
-                    return tail;
-                }
+            }
+            else {
+                Py_DECREF(tail);
             }
         }
     }
@@ -2238,17 +2271,6 @@ create_elementiter(ElementObject *self, PyObject *tag, int gettext)
     if (!it)
         return NULL;
 
-    if (PyUnicode_Check(tag)) {
-        if (PyUnicode_READY(tag) < 0)
-            return NULL;
-        if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*')
-            tag = Py_None;
-    }
-    else if (PyBytes_Check(tag)) {
-        if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*')
-            tag = Py_None;
-    }
-
     Py_INCREF(tag);
     it->sought_tag = tag;
     it->root_done = 0;
@@ -2452,6 +2474,23 @@ treebuilder_add_subelement(PyObject *element, PyObject *child)
     }
 }
 
+LOCAL(int)
+treebuilder_append_event(TreeBuilderObject *self, PyObject *action,
+                         PyObject *node)
+{
+    if (action != NULL) {
+        PyObject *res = PyTuple_Pack(2, action, node);
+        if (res == NULL)
+            return -1;
+        if (PyList_Append(self->events, res) < 0) {
+            Py_DECREF(res);
+            return -1;
+        }
+        Py_DECREF(res);
+    }
+    return 0;
+}
+
 /* -------------------------------------------------------------------- */
 /* handlers */
 
@@ -2511,24 +2550,13 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
     }
     self->index++;
 
-    Py_DECREF(this);
     Py_INCREF(node);
-    self->this = node;
-
-    Py_DECREF(self->last);
+    Py_SETREF(self->this, node);
     Py_INCREF(node);
-    self->last = node;
+    Py_SETREF(self->last, node);
 
-    if (self->start_event_obj) {
-        PyObject* res;
-        PyObject* action = self->start_event_obj;
-        res = PyTuple_Pack(2, action, node);
-        if (res) {
-            PyList_Append(self->events, res);
-            Py_DECREF(res);
-        } else
-            PyErr_Clear(); /* FIXME: propagate error */
-    }
+    if (treebuilder_append_event(self, self->start_event_obj, node) < 0)
+        goto error;
 
     return node;
 
@@ -2598,75 +2626,20 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
         return NULL;
     }
 
-    self->index--;
-
-    item = PyList_GET_ITEM(self->stack, self->index);
-    Py_INCREF(item);
-
-    Py_DECREF(self->last);
-
+    item = self->last;
     self->last = self->this;
-    self->this = item;
+    self->index--;
+    self->this = PyList_GET_ITEM(self->stack, self->index);
+    Py_INCREF(self->this);
+    Py_DECREF(item);
 
-    if (self->end_event_obj) {
-        PyObject* res;
-        PyObject* action = self->end_event_obj;
-        PyObject* node = (PyObject*) self->last;
-        res = PyTuple_Pack(2, action, node);
-        if (res) {
-            PyList_Append(self->events, res);
-            Py_DECREF(res);
-        } else
-            PyErr_Clear(); /* FIXME: propagate error */
-    }
+    if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0)
+        return NULL;
 
     Py_INCREF(self->last);
     return (PyObject*) self->last;
 }
 
-LOCAL(void)
-treebuilder_handle_namespace(TreeBuilderObject* self, int start,
-                             PyObject *prefix, PyObject *uri)
-{
-    PyObject* res;
-    PyObject* action;
-    PyObject* parcel;
-
-    if (!self->events)
-        return;
-
-    if (start) {
-        if (!self->start_ns_event_obj)
-            return;
-        action = self->start_ns_event_obj;
-        parcel = Py_BuildValue("OO", prefix, uri);
-        if (!parcel)
-            return;
-        Py_INCREF(action);
-    } else {
-        if (!self->end_ns_event_obj)
-            return;
-        action = self->end_ns_event_obj;
-        Py_INCREF(action);
-        parcel = Py_None;
-        Py_INCREF(parcel);
-    }
-
-    res = PyTuple_New(2);
-
-    if (res) {
-        PyTuple_SET_ITEM(res, 0, action);
-        PyTuple_SET_ITEM(res, 1, parcel);
-        PyList_Append(self->events, res);
-        Py_DECREF(res);
-    }
-    else {
-        Py_DECREF(action);
-        Py_DECREF(parcel);
-        PyErr_Clear(); /* FIXME: propagate error */
-    }
-}
-
 /* -------------------------------------------------------------------- */
 /* methods (in alphabetical order) */
 
@@ -2978,8 +2951,10 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
     /* attributes */
     if (attrib_in[0]) {
         attrib = PyDict_New();
-        if (!attrib)
+        if (!attrib) {
+            Py_DECREF(tag);
             return;
+        }
         while (attrib_in[0] && attrib_in[1]) {
             PyObject* key = makeuniversal(self, attrib_in[0]);
             PyObject* value = PyUnicode_DecodeUTF8(attrib_in[1], strlen(attrib_in[1]), "strict");
@@ -2987,6 +2962,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
                 Py_XDECREF(value);
                 Py_XDECREF(key);
                 Py_DECREF(attrib);
+                Py_DECREF(tag);
                 return;
             }
             ok = PyDict_SetItem(attrib, key, value);
@@ -2994,6 +2970,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
             Py_DECREF(key);
             if (ok < 0) {
                 Py_DECREF(attrib);
+                Py_DECREF(tag);
                 return;
             }
             attrib_in += 2;
@@ -3001,8 +2978,10 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
     } else {
         /* Pass an empty dictionary on */
         attrib = PyDict_New();
-        if (!attrib)
+        if (!attrib) {
+            Py_DECREF(tag);
             return;
+        }
     }
 
     if (TreeBuilder_CheckExact(self->target)) {
@@ -3078,45 +3057,39 @@ static void
 expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix,
                        const XML_Char *uri)
 {
-    PyObject* sprefix = NULL;
-    PyObject* suri = NULL;
+    TreeBuilderObject *target = (TreeBuilderObject*) self->target;
+    PyObject *parcel;
 
     if (PyErr_Occurred())
         return;
 
-    if (uri)
-        suri = PyUnicode_DecodeUTF8(uri, strlen(uri), "strict");
-    else
-        suri = PyUnicode_FromString("");
-    if (!suri)
-        return;
-
-    if (prefix)
-        sprefix = PyUnicode_DecodeUTF8(prefix, strlen(prefix), "strict");
-    else
-        sprefix = PyUnicode_FromString("");
-    if (!sprefix) {
-        Py_DECREF(suri);
+    if (!target->events || !target->start_ns_event_obj)
         return;
-    }
 
-    treebuilder_handle_namespace(
-        (TreeBuilderObject*) self->target, 1, sprefix, suri
-        );
+    if (!uri)
+        uri = "";
+    if (!prefix)
+        prefix = "";
 
-    Py_DECREF(sprefix);
-    Py_DECREF(suri);
+    parcel = Py_BuildValue("ss", prefix, uri);
+    if (!parcel)
+        return;
+    treebuilder_append_event(target, target->start_ns_event_obj, parcel);
+    Py_DECREF(parcel);
 }
 
 static void
 expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in)
 {
+    TreeBuilderObject *target = (TreeBuilderObject*) self->target;
+
     if (PyErr_Occurred())
         return;
 
-    treebuilder_handle_namespace(
-        (TreeBuilderObject*) self->target, 0, NULL, NULL
-        );
+    if (!target->events)
+        return;
+
+    treebuilder_append_event(target, target->end_ns_event_obj, Py_None);
 }
 
 static void
@@ -3615,7 +3588,7 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
 /*[clinic end generated code: output=1440092922b13ed1 input=59db9742910c6174]*/
 {
     /* activate element event reporting */
-    Py_ssize_t i, seqlen;
+    Py_ssize_t i;
     TreeBuilderObject *target;
     PyObject *events_seq;
 
@@ -3631,8 +3604,7 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
     target = (TreeBuilderObject*) self->target;
 
     Py_INCREF(events_queue);
-    Py_XDECREF(target->events);
-    target->events = events_queue;
+    Py_XSETREF(target->events, events_queue);
 
     /* clear out existing events */
     Py_CLEAR(target->start_event_obj);
@@ -3651,46 +3623,41 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
         return NULL;
     }
 
-    seqlen = PySequence_Size(events_seq);
-    for (i = 0; i < seqlen; ++i) {
+    for (i = 0; i < PySequence_Size(events_seq); ++i) {
         PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i);
         char *event_name = NULL;
         if (PyUnicode_Check(event_name_obj)) {
-            event_name = _PyUnicode_AsString(event_name_obj);
+            event_name = PyUnicode_AsUTF8(event_name_obj);
         } else if (PyBytes_Check(event_name_obj)) {
             event_name = PyBytes_AS_STRING(event_name_obj);
         }
-
         if (event_name == NULL) {
             Py_DECREF(events_seq);
             PyErr_Format(PyExc_ValueError, "invalid events sequence");
             return NULL;
-        } else if (strcmp(event_name, "start") == 0) {
-            Py_INCREF(event_name_obj);
-            target->start_event_obj = event_name_obj;
+        }
+
+        Py_INCREF(event_name_obj);
+        if (strcmp(event_name, "start") == 0) {
+            Py_XSETREF(target->start_event_obj, event_name_obj);
         } else if (strcmp(event_name, "end") == 0) {
-            Py_INCREF(event_name_obj);
-            Py_XDECREF(target->end_event_obj);
-            target->end_event_obj = event_name_obj;
+            Py_XSETREF(target->end_event_obj, event_name_obj);
         } else if (strcmp(event_name, "start-ns") == 0) {
-            Py_INCREF(event_name_obj);
-            Py_XDECREF(target->start_ns_event_obj);
-            target->start_ns_event_obj = event_name_obj;
+            Py_XSETREF(target->start_ns_event_obj, event_name_obj);
             EXPAT(SetNamespaceDeclHandler)(
                 self->parser,
                 (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
                 (XML_EndNamespaceDeclHandler) expat_end_ns_handler
                 );
         } else if (strcmp(event_name, "end-ns") == 0) {
-            Py_INCREF(event_name_obj);
-            Py_XDECREF(target->end_ns_event_obj);
-            target->end_ns_event_obj = event_name_obj;
+            Py_XSETREF(target->end_ns_event_obj, event_name_obj);
             EXPAT(SetNamespaceDeclHandler)(
                 self->parser,
                 (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
                 (XML_EndNamespaceDeclHandler) expat_end_ns_handler
                 );
         } else {
+            Py_DECREF(event_name_obj);
             Py_DECREF(events_seq);
             PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name);
             return NULL;
index fadc0a9..1aa4571 100644 (file)
@@ -34,7 +34,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
         return NULL;
     }
 
-    pargs = pkw = Py_None;
+    pargs = pkw = NULL;
     func = PyTuple_GET_ITEM(args, 0);
     if (Py_TYPE(func) == &partial_type && type == &partial_type) {
         partialobject *part = (partialobject *)func;
@@ -42,6 +42,8 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
             pargs = part->args;
             pkw = part->kw;
             func = part->fn;
+            assert(PyTuple_Check(pargs));
+            assert(PyDict_Check(pkw));
         }
     }
     if (!PyCallable_Check(func)) {
@@ -60,12 +62,10 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
 
     nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
     if (nargs == NULL) {
-        pto->args = NULL;
-        pto->kw = NULL;
         Py_DECREF(pto);
         return NULL;
     }
-    if (pargs == Py_None || PyTuple_GET_SIZE(pargs) == 0) {
+    if (pargs == NULL || PyTuple_GET_SIZE(pargs) == 0) {
         pto->args = nargs;
         Py_INCREF(nargs);
     }
@@ -76,47 +76,36 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
     else {
         pto->args = PySequence_Concat(pargs, nargs);
         if (pto->args == NULL) {
-            pto->kw = NULL;
+            Py_DECREF(nargs);
             Py_DECREF(pto);
             return NULL;
         }
+        assert(PyTuple_Check(pto->args));
     }
     Py_DECREF(nargs);
 
-    if (kw != NULL) {
-        if (pkw == Py_None) {
-            pto->kw = PyDict_Copy(kw);
+    if (pkw == NULL || PyDict_Size(pkw) == 0) {
+        if (kw == NULL) {
+            pto->kw = PyDict_New();
         }
         else {
-            pto->kw = PyDict_Copy(pkw);
-            if (pto->kw != NULL) {
-                if (PyDict_Merge(pto->kw, kw, 1) != 0) {
-                    Py_DECREF(pto);
-                    return NULL;
-                }
-            }
-        }
-        if (pto->kw == NULL) {
-            Py_DECREF(pto);
-            return NULL;
+            Py_INCREF(kw);
+            pto->kw = kw;
         }
     }
     else {
-        if (pkw == Py_None) {
-            pto->kw = PyDict_New();
-            if (pto->kw == NULL) {
+        pto->kw = PyDict_Copy(pkw);
+        if (kw != NULL && pto->kw != NULL) {
+            if (PyDict_Merge(pto->kw, kw, 1) != 0) {
                 Py_DECREF(pto);
                 return NULL;
             }
         }
-        else {
-            pto->kw = pkw;
-            Py_INCREF(pkw);
-        }
     }
-
-    pto->weakreflist = NULL;
-    pto->dict = NULL;
+    if (pto->kw == NULL) {
+        Py_DECREF(pto);
+        return NULL;
+    }
 
     return (PyObject *)pto;
 }
@@ -138,11 +127,11 @@ static PyObject *
 partial_call(partialobject *pto, PyObject *args, PyObject *kw)
 {
     PyObject *ret;
-    PyObject *argappl = NULL, *kwappl = NULL;
+    PyObject *argappl, *kwappl;
 
     assert (PyCallable_Check(pto->fn));
     assert (PyTuple_Check(pto->args));
-    assert (pto->kw == Py_None  ||  PyDict_Check(pto->kw));
+    assert (PyDict_Check(pto->kw));
 
     if (PyTuple_GET_SIZE(pto->args) == 0) {
         argappl = args;
@@ -154,11 +143,12 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kw)
         argappl = PySequence_Concat(pto->args, args);
         if (argappl == NULL)
             return NULL;
+        assert(PyTuple_Check(argappl));
     }
 
-    if (pto->kw == Py_None) {
+    if (PyDict_Size(pto->kw) == 0) {
         kwappl = kw;
-        Py_XINCREF(kw);
+        Py_XINCREF(kwappl);
     } else {
         kwappl = PyDict_Copy(pto->kw);
         if (kwappl == NULL) {
@@ -217,6 +207,7 @@ partial_repr(partialobject *pto)
     PyObject *arglist;
     PyObject *tmp;
     Py_ssize_t i, n;
+    PyObject *key, *value;
 
     arglist = PyUnicode_FromString("");
     if (arglist == NULL) {
@@ -234,17 +225,14 @@ partial_repr(partialobject *pto)
         arglist = tmp;
     }
     /* Pack keyword arguments */
-    assert (pto->kw == Py_None  ||  PyDict_Check(pto->kw));
-    if (pto->kw != Py_None) {
-        PyObject *key, *value;
-        for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) {
-            tmp = PyUnicode_FromFormat("%U, %U=%R", arglist,
-                                       key, value);
-            Py_DECREF(arglist);
-            if (tmp == NULL)
-                return NULL;
-            arglist = tmp;
-        }
+    assert (PyDict_Check(pto->kw));
+    for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) {
+        tmp = PyUnicode_FromFormat("%U, %U=%R", arglist,
+                                    key, value);
+        Py_DECREF(arglist);
+        if (tmp == NULL)
+            return NULL;
+        arglist = tmp;
     }
     result = PyUnicode_FromFormat("%s(%R%U)", Py_TYPE(pto)->tp_name,
                                   pto->fn, arglist);
@@ -271,25 +259,45 @@ static PyObject *
 partial_setstate(partialobject *pto, PyObject *state)
 {
     PyObject *fn, *fnargs, *kw, *dict;
-    if (!PyArg_ParseTuple(state, "OOOO",
-                          &fn, &fnargs, &kw, &dict))
+
+    if (!PyTuple_Check(state) ||
+        !PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) ||
+        !PyCallable_Check(fn) ||
+        !PyTuple_Check(fnargs) ||
+        (kw != Py_None && !PyDict_Check(kw)))
+    {
+        PyErr_SetString(PyExc_TypeError, "invalid partial state");
+        return NULL;
+    }
+
+    if(!PyTuple_CheckExact(fnargs))
+        fnargs = PySequence_Tuple(fnargs);
+    else
+        Py_INCREF(fnargs);
+    if (fnargs == NULL)
+        return NULL;
+
+    if (kw == Py_None)
+        kw = PyDict_New();
+    else if(!PyDict_CheckExact(kw))
+        kw = PyDict_Copy(kw);
+    else
+        Py_INCREF(kw);
+    if (kw == NULL) {
+        Py_DECREF(fnargs);
         return NULL;
-    Py_XDECREF(pto->fn);
-    Py_XDECREF(pto->args);
-    Py_XDECREF(pto->kw);
-    Py_XDECREF(pto->dict);
-    pto->fn = fn;
-    pto->args = fnargs;
-    pto->kw = kw;
-    if (dict != Py_None) {
-      pto->dict = dict;
-      Py_INCREF(dict);
-    } else {
-      pto->dict = NULL;
     }
+
     Py_INCREF(fn);
-    Py_INCREF(fnargs);
-    Py_INCREF(kw);
+    if (dict == Py_None)
+        dict = NULL;
+    else
+        Py_INCREF(dict);
+
+    Py_SETREF(pto->fn, fn);
+    Py_SETREF(pto->args, fnargs);
+    Py_SETREF(pto->kw, kw);
+    Py_XSETREF(pto->dict, dict);
     Py_RETURN_NONE;
 }
 
@@ -1053,6 +1061,20 @@ lru_cache_reduce(PyObject *self, PyObject *unused)
     return PyObject_GetAttrString(self, "__qualname__");
 }
 
+static PyObject *
+lru_cache_copy(PyObject *self, PyObject *unused)
+{
+    Py_INCREF(self);
+    return self;
+}
+
+static PyObject *
+lru_cache_deepcopy(PyObject *self, PyObject *unused)
+{
+    Py_INCREF(self);
+    return self;
+}
+
 static int
 lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
 {
@@ -1104,6 +1126,8 @@ static PyMethodDef lru_cache_methods[] = {
     {"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS},
     {"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS},
     {"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS},
+    {"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS},
+    {"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS},
     {NULL}
 };
 
index c343862..136abf5 100644 (file)
@@ -550,7 +550,7 @@ representation for a tournament.  The numbers below are `k', not a[k]:\n\
 \n\
 \n\
 In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'.  In\n\
-an usual binary tournament we see in sports, each cell is the winner\n\
+a usual binary tournament we see in sports, each cell is the winner\n\
 over the two cells it tops, and we can trace the winner down the tree\n\
 to see all opponents s/he had.  However, in many computer applications\n\
 of such tournaments, we do not need to trace the history of a winner.\n\
index 29e000b..6d67751 100644 (file)
@@ -190,8 +190,8 @@ bufferediobase_read1(PyObject *self, PyObject *args)
 PyDoc_STRVAR(bufferediobase_write_doc,
     "Write the given buffer to the IO stream.\n"
     "\n"
-    "Returns the number of bytes written, which is never less than\n"
-    "len(b).\n"
+    "Returns the number of bytes written, which is always the length of b\n"
+    "in bytes.\n"
     "\n"
     "Raises BlockingIOError if the buffer is full and the\n"
     "underlying raw stream cannot accept more data at the moment.\n");
@@ -423,7 +423,7 @@ buffered_sizeof(buffered *self, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(buffered);
+    res = _PyObject_SIZE(Py_TYPE(self));
     if (self->buffer)
         res += self->buffer_size;
     return PyLong_FromSsize_t(res);
@@ -1196,8 +1196,7 @@ found:
         Py_CLEAR(res);
         goto end;
     }
-    Py_CLEAR(res);
-    res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
+    Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
 
 end:
     LEAVE_BUFFERED(self)
@@ -1452,9 +1451,8 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw,
     if (_PyIOBase_check_readable(raw, Py_True) == NULL)
         return -1;
 
-    Py_CLEAR(self->raw);
     Py_INCREF(raw);
-    self->raw = raw;
+    Py_XSETREF(self->raw, raw);
     self->buffer_size = buffer_size;
     self->readable = 1;
     self->writable = 0;
@@ -1805,9 +1803,8 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
     if (_PyIOBase_check_writable(raw, Py_True) == NULL)
         return -1;
 
-    Py_CLEAR(self->raw);
     Py_INCREF(raw);
-    self->raw = raw;
+    Py_XSETREF(self->raw, raw);
     self->readable = 0;
     self->writable = 1;
 
@@ -2309,9 +2306,8 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
     if (_PyIOBase_check_writable(raw, Py_True) == NULL)
         return -1;
 
-    Py_CLEAR(self->raw);
     Py_INCREF(raw);
-    self->raw = raw;
+    Py_XSETREF(self->raw, raw);
     self->buffer_size = buffer_size;
     self->readable = 1;
     self->writable = 1;
@@ -2402,7 +2398,6 @@ static PyMethodDef bufferedreader_methods[] = {
     {"close", (PyCFunction)buffered_close, METH_NOARGS},
     {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
     {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
-    {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
     {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
     {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
     {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
@@ -2493,7 +2488,6 @@ static PyMethodDef bufferedwriter_methods[] = {
     {"close", (PyCFunction)buffered_close, METH_NOARGS},
     {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
     {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
-    {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
     {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
     {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
     {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
index 31cc1f7..9e5d78b 100644 (file)
@@ -548,15 +548,15 @@ _io.BytesIO.readinto
     buffer: Py_buffer(accept={rwbuffer})
     /
 
-Read up to len(buffer) bytes into buffer.
+Read bytes into buffer.
 
 Returns number of bytes read (0 for EOF), or None if the object
-is set not to block as has no data to read.
+is set not to block and has no data to read.
 [clinic start generated code]*/
 
 static PyObject *
 _io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
-/*[clinic end generated code: output=a5d407217dcf0639 input=71581f32635c3a31]*/
+/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
 {
     Py_ssize_t len, n;
 
@@ -969,8 +969,7 @@ _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
     if (initvalue && initvalue != Py_None) {
         if (PyBytes_CheckExact(initvalue)) {
             Py_INCREF(initvalue);
-            Py_XDECREF(self->buf);
-            self->buf = initvalue;
+            Py_XSETREF(self->buf, initvalue);
             self->string_size = PyBytes_GET_SIZE(initvalue);
         }
         else {
@@ -991,7 +990,7 @@ bytesio_sizeof(bytesio *self, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(bytesio);
+    res = _PyObject_SIZE(Py_TYPE(self));
     if (self->buf && !SHARED_BUF(self))
         res += _PySys_GetSizeOf(self->buf);
     return PyLong_FromSsize_t(res);
index 1ab1d65..5f2abb0 100644 (file)
@@ -259,10 +259,10 @@ PyDoc_STRVAR(_io_BytesIO_readinto__doc__,
 "readinto($self, buffer, /)\n"
 "--\n"
 "\n"
-"Read up to len(buffer) bytes into buffer.\n"
+"Read bytes into buffer.\n"
 "\n"
 "Returns number of bytes read (0 for EOF), or None if the object\n"
-"is set not to block as has no data to read.");
+"is set not to block and has no data to read.");
 
 #define _IO_BYTESIO_READINTO_METHODDEF    \
     {"readinto", (PyCFunction)_io_BytesIO_readinto, METH_O, _io_BytesIO_readinto__doc__},
@@ -419,4 +419,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=500ccc149587fac4 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=60ce2c6272718431 input=a9049054013a1b77]*/
index 4a1205e..1042008 100644 (file)
@@ -222,7 +222,7 @@ PyDoc_STRVAR(_io_FileIO_write__doc__,
 "write($self, b, /)\n"
 "--\n"
 "\n"
-"Write bytes b to file, return number written.\n"
+"Write buffer b to file, return number of bytes written.\n"
 "\n"
 "Only makes one system call, so not all of the data may be written.\n"
 "The number of bytes actually written is returned.  In non-blocking mode,\n"
@@ -364,4 +364,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored))
 #ifndef _IO_FILEIO_TRUNCATE_METHODDEF
     #define _IO_FILEIO_TRUNCATE_METHODDEF
 #endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */
-/*[clinic end generated code: output=b1a20b10c81add64 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=dcbc39b466598492 input=a9049054013a1b77]*/
index 3cea079..9762f11 100644 (file)
@@ -66,7 +66,7 @@ PyDoc_STRVAR(_io__IOBase_seekable__doc__,
 "\n"
 "Return whether object supports random access.\n"
 "\n"
-"If False, seek(), tell() and truncate() will raise UnsupportedOperation.\n"
+"If False, seek(), tell() and truncate() will raise OSError.\n"
 "This method may need to do a test seek().");
 
 #define _IO__IOBASE_SEEKABLE_METHODDEF    \
@@ -87,7 +87,7 @@ PyDoc_STRVAR(_io__IOBase_readable__doc__,
 "\n"
 "Return whether object was opened for reading.\n"
 "\n"
-"If False, read() will raise UnsupportedOperation.");
+"If False, read() will raise OSError.");
 
 #define _IO__IOBASE_READABLE_METHODDEF    \
     {"readable", (PyCFunction)_io__IOBase_readable, METH_NOARGS, _io__IOBase_readable__doc__},
@@ -107,7 +107,7 @@ PyDoc_STRVAR(_io__IOBase_writable__doc__,
 "\n"
 "Return whether object was opened for writing.\n"
 "\n"
-"If False, write() will raise UnsupportedOperation.");
+"If False, write() will raise OSError.");
 
 #define _IO__IOBASE_WRITABLE_METHODDEF    \
     {"writable", (PyCFunction)_io__IOBase_writable, METH_NOARGS, _io__IOBase_writable__doc__},
@@ -127,7 +127,7 @@ PyDoc_STRVAR(_io__IOBase_fileno__doc__,
 "\n"
 "Returns underlying file descriptor if one exists.\n"
 "\n"
-"An IOError is raised if the IO object does not use a file descriptor.");
+"OSError is raised if the IO object does not use a file descriptor.");
 
 #define _IO__IOBASE_FILENO_METHODDEF    \
     {"fileno", (PyCFunction)_io__IOBase_fileno, METH_NOARGS, _io__IOBase_fileno__doc__},
@@ -276,4 +276,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
     return _io__RawIOBase_readall_impl(self);
 }
-/*[clinic end generated code: output=fe034152b6884e65 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b874952f5cc248a4 input=a9049054013a1b77]*/
index 12e37bb..919cf50 100644 (file)
@@ -250,6 +250,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
     int *atomic_flag_works = NULL;
 #endif
     struct _Py_stat_struct fdfstat;
+    int fstat_result;
     int async_err = 0;
 
     assert(PyFileIO_Check(self));
@@ -420,7 +421,13 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
 
             self->fd = _PyLong_AsInt(fdobj);
             Py_DECREF(fdobj);
-            if (self->fd == -1) {
+            if (self->fd < 0) {
+                if (!PyErr_Occurred()) {
+                    /* The opener returned a negative but didn't set an
+                       exception.  See issue #27066 */
+                    PyErr_Format(PyExc_ValueError,
+                                 "opener returned %d", self->fd);
+                }
                 goto error;
             }
         }
@@ -438,22 +445,39 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
     }
 
     self->blksize = DEFAULT_BUFFER_SIZE;
-    if (_Py_fstat(self->fd, &fdfstat) < 0)
-        goto error;
-#if defined(S_ISDIR) && defined(EISDIR)
-    /* On Unix, open will succeed for directories.
-       In Python, there should be no file objects referring to
-       directories, so we need a check.  */
-    if (S_ISDIR(fdfstat.st_mode)) {
-        errno = EISDIR;
-        PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
-        goto error;
+    Py_BEGIN_ALLOW_THREADS
+    fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
+    Py_END_ALLOW_THREADS
+    if (fstat_result < 0) {
+        /* Tolerate fstat() errors other than EBADF.  See Issue #25717, where
+        an anonymous file on a Virtual Box shared folder filesystem would
+        raise ENOENT. */
+#ifdef MS_WINDOWS
+        if (GetLastError() == ERROR_INVALID_HANDLE) {
+            PyErr_SetFromWindowsErr(0);
+#else
+        if (errno == EBADF) {
+            PyErr_SetFromErrno(PyExc_OSError);
+#endif
+            goto error;
+        }
     }
+    else {
+#if defined(S_ISDIR) && defined(EISDIR)
+        /* On Unix, open will succeed for directories.
+           In Python, there should be no file objects referring to
+           directories, so we need a check.  */
+        if (S_ISDIR(fdfstat.st_mode)) {
+            errno = EISDIR;
+            PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
+            goto error;
+        }
 #endif /* defined(S_ISDIR) */
 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
-    if (fdfstat.st_blksize > 1)
-        self->blksize = fdfstat.st_blksize;
+        if (fdfstat.st_blksize > 1)
+            self->blksize = fdfstat.st_blksize;
 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
+    }
 
 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
     /* don't translate newlines (\r\n <=> \n) */
@@ -818,7 +842,7 @@ _io.FileIO.write
     b: Py_buffer
     /
 
-Write bytes b to file, return number written.
+Write buffer b to file, return number of bytes written.
 
 Only makes one system call, so not all of the data may be written.
 The number of bytes actually written is returned.  In non-blocking mode,
@@ -827,7 +851,7 @@ returns None if the write would block.
 
 static PyObject *
 _io_FileIO_write_impl(fileio *self, Py_buffer *b)
-/*[clinic end generated code: output=b4059db3d363a2f7 input=ffbd8834f447ac31]*/
+/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/
 {
     Py_ssize_t n;
     int err;
index 025007e..212b0dd 100644 (file)
@@ -53,8 +53,9 @@ PyDoc_STRVAR(iobase_doc,
     "called.\n"
     "\n"
     "The basic type used for binary data read from or written to a file is\n"
-    "bytes. bytearrays are accepted too, and in some cases (such as\n"
-    "readinto) needed. Text I/O classes work with str data.\n"
+    "bytes. Other bytes-like objects are accepted as method arguments too.\n"
+    "In some cases (such as readinto), a writable object is required. Text\n"
+    "I/O classes work with str data.\n"
     "\n"
     "Note that calling any method (except additional calls to close(),\n"
     "which are ignored) on a closed stream should raise a ValueError.\n"
@@ -335,13 +336,13 @@ _io._IOBase.seekable
 
 Return whether object supports random access.
 
-If False, seek(), tell() and truncate() will raise UnsupportedOperation.
+If False, seek(), tell() and truncate() will raise OSError.
 This method may need to do a test seek().
 [clinic start generated code]*/
 
 static PyObject *
 _io__IOBase_seekable_impl(PyObject *self)
-/*[clinic end generated code: output=4c24c67f5f32a43d input=22676eebb81dcf1e]*/
+/*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/
 {
     Py_RETURN_FALSE;
 }
@@ -368,12 +369,12 @@ _io._IOBase.readable
 
 Return whether object was opened for reading.
 
-If False, read() will raise UnsupportedOperation.
+If False, read() will raise OSError.
 [clinic start generated code]*/
 
 static PyObject *
 _io__IOBase_readable_impl(PyObject *self)
-/*[clinic end generated code: output=e48089250686388b input=12fc3d8f6be46434]*/
+/*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/
 {
     Py_RETURN_FALSE;
 }
@@ -401,12 +402,12 @@ _io._IOBase.writable
 
 Return whether object was opened for writing.
 
-If False, write() will raise UnsupportedOperation.
+If False, write() will raise OSError.
 [clinic start generated code]*/
 
 static PyObject *
 _io__IOBase_writable_impl(PyObject *self)
-/*[clinic end generated code: output=406001d0985be14f input=c17a0bb6a8dfc590]*/
+/*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/
 {
     Py_RETURN_FALSE;
 }
@@ -456,12 +457,12 @@ _io._IOBase.fileno
 
 Returns underlying file descriptor if one exists.
 
-An IOError is raised if the IO object does not use a file descriptor.
+OSError is raised if the IO object does not use a file descriptor.
 [clinic start generated code]*/
 
 static PyObject *
 _io__IOBase_fileno_impl(PyObject *self)
-/*[clinic end generated code: output=7cc0973f0f5f3b73 input=32773c5df4b7eede]*/
+/*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/
 {
     return iobase_unsupported("fileno");
 }
index 73018a5..06b4144 100644 (file)
@@ -913,8 +913,8 @@ stringio_setstate(stringio *self, PyObject *state)
     Py_DECREF(initarg);
 
     /* Restore the buffer state. Even if __init__ did initialize the buffer,
-       we have to initialize it again since __init__ may translates the
-       newlines in the inital_value string. We clearly do not want that
+       we have to initialize it again since __init__ may translate the
+       newlines in the initial_value string. We clearly do not want that
        because the string value in the state tuple has already been translated
        once by __init__. So we do not take any chance and replace object's
        buffer completely. */
index b232b02..063caa6 100644 (file)
@@ -995,8 +995,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
                 "Oi", self->decoder, (int)self->readtranslate);
             if (incrementalDecoder == NULL)
                 goto error;
-            Py_CLEAR(self->decoder);
-            self->decoder = incrementalDecoder;
+            Py_XSETREF(self->decoder, incrementalDecoder);
         }
     }
 
@@ -1374,8 +1373,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text)
 static void
 textiowrapper_set_decoded_chars(textio *self, PyObject *chars)
 {
-    Py_CLEAR(self->decoded_chars);
-    self->decoded_chars = chars;
+    Py_XSETREF(self->decoded_chars, chars);
     self->decoded_chars_used = 0;
 }
 
@@ -1523,8 +1521,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
             dec_buffer = NULL; /* Reference lost to PyBytes_Concat */
             goto fail;
         }
-        Py_CLEAR(self->snapshot);
-        self->snapshot = Py_BuildValue("NN", dec_flags, next_input);
+        Py_XSETREF(self->snapshot, Py_BuildValue("NN", dec_flags, next_input));
     }
     Py_DECREF(input_chunk);
 
@@ -1630,8 +1627,7 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
         if (chunks != NULL) {
             if (result != NULL && PyList_Append(chunks, result) < 0)
                 goto fail;
-            Py_CLEAR(result);
-            result = PyUnicode_Join(_PyIO_empty_str, chunks);
+            Py_XSETREF(result, PyUnicode_Join(_PyIO_empty_str, chunks));
             if (result == NULL)
                 goto fail;
             Py_CLEAR(chunks);
index f63d758..f82af34 100644 (file)
@@ -116,8 +116,6 @@ raise_errmsg(char *msg, PyObject *s, Py_ssize_t end);
 static PyObject *
 encoder_encode_string(PyEncoderObject *s, PyObject *obj);
 static PyObject *
-encoder_encode_long(PyEncoderObject* s UNUSED, PyObject *obj);
-static PyObject *
 encoder_encode_float(PyEncoderObject *s, PyObject *obj);
 
 #define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"')
@@ -1445,38 +1443,9 @@ _encoded_const(PyObject *obj)
 }
 
 static PyObject *
-encoder_encode_long(PyEncoderObject* s UNUSED, PyObject *obj)
-{
-    /* Return the JSON representation of a PyLong and PyLong subclasses.
-       Calls int() on PyLong subclasses in case the str() was changed.
-       Added specifically to deal with IntEnum.  See Issue18264. */
-    PyObject *encoded, *longobj;
-    if (PyLong_CheckExact(obj)) {
-        encoded = PyObject_Str(obj);
-    }
-    else {
-        longobj = PyNumber_Long(obj);
-        if (longobj == NULL) {
-            PyErr_SetString(
-                    PyExc_ValueError,
-                    "Unable to coerce int subclass to int"
-                    );
-            return NULL;
-        }
-        encoded = PyObject_Str(longobj);
-        Py_DECREF(longobj);
-    }
-    return encoded;
-}
-
-
-static PyObject *
 encoder_encode_float(PyEncoderObject *s, PyObject *obj)
 {
-    /* Return the JSON representation of a PyFloat.
-       Modified to call float() on float subclasses in case the subclass
-       changes the repr.  See Issue18264.  */
-    PyObject *encoded, *floatobj;
+    /* Return the JSON representation of a PyFloat. */
     double i = PyFloat_AS_DOUBLE(obj);
     if (!Py_IS_FINITE(i)) {
         if (!s->allow_nan) {
@@ -1496,24 +1465,7 @@ encoder_encode_float(PyEncoderObject *s, PyObject *obj)
             return PyUnicode_FromString("NaN");
         }
     }
-    /* coerce float subclasses to float (primarily for Enum) */
-    if (PyFloat_CheckExact(obj)) {
-        /* Use a better float format here? */
-        encoded = PyObject_Repr(obj);
-    }
-    else {
-        floatobj = PyNumber_Float(obj);
-        if (floatobj == NULL) {
-            PyErr_SetString(
-                    PyExc_ValueError,
-                    "Unable to coerce float subclass to float"
-                    );
-            return NULL;
-        }
-        encoded = PyObject_Repr(floatobj);
-        Py_DECREF(floatobj);
-    }
-    return encoded;
+    return PyFloat_Type.tp_repr(obj);
 }
 
 static PyObject *
@@ -1557,7 +1509,7 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
         return _steal_accumulate(acc, encoded);
     }
     else if (PyLong_Check(obj)) {
-        PyObject *encoded = encoder_encode_long(s, obj);
+        PyObject *encoded = PyLong_Type.tp_str(obj);
         if (encoded == NULL)
             return -1;
         return _steal_accumulate(acc, encoded);
@@ -1722,7 +1674,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
                 goto bail;
         }
         else if (PyLong_Check(key)) {
-            kstr = encoder_encode_long(s, key);
+            kstr = PyLong_Type.tp_str(key);
             if (kstr == NULL) {
                 goto bail;
             }
index 7e4e2df..846dc0e 100644 (file)
@@ -705,7 +705,7 @@ _lzma.LZMACompressor.__init__
 
     check: int(c_default="-1") = unspecified
         The integrity check to use.  For FORMAT_XZ, the default
-        is CHECK_CRC64.  FORMAT_ALONE and FORMAT_RAW do not suport integrity
+        is CHECK_CRC64.  FORMAT_ALONE and FORMAT_RAW do not support integrity
         checks; for these formats, check must be omitted, or be CHECK_NONE.
 
     preset: object = None
@@ -1011,9 +1011,8 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length)
     if (d->eof) {
         d->needs_input = 0;
         if (lzs->avail_in > 0) {
-            Py_CLEAR(d->unused_data);
-            d->unused_data = PyBytes_FromStringAndSize(
-                (char *)lzs->next_in, lzs->avail_in);
+            Py_XSETREF(d->unused_data,
+                      PyBytes_FromStringAndSize((char *)lzs->next_in, lzs->avail_in));
             if (d->unused_data == NULL)
                 goto error;
         }
index 735affc..eb4f3a3 100644 (file)
@@ -460,6 +460,8 @@ itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
     PyObject *obj, *result;
     Py_ssize_t i, nitems=ig->nitems;
 
+    if (kw != NULL && !_PyArg_NoKeywords("itemgetter", kw))
+        return NULL;
     if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj))
         return NULL;
     if (nitems == 1)
@@ -747,6 +749,8 @@ attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
     PyObject *obj, *result;
     Py_ssize_t i, nattrs=ag->nattrs;
 
+    if (kw != NULL && !_PyArg_NoKeywords("attrgetter", kw))
+        return NULL;
     if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &obj))
         return NULL;
     if (ag->nattrs == 1) /* ag->attr is always a tuple */
@@ -988,6 +992,8 @@ methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
 {
     PyObject *method, *obj, *result;
 
+    if (kw != NULL && !_PyArg_NoKeywords("methodcaller", kw))
+        return NULL;
     if (!PyArg_UnpackTuple(args, "methodcaller", 1, 1, &obj))
         return NULL;
     method = PyObject_GetAttr(obj, mc->name);
index 5f38500..e52da37 100644 (file)
@@ -459,8 +459,8 @@ Pdata_grow(Pdata *self)
 static PyObject *
 Pdata_pop(Pdata *self)
 {
-    PickleState *st = _Pickle_GetGlobalState();
     if (Py_SIZE(self) == 0) {
+        PickleState *st = _Pickle_GetGlobalState();
         PyErr_SetString(st->UnpicklingError, "bad pickle data");
         return NULL;
     }
@@ -550,7 +550,7 @@ typedef struct PicklerObject {
     int bin;                    /* Boolean, true if proto > 0 */
     int framing;                /* True when framing is enabled, proto >= 4 */
     Py_ssize_t frame_start;     /* Position in output_buffer where the
-                                   where the current frame begins. -1 if there
+                                   current frame begins. -1 if there
                                    is no frame currently open. */
 
     Py_ssize_t buf_size;        /* Size of the current buffered pickle data */
@@ -846,9 +846,8 @@ PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value)
 static int
 _Pickler_ClearBuffer(PicklerObject *self)
 {
-    Py_CLEAR(self->output_buffer);
-    self->output_buffer =
-        PyBytes_FromStringAndSize(NULL, self->max_output_len);
+    Py_XSETREF(self->output_buffer,
+              PyBytes_FromStringAndSize(NULL, self->max_output_len));
     if (self->output_buffer == NULL)
         return -1;
     self->output_len = 0;
@@ -1097,7 +1096,7 @@ _Unpickler_SkipConsumed(UnpicklerObject *self)
         return 0;
 
     assert(self->peek);  /* otherwise we did something wrong */
-    /* This makes an useless copy... */
+    /* This makes a useless copy... */
     r = PyObject_CallFunction(self->read, "n", consumed);
     if (r == NULL)
         return -1;
@@ -3089,9 +3088,8 @@ fix_imports(PyObject **module_name, PyObject **global_name)
                          Py_TYPE(item)->tp_name);
             return -1;
         }
-        Py_CLEAR(*module_name);
         Py_INCREF(item);
-        *module_name = item;
+        Py_XSETREF(*module_name, item);
     }
     else if (PyErr_Occurred()) {
         return -1;
@@ -4015,7 +4013,7 @@ _pickle_Pickler___sizeof___impl(PicklerObject *self)
 {
     Py_ssize_t res, s;
 
-    res = sizeof(PicklerObject);
+    res = _PyObject_SIZE(Py_TYPE(self));
     if (self->memo != NULL) {
         res += sizeof(PyMemoTable);
         res += self->memo->mt_allocated * sizeof(PyMemoEntry);
@@ -4631,7 +4629,7 @@ calc_binsize(char *bytes, int nbytes)
 
 /* s contains x bytes of a little-endian integer.  Return its value as a
  * C int.  Obscure:  when x is 1 or 2, this is an unsigned little-endian
- * int, but when x is 4 it's a signed one.  This is an historical source
+ * int, but when x is 4 it's a signed one.  This is a historical source
  * of x-platform bugs.
  */
 static long
@@ -4984,15 +4982,14 @@ load_counted_binunicode(UnpicklerObject *self, int nbytes)
 }
 
 static int
-load_tuple(UnpicklerObject *self)
+load_counted_tuple(UnpicklerObject *self, Py_ssize_t len)
 {
     PyObject *tuple;
-    Py_ssize_t i;
 
-    if ((i = marker(self)) < 0)
-        return -1;
+    if (Py_SIZE(self->stack) < len)
+        return stack_underflow();
 
-    tuple = Pdata_poptuple(self->stack, i);
+    tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len);
     if (tuple == NULL)
         return -1;
     PDATA_PUSH(self->stack, tuple, -1);
@@ -5000,24 +4997,14 @@ load_tuple(UnpicklerObject *self)
 }
 
 static int
-load_counted_tuple(UnpicklerObject *self, int len)
+load_tuple(UnpicklerObject *self)
 {
-    PyObject *tuple;
+    Py_ssize_t i;
 
-    tuple = PyTuple_New(len);
-    if (tuple == NULL)
+    if ((i = marker(self)) < 0)
         return -1;
 
-    while (--len >= 0) {
-        PyObject *item;
-
-        PDATA_POP(self->stack, item);
-        if (item == NULL)
-            return -1;
-        PyTuple_SET_ITEM(tuple, len, item);
-    }
-    PDATA_PUSH(self->stack, tuple, -1);
-    return 0;
+    return load_counted_tuple(self, Py_SIZE(self->stack) - i);
 }
 
 static int
@@ -5148,6 +5135,9 @@ load_obj(UnpicklerObject *self)
     if ((i = marker(self)) < 0)
         return -1;
 
+    if (Py_SIZE(self->stack) - i < 1)
+        return stack_underflow();
+
     args = Pdata_poptuple(self->stack, i + 1);
     if (args == NULL)
         return -1;
@@ -5192,8 +5182,10 @@ load_inst(UnpicklerObject *self)
         return -1;
 
     if ((len = _Unpickler_Readline(self, &s)) >= 0) {
-        if (len < 2)
+        if (len < 2) {
+            Py_DECREF(module_name);
             return bad_readline();
+        }
         class_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
         if (class_name != NULL) {
             cls = find_class(self, module_name, class_name);
@@ -5806,13 +5798,18 @@ do_append(UnpicklerObject *self, Py_ssize_t x)
 static int
 load_append(UnpicklerObject *self)
 {
+    if (Py_SIZE(self->stack) - 1 <= 0)
+        return stack_underflow();
     return do_append(self, Py_SIZE(self->stack) - 1);
 }
 
 static int
 load_appends(UnpicklerObject *self)
 {
-    return do_append(self, marker(self));
+    Py_ssize_t i = marker(self);
+    if (i < 0)
+        return -1;
+    return do_append(self, i);
 }
 
 static int
@@ -5862,7 +5859,10 @@ load_setitem(UnpicklerObject *self)
 static int
 load_setitems(UnpicklerObject *self)
 {
-    return do_setitems(self, marker(self));
+    Py_ssize_t i = marker(self);
+    if (i < 0)
+        return -1;
+    return do_setitems(self, i);
 }
 
 static int
@@ -5872,6 +5872,8 @@ load_additems(UnpicklerObject *self)
     Py_ssize_t mark, len, i;
 
     mark =  marker(self);
+    if (mark < 0)
+        return -1;
     len = Py_SIZE(self->stack);
     if (mark > len || mark <= 0)
         return stack_underflow();
@@ -6414,7 +6416,7 @@ _pickle_Unpickler___sizeof___impl(UnpicklerObject *self)
 {
     Py_ssize_t res;
 
-    res = sizeof(UnpicklerObject);
+    res = _PyObject_SIZE(Py_TYPE(self));
     if (self->memo != NULL)
         res += self->memo_size * sizeof(PyObject *);
     if (self->marks != NULL)
@@ -6518,7 +6520,7 @@ binary file object opened for reading, an io.BytesIO object, or any
 other custom object that meets this interface.
 
 Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
-which are used to control compatiblity support for pickle stream
+which are used to control compatibility support for pickle stream
 generated by Python 2.  If *fix_imports* is True, pickle will try to
 map the old Python 2 names to the new names used in Python 3.  The
 *encoding* and *errors* tell pickle how to decode 8-bit string
@@ -6531,7 +6533,7 @@ static int
 _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file,
                                 int fix_imports, const char *encoding,
                                 const char *errors)
-/*[clinic end generated code: output=e2c8ce748edc57b0 input=04ece661aa884837]*/
+/*[clinic end generated code: output=e2c8ce748edc57b0 input=f9b7da04f5f4f335]*/
 {
     _Py_IDENTIFIER(persistent_load);
 
@@ -7064,7 +7066,7 @@ binary file object opened for reading, an io.BytesIO object, or any
 other custom object that meets this interface.
 
 Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
-which are used to control compatiblity support for pickle stream
+which are used to control compatibility support for pickle stream
 generated by Python 2.  If *fix_imports* is True, pickle will try to
 map the old Python 2 names to the new names used in Python 3.  The
 *encoding* and *errors* tell pickle how to decode 8-bit string
@@ -7076,7 +7078,7 @@ string instances as bytes objects.
 static PyObject *
 _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports,
                   const char *encoding, const char *errors)
-/*[clinic end generated code: output=798f1c57cb2b4eb1 input=2df7c7a1e6742204]*/
+/*[clinic end generated code: output=798f1c57cb2b4eb1 input=01b44dd3fc07afa7]*/
 {
     PyObject *result;
     UnpicklerObject *unpickler = _Unpickler_New();
@@ -7118,7 +7120,7 @@ protocol argument is needed.  Bytes past the pickled object's
 representation are ignored.
 
 Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
-which are used to control compatiblity support for pickle stream
+which are used to control compatibility support for pickle stream
 generated by Python 2.  If *fix_imports* is True, pickle will try to
 map the old Python 2 names to the new names used in Python 3.  The
 *encoding* and *errors* tell pickle how to decode 8-bit string
@@ -7130,7 +7132,7 @@ string instances as bytes objects.
 static PyObject *
 _pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports,
                    const char *encoding, const char *errors)
-/*[clinic end generated code: output=61e9cdb01e36a736 input=f57f0fdaa2b4cb8b]*/
+/*[clinic end generated code: output=61e9cdb01e36a736 input=70605948a719feb9]*/
 {
     PyObject *result;
     UnpicklerObject *unpickler = _Unpickler_New();
index 2cdc381..8bedab5 100644 (file)
 #define POSIX_CALL(call)   do { if ((call) == -1) goto error; } while (0)
 
 
-/* Given the gc module call gc.enable() and return 0 on success. */
+/* If gc was disabled, call gc.enable().  Return 0 on success. */
 static int
-_enable_gc(PyObject *gc_module)
+_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
 {
     PyObject *result;
     _Py_IDENTIFIER(enable);
+    PyObject *exctype, *val, *tb;
 
-    result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
-    if (result == NULL)
-        return 1;
-    Py_DECREF(result);
+    if (need_to_reenable_gc) {
+        PyErr_Fetch(&exctype, &val, &tb);
+        result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
+        if (exctype != NULL) {
+            PyErr_Restore(exctype, val, tb);
+        }
+        if (result == NULL) {
+            return 1;
+        }
+        Py_DECREF(result);
+    }
     return 0;
 }
 
@@ -698,6 +706,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
         && _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) {
         PyErr_SetString(PyExc_RuntimeError,
                         "not holding the import lock");
+        pid = -1;
     }
     import_lock_held = 0;
 #endif
@@ -710,9 +719,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
     _Py_FreeCharPArray(exec_array);
 
     /* Reenable gc in the parent process (or if fork failed). */
-    if (need_to_reenable_gc && _enable_gc(gc_module)) {
-        Py_XDECREF(gc_module);
-        return NULL;
+    if (_enable_gc(need_to_reenable_gc, gc_module)) {
+        pid = -1;
     }
     Py_XDECREF(preexec_fn_args_tuple);
     Py_XDECREF(gc_module);
@@ -736,14 +744,7 @@ cleanup:
     Py_XDECREF(converted_args);
     Py_XDECREF(fast_args);
     Py_XDECREF(preexec_fn_args_tuple);
-
-    /* Reenable gc if it was disabled. */
-    if (need_to_reenable_gc) {
-        PyObject *exctype, *val, *tb;
-        PyErr_Fetch(&exctype, &val, &tb);
-        _enable_gc(gc_module);
-        PyErr_Restore(exctype, val, tb);
-    }
+    _enable_gc(need_to_reenable_gc, gc_module);
     Py_XDECREF(gc_module);
     return NULL;
 }
index a08ebfe..7570624 100644 (file)
@@ -204,8 +204,8 @@ void pysqlite_flush_statement_cache(pysqlite_Connection* self)
         node = node->next;
     }
 
-    Py_DECREF(self->statement_cache);
-    self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "O", self);
+    Py_SETREF(self->statement_cache,
+              (pysqlite_Cache *)PyObject_CallFunction((PyObject *)&pysqlite_CacheType, "O", self));
     Py_DECREF(self);
     self->statement_cache->decref_factory = 0;
 }
@@ -318,9 +318,8 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args,
     _pysqlite_drop_unused_cursor_references(self);
 
     if (cursor && self->row_factory != Py_None) {
-        Py_XDECREF(((pysqlite_Cursor*)cursor)->row_factory);
         Py_INCREF(self->row_factory);
-        ((pysqlite_Cursor*)cursor)->row_factory = self->row_factory;
+        Py_XSETREF(((pysqlite_Cursor *)cursor)->row_factory, self->row_factory);
     }
 
     return cursor;
@@ -795,8 +794,7 @@ static void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self
         }
     }
 
-    Py_DECREF(self->statements);
-    self->statements = new_list;
+    Py_SETREF(self->statements, new_list);
 }
 
 static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self)
@@ -827,8 +825,7 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self)
         }
     }
 
-    Py_DECREF(self->cursors);
-    self->cursors = new_list;
+    Py_SETREF(self->cursors, new_list);
 }
 
 PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
index c1599c0..300da28 100644 (file)
@@ -170,8 +170,7 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
         return 0;
     }
 
-    Py_XDECREF(self->row_cast_map);
-    self->row_cast_map = PyList_New(0);
+    Py_XSETREF(self->row_cast_map, PyList_New(0));
 
     for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
         converter = NULL;
@@ -510,9 +509,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
         goto error;
 
     /* reset description and rowcount */
-    Py_DECREF(self->description);
     Py_INCREF(Py_None);
-    self->description = Py_None;
+    Py_SETREF(self->description, Py_None);
     self->rowcount = -1L;
 
     func_args = PyTuple_New(1);
@@ -526,10 +524,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
 
     if (self->statement) {
         (void)pysqlite_statement_reset(self->statement);
-        Py_DECREF(self->statement);
     }
 
-    self->statement = (pysqlite_Statement*)pysqlite_cache_get(self->connection->statement_cache, func_args);
+    Py_XSETREF(self->statement,
+              (pysqlite_Statement *)pysqlite_cache_get(self->connection->statement_cache, func_args));
     Py_DECREF(func_args);
 
     if (!self->statement) {
@@ -537,8 +535,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
     }
 
     if (self->statement->in_use) {
-        Py_DECREF(self->statement);
-        self->statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType);
+        Py_SETREF(self->statement,
+                  PyObject_New(pysqlite_Statement, &pysqlite_StatementType));
         if (!self->statement) {
             goto error;
         }
@@ -654,8 +652,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
                 numcols = sqlite3_column_count(self->statement->st);
                 Py_END_ALLOW_THREADS
 
-                Py_DECREF(self->description);
-                self->description = PyTuple_New(numcols);
+                Py_SETREF(self->description, PyTuple_New(numcols));
                 if (!self->description) {
                     goto error;
                 }
index 957ccbc..150229d 100644 (file)
@@ -756,8 +756,7 @@ deepcopy(PyObject** object, PyObject* memo)
     if (!copy)
         return 0;
 
-    Py_DECREF(*object);
-    *object = copy;
+    Py_SETREF(*object, copy);
 
     return 1; /* success */
 }
index 67402fe..1117b55 100644 (file)
@@ -1589,8 +1589,7 @@ static int PySSL_set_context(PySSLSocket *self, PyObject *value,
         return -1;
 #else
         Py_INCREF(value);
-        Py_DECREF(self->ctx);
-        self->ctx = (PySSLContext *) value;
+        Py_SETREF(self->ctx, (PySSLContext *)value);
         SSL_set_SSL_CTX(self->ssl, self->ctx->ctx);
 #endif
     } else {
@@ -1647,8 +1646,7 @@ PySSL_get_owner(PySSLSocket *self, void *c)
 static int
 PySSL_set_owner(PySSLSocket *self, PyObject *value, void *c)
 {
-    Py_XDECREF(self->owner);
-    self->owner = PyWeakref_NewRef(value, NULL);
+    Py_XSETREF(self->owner, PyWeakref_NewRef(value, NULL));
     if (self->owner == NULL)
         return -1;
     return 0;
@@ -1897,6 +1895,11 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1,
     _PyTime_t timeout, deadline = 0;
     int has_timeout;
 
+    if (!group_right_1 && len < 0) {
+        PyErr_SetString(PyExc_ValueError, "size should not be negative");
+        return NULL;
+    }
+
     if (sock != NULL) {
         if (((PyObject*)sock) == Py_None) {
             _setSSLError("Underlying socket connection gone",
@@ -2221,6 +2224,9 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
     PySSLContext *self;
     long options;
     SSL_CTX *ctx = NULL;
+#if defined(SSL_MODE_RELEASE_BUFFERS)
+    unsigned long libver;
+#endif
 
     PySSL_BEGIN_ALLOW_THREADS
     if (proto_version == PY_SSL_VERSION_TLS1)
@@ -2283,6 +2289,22 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
         options |= SSL_OP_NO_SSLv3;
     SSL_CTX_set_options(self->ctx, options);
 
+#if defined(SSL_MODE_RELEASE_BUFFERS)
+    /* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory
+       usage for no cost at all. However, don't do this for OpenSSL versions
+       between 1.0.1 and 1.0.1h or 1.0.0 and 1.0.0m, which are affected by CVE
+       2014-0198. I can't find exactly which beta fixed this CVE, so be
+       conservative and assume it wasn't fixed until release. We do this check
+       at runtime to avoid problems from the dynamic linker.
+       See #25672 for more on this. */
+    libver = SSLeay();
+    if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) &&
+        !(libver >= 0x10000000UL && libver < 0x100000dfUL)) {
+        SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS);
+    }
+#endif
+
+
 #ifndef OPENSSL_NO_ECDH
     /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use
        prime256v1 by default.  This is Apache mod_ssl's initialization
@@ -4183,7 +4205,9 @@ _ssl_enum_certificates_impl(PyModuleDef *module, const char *store_name)
     if (result == NULL) {
         return NULL;
     }
-    hStore = CertOpenSystemStore((HCRYPTPROV)NULL, store_name);
+    hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, (HCRYPTPROV)NULL,
+                            CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE,
+                            store_name);
     if (hStore == NULL) {
         Py_DECREF(result);
         return PyErr_SetFromWindowsErr(GetLastError());
@@ -4269,7 +4293,9 @@ _ssl_enum_crls_impl(PyModuleDef *module, const char *store_name)
     if (result == NULL) {
         return NULL;
     }
-    hStore = CertOpenSystemStore((HCRYPTPROV)NULL, store_name);
+    hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, (HCRYPTPROV)NULL,
+                            CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE,
+                            store_name);
     if (hStore == NULL) {
         Py_DECREF(result);
         return PyErr_SetFromWindowsErr(GetLastError());
index 068c5d1..f965541 100644 (file)
@@ -1437,8 +1437,7 @@ s_init(PyObject *self, PyObject *args, PyObject *kwds)
         return -1;
     }
 
-    Py_CLEAR(soself->s_format);
-    soself->s_format = o_format;
+    Py_XSETREF(soself->s_format, o_format);
 
     ret = prepare_s(soself);
     return ret;
@@ -1498,8 +1497,8 @@ PyDoc_STRVAR(s_unpack__doc__,
 "S.unpack(buffer) -> (v1, v2, ...)\n\
 \n\
 Return a tuple containing values unpacked according to the format\n\
-string S.format.  Requires len(buffer) == S.size.  See help(struct)\n\
-for more on format strings.");
+string S.format.  The buffer's size in bytes must be S.size.  See\n\
+help(struct) for more on format strings.");
 
 static PyObject *
 s_unpack(PyObject *self, PyObject *input)
@@ -1528,8 +1527,8 @@ PyDoc_STRVAR(s_unpack_from__doc__,
 "S.unpack_from(buffer, offset=0) -> (v1, v2, ...)\n\
 \n\
 Return a tuple containing values unpacked according to the format\n\
-string S.format.  Requires len(buffer[offset:]) >= S.size.  See\n\
-help(struct) for more on format strings.");
+string S.format.  The buffer's size in bytes, minus offset, must be at\n\
+least S.size.  See help(struct) for more on format strings.");
 
 static PyObject *
 s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
@@ -1924,7 +1923,7 @@ s_sizeof(PyStructObject *self, void *unused)
     Py_ssize_t size;
     formatcode *code;
 
-    size = sizeof(PyStructObject) + sizeof(formatcode);
+    size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
     for (code = self->s_codes; code->fmtdef != NULL; code++)
         size += sizeof(formatcode);
     return PyLong_FromSsize_t(size);
@@ -2131,8 +2130,8 @@ PyDoc_STRVAR(unpack_doc,
 "unpack(fmt, buffer) -> (v1, v2, ...)\n\
 \n\
 Return a tuple containing values unpacked according to the format string\n\
-fmt.  Requires len(buffer) == calcsize(fmt). See help(struct) for more\n\
-on format strings.");
+fmt.  The buffer's size in bytes must be calcsize(fmt). See help(struct)\n\
+for more on format strings.");
 
 static PyObject *
 unpack(PyObject *self, PyObject *args)
@@ -2154,8 +2153,8 @@ PyDoc_STRVAR(unpack_from_doc,
 "unpack_from(fmt, buffer, offset=0) -> (v1, v2, ...)\n\
 \n\
 Return a tuple containing values unpacked according to the format string\n\
-fmt.  Requires len(buffer[offset:]) >= calcsize(fmt).  See help(struct)\n\
-for more on format strings.");
+fmt.  The buffer's size, minus offset, must be at least calcsize(fmt).\n\
+See help(struct) for more on format strings.");
 
 static PyObject *
 unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
index 9a03648..3810e94 100644 (file)
@@ -872,6 +872,120 @@ test_L_code(PyObject *self)
 
 #endif  /* ifdef HAVE_LONG_LONG */
 
+static PyObject *
+return_none(void *unused)
+{
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+raise_error(void *unused)
+{
+    PyErr_SetNone(PyExc_ValueError);
+    return NULL;
+}
+
+static int
+test_buildvalue_N_error(const char *fmt)
+{
+    PyObject *arg, *res;
+
+    arg = PyList_New(0);
+    if (arg == NULL) {
+        return -1;
+    }
+
+    Py_INCREF(arg);
+    res = Py_BuildValue(fmt, return_none, NULL, arg);
+    if (res == NULL) {
+        return -1;
+    }
+    Py_DECREF(res);
+    if (Py_REFCNT(arg) != 1) {
+        PyErr_Format(TestError, "test_buildvalue_N: "
+                     "arg was not decrefed in successful "
+                     "Py_BuildValue(\"%s\")", fmt);
+        return -1;
+    }
+
+    Py_INCREF(arg);
+    res = Py_BuildValue(fmt, raise_error, NULL, arg);
+    if (res != NULL || !PyErr_Occurred()) {
+        PyErr_Format(TestError, "test_buildvalue_N: "
+                     "Py_BuildValue(\"%s\") didn't complain", fmt);
+        return -1;
+    }
+    PyErr_Clear();
+    if (Py_REFCNT(arg) != 1) {
+        PyErr_Format(TestError, "test_buildvalue_N: "
+                     "arg was not decrefed in failed "
+                     "Py_BuildValue(\"%s\")", fmt);
+        return -1;
+    }
+    Py_DECREF(arg);
+    return 0;
+}
+
+static PyObject *
+test_buildvalue_N(PyObject *self, PyObject *noargs)
+{
+    PyObject *arg, *res;
+
+    arg = PyList_New(0);
+    if (arg == NULL) {
+        return NULL;
+    }
+    Py_INCREF(arg);
+    res = Py_BuildValue("N", arg);
+    if (res == NULL) {
+        return NULL;
+    }
+    if (res != arg) {
+        return raiseTestError("test_buildvalue_N",
+                              "Py_BuildValue(\"N\") returned wrong result");
+    }
+    if (Py_REFCNT(arg) != 2) {
+        return raiseTestError("test_buildvalue_N",
+                              "arg was not decrefed in Py_BuildValue(\"N\")");
+    }
+    Py_DECREF(res);
+    Py_DECREF(arg);
+
+    if (test_buildvalue_N_error("O&N") < 0)
+        return NULL;
+    if (test_buildvalue_N_error("(O&N)") < 0)
+        return NULL;
+    if (test_buildvalue_N_error("[O&N]") < 0)
+        return NULL;
+    if (test_buildvalue_N_error("{O&N}") < 0)
+        return NULL;
+    if (test_buildvalue_N_error("{()O&(())N}") < 0)
+        return NULL;
+
+    Py_RETURN_NONE;
+}
+
+
+static PyObject *
+get_args(PyObject *self, PyObject *args)
+{
+    if (args == NULL) {
+        args = Py_None;
+    }
+    Py_INCREF(args);
+    return args;
+}
+
+static PyObject *
+get_kwargs(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    if (kwargs == NULL) {
+        kwargs = Py_None;
+    }
+    Py_INCREF(kwargs);
+    return kwargs;
+}
+
 /* Test tuple argument processing */
 static PyObject *
 getargs_tuple(PyObject *self, PyObject *args)
@@ -1083,12 +1197,78 @@ test_k_code(PyObject *self)
 }
 
 static PyObject *
+getargs_f(PyObject *self, PyObject *args)
+{
+    float f;
+    if (!PyArg_ParseTuple(args, "f", &f))
+        return NULL;
+    return PyFloat_FromDouble(f);
+}
+
+static PyObject *
+getargs_d(PyObject *self, PyObject *args)
+{
+    double d;
+    if (!PyArg_ParseTuple(args, "d", &d))
+        return NULL;
+    return PyFloat_FromDouble(d);
+}
+
+static PyObject *
+getargs_D(PyObject *self, PyObject *args)
+{
+    Py_complex cval;
+    if (!PyArg_ParseTuple(args, "D", &cval))
+        return NULL;
+    return PyComplex_FromCComplex(cval);
+}
+
+static PyObject *
+getargs_S(PyObject *self, PyObject *args)
+{
+    PyObject *obj;
+    if (!PyArg_ParseTuple(args, "S", &obj))
+        return NULL;
+    Py_INCREF(obj);
+    return obj;
+}
+
+static PyObject *
+getargs_Y(PyObject *self, PyObject *args)
+{
+    PyObject *obj;
+    if (!PyArg_ParseTuple(args, "Y", &obj))
+        return NULL;
+    Py_INCREF(obj);
+    return obj;
+}
+
+static PyObject *
+getargs_U(PyObject *self, PyObject *args)
+{
+    PyObject *obj;
+    if (!PyArg_ParseTuple(args, "U", &obj))
+        return NULL;
+    Py_INCREF(obj);
+    return obj;
+}
+
+static PyObject *
 getargs_c(PyObject *self, PyObject *args)
 {
     char c;
     if (!PyArg_ParseTuple(args, "c", &c))
         return NULL;
-    return PyBytes_FromStringAndSize(&c, 1);
+    return PyLong_FromLong((unsigned char)c);
+}
+
+static PyObject *
+getargs_C(PyObject *self, PyObject *args)
+{
+    int c;
+    if (!PyArg_ParseTuple(args, "C", &c))
+        return NULL;
+    return PyLong_FromLong(c);
 }
 
 static PyObject *
@@ -1243,6 +1423,84 @@ getargs_Z_hash(PyObject *self, PyObject *args)
         Py_RETURN_NONE;
 }
 
+static PyObject *
+getargs_es(PyObject *self, PyObject *args)
+{
+    PyObject *arg, *result;
+    const char *encoding = NULL;
+    char *str;
+
+    if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding))
+        return NULL;
+    if (!PyArg_Parse(arg, "es", encoding, &str))
+        return NULL;
+    result = PyBytes_FromString(str);
+    PyMem_Free(str);
+    return result;
+}
+
+static PyObject *
+getargs_et(PyObject *self, PyObject *args)
+{
+    PyObject *arg, *result;
+    const char *encoding = NULL;
+    char *str;
+
+    if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding))
+        return NULL;
+    if (!PyArg_Parse(arg, "et", encoding, &str))
+        return NULL;
+    result = PyBytes_FromString(str);
+    PyMem_Free(str);
+    return result;
+}
+
+static PyObject *
+getargs_es_hash(PyObject *self, PyObject *args)
+{
+    PyObject *arg, *result;
+    const char *encoding = NULL;
+    PyByteArrayObject *buffer = NULL;
+    char *str = NULL;
+    Py_ssize_t size;
+
+    if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer))
+        return NULL;
+    if (buffer != NULL) {
+        str = PyByteArray_AS_STRING(buffer);
+        size = PyByteArray_GET_SIZE(buffer);
+    }
+    if (!PyArg_Parse(arg, "es#", encoding, &str, &size))
+        return NULL;
+    result = PyBytes_FromStringAndSize(str, size);
+    if (buffer == NULL)
+        PyMem_Free(str);
+    return result;
+}
+
+static PyObject *
+getargs_et_hash(PyObject *self, PyObject *args)
+{
+    PyObject *arg, *result;
+    const char *encoding = NULL;
+    PyByteArrayObject *buffer = NULL;
+    char *str = NULL;
+    Py_ssize_t size;
+
+    if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer))
+        return NULL;
+    if (buffer != NULL) {
+        str = PyByteArray_AS_STRING(buffer);
+        size = PyByteArray_GET_SIZE(buffer);
+    }
+    if (!PyArg_Parse(arg, "et#", encoding, &str, &size))
+        return NULL;
+    result = PyBytes_FromStringAndSize(str, size);
+    if (buffer == NULL)
+        PyMem_Free(str);
+    return result;
+}
+
 /* Test the s and z codes for PyArg_ParseTuple.
 */
 static PyObject *
@@ -3564,6 +3822,9 @@ static PyMethodDef TestMethods[] = {
     {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS},
 #endif
     {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O},
+    {"test_buildvalue_N",       test_buildvalue_N,               METH_NOARGS},
+    {"get_args", get_args, METH_VARARGS},
+    {"get_kwargs", (PyCFunction)get_kwargs, METH_VARARGS|METH_KEYWORDS},
     {"getargs_tuple",           getargs_tuple,                   METH_VARARGS},
     {"getargs_keywords", (PyCFunction)getargs_keywords,
       METH_VARARGS|METH_KEYWORDS},
@@ -3587,7 +3848,14 @@ static PyMethodDef TestMethods[] = {
         (PyCFunction)test_long_long_and_overflow, METH_NOARGS},
     {"test_L_code",             (PyCFunction)test_L_code,        METH_NOARGS},
 #endif
+    {"getargs_f",               getargs_f,                       METH_VARARGS},
+    {"getargs_d",               getargs_d,                       METH_VARARGS},
+    {"getargs_D",               getargs_D,                       METH_VARARGS},
+    {"getargs_S",               getargs_S,                       METH_VARARGS},
+    {"getargs_Y",               getargs_Y,                       METH_VARARGS},
+    {"getargs_U",               getargs_U,                       METH_VARARGS},
     {"getargs_c",               getargs_c,                       METH_VARARGS},
+    {"getargs_C",               getargs_C,                       METH_VARARGS},
     {"getargs_s",               getargs_s,                       METH_VARARGS},
     {"getargs_s_star",          getargs_s_star,                  METH_VARARGS},
     {"getargs_s_hash",          getargs_s_hash,                  METH_VARARGS},
@@ -3602,6 +3870,10 @@ static PyMethodDef TestMethods[] = {
     {"getargs_Z",               getargs_Z,                       METH_VARARGS},
     {"getargs_Z_hash",          getargs_Z_hash,                  METH_VARARGS},
     {"getargs_w_star",          getargs_w_star,                  METH_VARARGS},
+    {"getargs_es",              getargs_es,                      METH_VARARGS},
+    {"getargs_et",              getargs_et,                      METH_VARARGS},
+    {"getargs_es_hash",         getargs_es_hash,                 METH_VARARGS},
+    {"getargs_et_hash",         getargs_et_hash,                 METH_VARARGS},
     {"codec_incrementalencoder",
      (PyCFunction)codec_incrementalencoder,                      METH_VARARGS},
     {"codec_incrementaldecoder",
index bcb3aee..968181c 100644 (file)
@@ -159,7 +159,7 @@ lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
 }
 
 PyDoc_STRVAR(acquire_doc,
-"acquire([wait]) -> bool\n\
+"acquire(blocking=True, timeout=-1) -> bool\n\
 (acquire_lock() is an obsolete synonym)\n\
 \n\
 Lock the lock.  Without argument, this blocks if the lock is already\n\
@@ -1134,7 +1134,8 @@ PyDoc_STRVAR(allocate_doc,
 "allocate_lock() -> lock object\n\
 (allocate() is an obsolete synonym)\n\
 \n\
-Create a new lock object.  See help(LockType) for information about locks.");
+Create a new lock object. See help(type(threading.Lock())) for\n\
+information about locks.");
 
 static PyObject *
 thread_get_ident(PyObject *self)
@@ -1326,7 +1327,7 @@ The 'threading' module provides a more convenient interface.");
 
 PyDoc_STRVAR(lock_doc,
 "A lock object is a synchronization primitive.  To create a lock,\n\
-call the PyThread_allocate_lock() function.  Methods are:\n\
+call threading.Lock().  Methods are:\n\
 \n\
 acquire() -- lock the lock, possibly blocking until it can be obtained\n\
 release() -- unlock of the lock\n\
index 41ad5f9..cf56fa8 100644 (file)
@@ -3551,6 +3551,7 @@ PyInit__tkinter(void)
         Py_DECREF(m);
         return NULL;
     }
+    ((PyTypeObject *)o)->tp_new = NULL;
     if (PyModule_AddObject(m, "TkappType", o)) {
         Py_DECREF(o);
         Py_DECREF(m);
@@ -3563,6 +3564,7 @@ PyInit__tkinter(void)
         Py_DECREF(m);
         return NULL;
     }
+    ((PyTypeObject *)o)->tp_new = NULL;
     if (PyModule_AddObject(m, "TkttType", o)) {
         Py_DECREF(o);
         Py_DECREF(m);
@@ -3575,6 +3577,7 @@ PyInit__tkinter(void)
         Py_DECREF(m);
         return NULL;
     }
+    ((PyTypeObject *)o)->tp_new = NULL;
     if (PyModule_AddObject(m, "Tcl_Obj", o)) {
         Py_DECREF(o);
         Py_DECREF(m);
index 226a473..796ac0f 100644 (file)
@@ -66,7 +66,7 @@ _declspec(align(4))
 #endif
 {
     PyObject *filename;
-    int lineno;
+    unsigned int lineno;
 } frame_t;
 
 typedef struct {
@@ -189,7 +189,7 @@ get_reentrant(void)
 static void
 set_reentrant(int reentrant)
 {
-    assert(!reentrant || !get_reentrant());
+    assert(reentrant != tracemalloc_reentrant);
     tracemalloc_reentrant = reentrant;
 }
 #endif
@@ -266,12 +266,13 @@ tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
     PyCodeObject *code;
     PyObject *filename;
     _Py_hashtable_entry_t *entry;
+    int lineno;
 
     frame->filename = unknown_filename;
-    frame->lineno = PyFrame_GetLineNumber(pyframe);
-    assert(frame->lineno >= 0);
-    if (frame->lineno < 0)
-        frame->lineno = 0;
+    lineno = PyFrame_GetLineNumber(pyframe);
+    if (lineno < 0)
+        lineno = 0;
+    frame->lineno = (unsigned int)lineno;
 
     code = pyframe->f_code;
     if (code == NULL) {
@@ -295,7 +296,7 @@ tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame)
 
     if (!PyUnicode_Check(filename)) {
 #ifdef TRACE_DEBUG
-        tracemalloc_error("filename is not an unicode string");
+        tracemalloc_error("filename is not a unicode string");
 #endif
         return;
     }
@@ -375,7 +376,6 @@ traceback_get_frames(traceback_t *traceback)
     for (pyframe = tstate->frame; pyframe != NULL; pyframe = pyframe->f_back) {
         tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]);
         assert(traceback->frames[traceback->nframe].filename != NULL);
-        assert(traceback->frames[traceback->nframe].lineno >= 0);
         traceback->nframe++;
         if (traceback->nframe == tracemalloc_config.max_nframe)
             break;
@@ -519,7 +519,7 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size)
                the caller, because realloc() may already have shrinked the
                memory block and so removed bytes.
 
-               This case is very unlikely: an hash entry has just been
+               This case is very unlikely: a hash entry has just been
                released, so the hash table should have at least one free entry.
 
                The GIL and the table lock ensures that only one thread is
@@ -740,10 +740,6 @@ tracemalloc_clear_traces(void)
     assert(PyGILState_Check());
 #endif
 
-    /* Disable also reentrant calls to tracemalloc_malloc() to not add a new
-       trace while we are clearing traces */
-    assert(get_reentrant());
-
     TABLES_LOCK();
     _Py_hashtable_clear(tracemalloc_traces);
     tracemalloc_traced_memory = 0;
@@ -823,11 +819,6 @@ tracemalloc_init(void)
     tracemalloc_empty_traceback.frames[0].lineno = 0;
     tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback);
 
-    /* Disable tracing allocations until hooks are installed. Set
-       also the reentrant flag to detect bugs: fail with an assertion error
-       if set_reentrant(1) is called while tracing is disabled. */
-    set_reentrant(1);
-
     tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED;
     return 0;
 }
@@ -912,7 +903,6 @@ tracemalloc_start(int max_nframe)
 
     /* everything is ready: start tracing Python memory allocations */
     tracemalloc_config.tracing = 1;
-    set_reentrant(0);
 
     return 0;
 }
@@ -926,10 +916,6 @@ tracemalloc_stop(void)
     /* stop tracing Python memory allocations */
     tracemalloc_config.tracing = 0;
 
-    /* set the reentrant flag to detect bugs: fail with an assertion error if
-       set_reentrant(1) is called while tracing is disabled. */
-    set_reentrant(1);
-
     /* unregister the hook on memory allocators */
 #ifdef TRACE_RAW_MALLOC
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
@@ -943,15 +929,6 @@ tracemalloc_stop(void)
     tracemalloc_traceback = NULL;
 }
 
-static PyObject*
-lineno_as_obj(int lineno)
-{
-    if (lineno >= 0)
-        return PyLong_FromLong(lineno);
-    else
-        Py_RETURN_NONE;
-}
-
 PyDoc_STRVAR(tracemalloc_is_tracing_doc,
     "is_tracing()->bool\n"
     "\n"
@@ -996,8 +973,7 @@ frame_to_pyobject(frame_t *frame)
     Py_INCREF(frame->filename);
     PyTuple_SET_ITEM(frame_obj, 0, frame->filename);
 
-    assert(frame->lineno >= 0);
-    lineno_obj = lineno_as_obj(frame->lineno);
+    lineno_obj = PyLong_FromUnsignedLong(frame->lineno);
     if (lineno_obj == NULL) {
         Py_DECREF(frame_obj);
         return NULL;
index a3ccf93..f73c599 100644 (file)
@@ -1743,7 +1743,7 @@ array_array___sizeof___impl(arrayobject *self)
 /*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/
 {
     Py_ssize_t res;
-    res = sizeof(arrayobject) + self->allocated * self->ob_descr->itemsize;
+    res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize;
     return PyLong_FromSsize_t(res);
 }
 
@@ -2090,7 +2090,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype,
          * that fits better. This may result in an array with narrower
          * or wider elements.
          *
-         * For example, if a 32-bit machine pickles a L-code array of
+         * For example, if a 32-bit machine pickles an L-code array of
          * unsigned longs, then the array will be unpickled by 64-bit
          * machine as an I-code array of unsigned ints.
          *
index 3b05aec..306937e 100644 (file)
@@ -46,7 +46,7 @@ fbound(double val, double minval, double maxval)
  */
 #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
 #define CLIP 32635
-#define SIGN_BIT        (0x80)          /* Sign bit for a A-law byte. */
+#define SIGN_BIT        (0x80)          /* Sign bit for an A-law byte. */
 #define QUANT_MASK      (0xf)           /* Quantization field mask. */
 #define SEG_SHIFT       (4)             /* Left shift for segment number. */
 #define SEG_MASK        (0x70)          /* Segment field mask. */
@@ -217,7 +217,7 @@ static PyInt16 _st_alaw2linear16[256] = {
 };
 
 /*
- * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
+ * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
  * stored in an unsigned char.  This function should only be called with
  * the data shifted such that it only contains information in the lower
  * 13-bits.
index 23642df..b72a3f0 100644 (file)
@@ -328,22 +328,26 @@ find_pairencmap(ucs2_t body, ucs2_t modifier,
     min = 0;
     max = haystacksize;
 
-    for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1)
+    for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1) {
         if (value < haystack[pos].uniseq) {
-            if (max == pos) break;
-            else max = pos;
+            if (max != pos) {
+                max = pos;
+                continue;
+            }
         }
         else if (value > haystack[pos].uniseq) {
-            if (min == pos) break;
-            else min = pos;
+            if (min != pos) {
+                min = pos;
+                continue;
+            }
         }
-        else
-            break;
+        break;
+    }
 
-        if (value == haystack[pos].uniseq)
-            return haystack[pos].code;
-        else
-            return DBCINV;
+    if (value == haystack[pos].uniseq) {
+        return haystack[pos].code;
+    }
+    return DBCINV;
 }
 #endif
 
index e4547f7..e1cdb2c 100644 (file)
@@ -793,8 +793,7 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx,
                               ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0);
     if (r == NULL) {
         /* recover the original pending buffer */
-        Py_CLEAR(ctx->pending);
-        ctx->pending = origpending;
+        Py_XSETREF(ctx->pending, origpending);
         origpending = NULL;
         goto errorexit;
     }
index a9f0c42..ab4d205 100644 (file)
@@ -264,7 +264,7 @@ PyDoc_STRVAR(_pickle_Unpickler___init____doc__,
 "other custom object that meets this interface.\n"
 "\n"
 "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n"
-"which are used to control compatiblity support for pickle stream\n"
+"which are used to control compatibility support for pickle stream\n"
 "generated by Python 2.  If *fix_imports* is True, pickle will try to\n"
 "map the old Python 2 names to the new names used in Python 3.  The\n"
 "*encoding* and *errors* tell pickle how to decode 8-bit string\n"
@@ -466,7 +466,7 @@ PyDoc_STRVAR(_pickle_load__doc__,
 "other custom object that meets this interface.\n"
 "\n"
 "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n"
-"which are used to control compatiblity support for pickle stream\n"
+"which are used to control compatibility support for pickle stream\n"
 "generated by Python 2.  If *fix_imports* is True, pickle will try to\n"
 "map the old Python 2 names to the new names used in Python 3.  The\n"
 "*encoding* and *errors* tell pickle how to decode 8-bit string\n"
@@ -512,7 +512,7 @@ PyDoc_STRVAR(_pickle_loads__doc__,
 "representation are ignored.\n"
 "\n"
 "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n"
-"which are used to control compatiblity support for pickle stream\n"
+"which are used to control compatibility support for pickle stream\n"
 "generated by Python 2.  If *fix_imports* is True, pickle will try to\n"
 "map the old Python 2 names to the new names used in Python 3.  The\n"
 "*encoding* and *errors* tell pickle how to decode 8-bit string\n"
@@ -545,4 +545,4 @@ _pickle_loads(PyModuleDef *module, PyObject *args, PyObject *kwargs)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=aecd61660d1cf31d input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a7169d4fbbeef827 input=a9049054013a1b77]*/
index 5e3b1c0..d9a1517 100644 (file)
@@ -145,7 +145,7 @@ PyDoc_STRVAR(fcntl_lockf__doc__,
 "\n"
 "When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n"
 "LOCK_NB to avoid blocking on lock acquisition.  If LOCK_NB is used and the\n"
-"lock cannot be acquired, an IOError will be raised and the exception will\n"
+"lock cannot be acquired, an OSError will be raised and the exception will\n"
 "have an errno attribute set to EACCES or EAGAIN (depending on the operating\n"
 "system -- for portability, check for either value).\n"
 "\n"
@@ -182,4 +182,4 @@ fcntl_lockf(PyModuleDef *module, PyObject *args)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=92963b631d00f0fe input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b7d6e8fc2ad09c48 input=a9049054013a1b77]*/
index c5cdf42..602ae1d 100644 (file)
@@ -48,7 +48,7 @@ PyDoc_STRVAR(zlib_decompress__doc__,
 "  data\n"
 "    Compressed data.\n"
 "  wbits\n"
-"    The window buffer size.\n"
+"    The window buffer size and container format.\n"
 "  bufsize\n"
 "    The initial output buffer size.");
 
@@ -89,12 +89,16 @@ PyDoc_STRVAR(zlib_compressobj__doc__,
 "Return a compressor object.\n"
 "\n"
 "  level\n"
-"    The compression level (an integer in the range 0-9; default is 6).\n"
-"    Higher compression levels are slower, but produce smaller results.\n"
+"    The compression level (an integer in the range 0-9 or -1; default is\n"
+"    currently equivalent to 6).  Higher compression levels are slower,\n"
+"    but produce smaller results.\n"
 "  method\n"
 "    The compression algorithm.  If given, this must be DEFLATED.\n"
 "  wbits\n"
-"    The base two logarithm of the window size (range: 8..15).\n"
+"    +9 to +15: The base-two logarithm of the window size.  Include a zlib\n"
+"        container.\n"
+"    -9 to -15: Generate a raw stream.\n"
+"    +25 to +31: Include a gzip container.\n"
 "  memLevel\n"
 "    Controls the amount of memory used for internal compression state.\n"
 "    Valid values range from 1 to 9.  Higher values result in higher memory\n"
@@ -145,7 +149,7 @@ PyDoc_STRVAR(zlib_decompressobj__doc__,
 "Return a decompressor object.\n"
 "\n"
 "  wbits\n"
-"    The window buffer size.\n"
+"    The window buffer size and container format.\n"
 "  zdict\n"
 "    The predefined compression dictionary.  This must be the same\n"
 "    dictionary as used by the compressor that produced the input data.");
@@ -438,4 +442,4 @@ exit:
 #ifndef ZLIB_COMPRESS_COPY_METHODDEF
     #define ZLIB_COMPRESS_COPY_METHODDEF
 #endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */
-/*[clinic end generated code: output=7734aec079550bc8 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=f31627b314a7bd2f input=a9049054013a1b77]*/
index 7f6c2c9..82ea589 100644 (file)
@@ -27,20 +27,20 @@ class Py_complex_protected_return_converter(CReturnConverter):
         self.declare(data)
         data.return_conversion.append("""
 PyFPE_END_PROTECT(_return_value);
-if (errno == EDOM) {{
+if (errno == EDOM) {
     PyErr_SetString(PyExc_ValueError, "math domain error");
     goto exit;
-}}
-else if (errno == ERANGE) {{
+}
+else if (errno == ERANGE) {
     PyErr_SetString(PyExc_OverflowError, "math range error");
     goto exit;
-}}
-else {{
+}
+else {
     return_value = PyComplex_FromCComplex(_return_value);
-}}
+}
 """.strip())
 [python start generated code]*/
-/*[python end generated code: output=da39a3ee5e6b4b0d input=231019039a6fbb9a]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=345daa075b1028e7]*/
 
 #if (FLT_RADIX != 2 && FLT_RADIX != 16)
 #error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16"
index 06b5de0..e8eefdd 100644 (file)
@@ -1040,7 +1040,7 @@ XML_GetFeatureList(void);
 */
 #define XML_MAJOR_VERSION 2
 #define XML_MINOR_VERSION 1
-#define XML_MICRO_VERSION 0
+#define XML_MICRO_VERSION 1
 
 #ifdef __cplusplus
 }
index 0ac0317..4128387 100644 (file)
@@ -1550,7 +1550,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
   else if (bufferPtr == bufferEnd) {
     const char *end;
     int nLeftOver;
-    enum XML_Error result;
+    enum XML_Status result;
     parseEndByteIndex += len;
     positionPtr = s;
     ps_finalBuffer = (XML_Bool)isFinal;
@@ -1678,6 +1678,10 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
 void * XMLCALL
 XML_GetBuffer(XML_Parser parser, int len)
 {
+  if (len < 0) {
+    errorCode = XML_ERROR_NO_MEMORY;
+    return NULL;
+  }
   switch (ps_parsing) {
   case XML_SUSPENDED:
     errorCode = XML_ERROR_SUSPENDED;
@@ -1689,10 +1693,16 @@ XML_GetBuffer(XML_Parser parser, int len)
   }
 
   if (len > bufferLim - bufferEnd) {
-    /* FIXME avoid integer overflow */
+#ifdef XML_CONTEXT_BYTES
+    int keep;
+#endif
     int neededSize = len + (int)(bufferEnd - bufferPtr);
+    if (neededSize < 0) {
+      errorCode = XML_ERROR_NO_MEMORY;
+      return NULL;
+    }
 #ifdef XML_CONTEXT_BYTES
-    int keep = (int)(bufferPtr - buffer);
+    keep = (int)(bufferPtr - buffer);
 
     if (keep > XML_CONTEXT_BYTES)
       keep = XML_CONTEXT_BYTES;
@@ -1719,7 +1729,11 @@ XML_GetBuffer(XML_Parser parser, int len)
         bufferSize = INIT_BUFFER_SIZE;
       do {
         bufferSize *= 2;
-      } while (bufferSize < neededSize);
+      } while (bufferSize < neededSize && bufferSize > 0);
+      if (bufferSize <= 0) {
+        errorCode = XML_ERROR_NO_MEMORY;
+        return NULL;
+      }
       newBuf = (char *)MALLOC(bufferSize);
       if (newBuf == 0) {
         errorCode = XML_ERROR_NO_MEMORY;
@@ -2911,6 +2925,8 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
         unsigned long uriHash = hash_secret_salt;
         ((XML_Char *)s)[-1] = 0;  /* clear flag */
         id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
+        if (!id || !id->prefix)
+          return XML_ERROR_NO_MEMORY;
         b = id->prefix->binding;
         if (!b)
           return XML_ERROR_UNBOUND_PREFIX;
@@ -5475,6 +5491,8 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
             return NULL;
           id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
                                         sizeof(PREFIX));
+          if (!id->prefix)
+            return NULL;
           if (id->prefix->name == poolStart(&dtd->pool))
             poolFinish(&dtd->pool);
           else
index fd6bf7a..205c07e 100644 (file)
@@ -1584,7 +1584,7 @@ initScan(const ENCODING * const *encodingTable,
       if (ptr[0] == '\0') {
         /* 0 isn't a legal data character. Furthermore a document
            entity can only start with ASCII characters.  So the only
-           way this can fail to be big-endian UTF-16 is if it is an
+           way this can fail to be big-endian UTF-16 if it it's an
            external parsed general entity that's labelled as
            UTF-16LE.
         */
index 530ddc7..f1fda48 100644 (file)
@@ -380,9 +380,8 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
     if (tstate == NULL)
         return NULL;
 
-    Py_XDECREF(fatal_error.file);
     Py_XINCREF(file);
-    fatal_error.file = file;
+    Py_XSETREF(fatal_error.file, file);
     fatal_error.fd = fd;
     fatal_error.all_threads = all_threads;
     fatal_error.interp = tstate->interp;
@@ -491,7 +490,7 @@ faulthandler_thread(void *unused)
         assert(st == PY_LOCK_FAILURE);
 
         /* get the thread holding the GIL, NULL if no thread hold the GIL */
-        current = (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current);
+        current = _PyThreadState_UncheckedGet();
 
         _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
 
@@ -599,9 +598,8 @@ faulthandler_dump_traceback_later(PyObject *self,
     /* Cancel previous thread, if running */
     cancel_dump_traceback_later();
 
-    Py_XDECREF(thread.file);
     Py_XINCREF(file);
-    thread.file = file;
+    Py_XSETREF(thread.file, file);
     thread.fd = fd;
     thread.timeout_us = timeout_us;
     thread.repeat = repeat;
@@ -778,9 +776,8 @@ faulthandler_register_py(PyObject *self,
         user->previous = previous;
     }
 
-    Py_XDECREF(user->file);
     Py_XINCREF(file);
-    user->file = file;
+    Py_XSETREF(user->file, file);
     user->fd = fd;
     user->all_threads = all_threads;
     user->chain = chain;
@@ -938,10 +935,18 @@ static PyObject *
 faulthandler_fatal_error_py(PyObject *self, PyObject *args)
 {
     char *message;
-    if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
+    int release_gil = 0;
+    if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
         return NULL;
     faulthandler_suppress_crash_report();
-    Py_FatalError(message);
+    if (release_gil) {
+        Py_BEGIN_ALLOW_THREADS
+        Py_FatalError(message);
+        Py_END_ALLOW_THREADS
+    }
+    else {
+        Py_FatalError(message);
+    }
     Py_RETURN_NONE;
 }
 
@@ -1046,7 +1051,7 @@ static PyMethodDef module_methods[] = {
     {"register",
      (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
      PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
-               "register an handler for the signal 'signum': dump the "
+               "register a handler for the signal 'signum': dump the "
                "traceback of the current thread, or of all threads if "
                "all_threads is True, into file")},
     {"unregister",
index 97ff07c..4e6eb72 100644 (file)
@@ -344,7 +344,7 @@ of the following values:
 
 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
 LOCK_NB to avoid blocking on lock acquisition.  If LOCK_NB is used and the
-lock cannot be acquired, an IOError will be raised and the exception will
+lock cannot be acquired, an OSError will be raised and the exception will
 have an errno attribute set to EACCES or EAGAIN (depending on the operating
 system -- for portability, check for either value).
 
@@ -360,7 +360,7 @@ starts.  `whence` is as with fileobj.seek(), specifically:
 static PyObject *
 fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj,
                  PyObject *startobj, int whence)
-/*[clinic end generated code: output=31af35eba08b9af7 input=9c594391de821f24]*/
+/*[clinic end generated code: output=31af35eba08b9af7 input=3a5dc01b04371f1a]*/
 {
     int ret;
 
index e2a2edf..d8167ea 100644 (file)
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
index 03d292c..18deb60 100644 (file)
 #endif
 
 
-#ifndef VERSION
-#define VERSION "2.1"
-#endif
-
-#ifndef VPATH
-#define VPATH "."
-#endif
-
-#ifndef PREFIX
-#  define PREFIX "/usr/local"
-#endif
-
-#ifndef EXEC_PREFIX
-#define EXEC_PREFIX PREFIX
-#endif
-
-#ifndef PYTHONPATH
-#define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
-              EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
+#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH)
+#error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined"
 #endif
 
 #ifndef LANDMARK
index dfafeab..409922a 100644 (file)
@@ -4,8 +4,6 @@
 
 /* Itertools module written and maintained
    by Raymond D. Hettinger <python@rcn.com>
-   Copyright (c) 2003-2013 Python Software Foundation.
-   All rights reserved.
 */
 
 
@@ -159,15 +157,12 @@ groupby_setstate(groupbyobject *lz, PyObject *state)
     PyObject *currkey, *currvalue, *tgtkey;
     if (!PyArg_ParseTuple(state, "OOO", &currkey, &currvalue, &tgtkey))
         return NULL;
-    Py_CLEAR(lz->currkey);
-    lz->currkey = currkey;
-    Py_INCREF(lz->currkey);
-    Py_CLEAR(lz->currvalue);
-    lz->currvalue = currvalue;
-    Py_INCREF(lz->currvalue);
-    Py_CLEAR(lz->tgtkey);
-    lz->tgtkey = tgtkey;
-    Py_INCREF(lz->tgtkey);
+    Py_INCREF(currkey);
+    Py_XSETREF(lz->currkey, currkey);
+    Py_INCREF(currvalue);
+    Py_XSETREF(lz->currvalue, currvalue);
+    Py_INCREF(tgtkey);
+    Py_XSETREF(lz->tgtkey, tgtkey);
     Py_RETURN_NONE;
 }
 
@@ -636,8 +631,7 @@ tee_next(teeobject *to)
         link = teedataobject_jumplink(to->dataobj);
         if (link == NULL)
             return NULL;
-        Py_DECREF(to->dataobj);
-        to->dataobj = (teedataobject *)link;
+        Py_SETREF(to->dataobj, (teedataobject *)link);
         to->index = 0;
     }
     value = teedataobject_getitem(to->dataobj, to->index);
@@ -748,9 +742,8 @@ tee_setstate(teeobject *to, PyObject *state)
         PyErr_SetString(PyExc_ValueError, "Index out of range");
         return NULL;
     }
-    Py_CLEAR(to->dataobj);
-    to->dataobj = tdo;
-    Py_INCREF(to->dataobj);
+    Py_INCREF(tdo);
+    Py_XSETREF(to->dataobj, tdo);
     to->index = index;
     Py_RETURN_NONE;
 }
@@ -975,9 +968,8 @@ cycle_setstate(cycleobject *lz, PyObject *state)
     int firstpass;
     if (!PyArg_ParseTuple(state, "Oi", &saved, &firstpass))
         return NULL;
-    Py_CLEAR(lz->saved);
-    lz->saved = saved;
-    Py_XINCREF(lz->saved);
+    Py_XINCREF(saved);
+    Py_XSETREF(lz->saved, saved);
     lz->firstpass = firstpass != 0;
     Py_RETURN_NONE;
 }
@@ -1902,12 +1894,10 @@ chain_setstate(chainobject *lz, PyObject *state)
     if (! PyArg_ParseTuple(state, "O|O", &source, &active))
         return NULL;
 
-    Py_CLEAR(lz->source);
-    lz->source = source;
-    Py_INCREF(lz->source);
-    Py_CLEAR(lz->active);
-    lz->active = active;
-    Py_XINCREF(lz->active);
+    Py_INCREF(source);
+    Py_XSETREF(lz->source, source);
+    Py_XINCREF(active);
+    Py_XSETREF(lz->active, active);
     Py_RETURN_NONE;
 }
 
@@ -2089,7 +2079,7 @@ product_sizeof(productobject *lz, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(productobject);
+    res = _PyObject_SIZE(Py_TYPE(lz));
     res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t);
     return PyLong_FromSsize_t(res);
 }
@@ -2263,8 +2253,7 @@ product_setstate(productobject *lz, PyObject *state)
         Py_INCREF(element);
         PyTuple_SET_ITEM(result, i, element);
     }
-    Py_CLEAR(lz->result);
-    lz->result = result;
+    Py_XSETREF(lz->result, result);
     Py_RETURN_NONE;
 }
 
@@ -2420,7 +2409,7 @@ combinations_sizeof(combinationsobject *co, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(combinationsobject);
+    res = _PyObject_SIZE(Py_TYPE(co));
     res += co->r * sizeof(Py_ssize_t);
     return PyLong_FromSsize_t(res);
 }
@@ -2586,8 +2575,7 @@ combinations_setstate(combinationsobject *lz, PyObject *state)
         PyTuple_SET_ITEM(result, i, element);
     }
 
-    Py_CLEAR(lz->result);
-    lz->result = result;
+    Py_XSETREF(lz->result, result);
     Py_RETURN_NONE;
 }
 
@@ -2761,7 +2749,7 @@ cwr_sizeof(cwrobject *co, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(cwrobject);
+    res = _PyObject_SIZE(Py_TYPE(co));
     res += co->r * sizeof(Py_ssize_t);
     return PyLong_FromSsize_t(res);
 }
@@ -2917,8 +2905,7 @@ cwr_setstate(cwrobject *lz, PyObject *state)
         Py_INCREF(element);
         PyTuple_SET_ITEM(result, i, element);
     }
-    Py_CLEAR(lz->result);
-    lz->result = result;
+    Py_XSETREF(lz->result, result);
     Py_RETURN_NONE;
 }
 
@@ -3110,7 +3097,7 @@ permutations_sizeof(permutationsobject *po, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(permutationsobject);
+    res = _PyObject_SIZE(Py_TYPE(po));
     res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t);
     res += po->r * sizeof(Py_ssize_t);
     return PyLong_FromSsize_t(res);
@@ -3311,8 +3298,7 @@ permutations_setstate(permutationsobject *po, PyObject *state)
         Py_INCREF(element);
         PyTuple_SET_ITEM(result, i, element);
     }
-    Py_CLEAR(po->result);
-    po->result = result;
+    Py_XSETREF(po->result, result);
     Py_RETURN_NONE;
 }
 
@@ -3474,6 +3460,23 @@ accumulate_next(accumulateobject *lz)
 static PyObject *
 accumulate_reduce(accumulateobject *lz)
 {
+    if (lz->total == Py_None) {
+        PyObject *it;
+
+        if (PyType_Ready(&chain_type) < 0)
+            return NULL;
+        if (PyType_Ready(&islice_type) < 0)
+            return NULL;
+        it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
+                                   lz->total, lz->it);
+        if (it == NULL)
+            return NULL;
+        it = PyObject_CallFunction((PyObject *)Py_TYPE(lz), "NO",
+                                   it, lz->binop ? lz->binop : Py_None);
+        if (it == NULL)
+            return NULL;
+        return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None);
+    }
     return Py_BuildValue("O(OO)O", Py_TYPE(lz),
                             lz->it, lz->binop?lz->binop:Py_None,
                             lz->total?lz->total:Py_None);
@@ -3482,9 +3485,8 @@ accumulate_reduce(accumulateobject *lz)
 static PyObject *
 accumulate_setstate(accumulateobject *lz, PyObject *state)
 {
-    Py_CLEAR(lz->total);
-    lz->total = state;
-    Py_INCREF(lz->total);
+    Py_INCREF(state);
+    Py_XSETREF(lz->total, state);
     Py_RETURN_NONE;
 }
 
@@ -4465,9 +4467,8 @@ zip_longest_reduce(ziplongestobject *lz)
 static PyObject *
 zip_longest_setstate(ziplongestobject *lz, PyObject *state)
 {
-    Py_CLEAR(lz->fillvalue);
-    lz->fillvalue = state;
-    Py_INCREF(lz->fillvalue);
+    Py_INCREF(state);
+    Py_XSETREF(lz->fillvalue, state);
     Py_RETURN_NONE;
 }
 
@@ -4482,7 +4483,7 @@ static PyMethodDef zip_longest_methods[] = {
 PyDoc_STRVAR(zip_longest_doc,
 "zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object\n\
 \n\
-Return an zip_longest object whose .__next__() method returns a tuple where\n\
+Return a zip_longest object whose .__next__() method returns a tuple where\n\
 the i-th element comes from the i-th iterable argument.  The .__next__()\n\
 method continues until the longest iterable in the argument sequence\n\
 is exhausted and then it raises StopIteration.  When the shorter iterables\n\
index 961532b..add6b3e 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   ARGUMENTS:      Same as for "ld". The following arguments are processed
 #                   or supplied by this script (those marked with an asterisk
-#                   can be overriden from command line):
+#                   can be overridden from command line):
 #
 #                       Argument                     Default value
 #                   (*) -o [OutputFileName]          -o shr.o
@@ -85,7 +85,7 @@ if test ! -n "$*"; then
 fi
 
 # Default import file for Python
-# Can be overriden by providing a -bI: argument.
+# Can be overridden by providing a -bI: argument.
 impfile="./python.exp"
 
 # Parse arguments
@@ -156,7 +156,7 @@ if test -z "$expfile"; then
 fi
 
 # Default entry symbol for Python modules = init[modulename]
-# Can be overriden by providing a -e argument.
+# Can be overridden by providing a -e argument.
 if test -z "$entry"; then
   entry=PyInit_`echo $filename | sed "s/module.*//"`
 fi
index 2a9ea28..e4c955e 100644 (file)
@@ -85,11 +85,11 @@ file   : program read from script file\n\
 arg ...: arguments passed to program in sys.argv[1:]\n\n\
 Other environment variables:\n\
 PYTHONSTARTUP: file executed on interactive startup (no default)\n\
-PYTHONPATH   : '%c'-separated list of directories prefixed to the\n\
+PYTHONPATH   : '%lc'-separated list of directories prefixed to the\n\
                default module search path.  The result is sys.path.\n\
 ";
 static char *usage_5 =
-"PYTHONHOME   : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n"
+"PYTHONHOME   : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
 "               The default module search path uses %s.\n"
 "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
 "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
@@ -114,8 +114,8 @@ usage(int exitcode, wchar_t* program)
         fputs(usage_1, f);
         fputs(usage_2, f);
         fputs(usage_3, f);
-        fprintf(f, usage_4, DELIM);
-        fprintf(f, usage_5, DELIM, PYTHONHOMEHELP);
+        fprintf(f, usage_4, (wint_t)DELIM);
+        fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
         fputs(usage_6, f);
     }
     return exitcode;
index 9359eb2..7ebf8e8 100644 (file)
@@ -400,9 +400,8 @@ m_lgamma(double x)
    Implementations of the error function erf(x) and the complementary error
    function erfc(x).
 
-   Method: following 'Numerical Recipes' by Flannery, Press et. al. (2nd ed.,
-   Cambridge University Press), we use a series approximation for erf for
-   small x, and a continued fraction approximation for erfc(x) for larger x;
+   Method: we use a series approximation for erf for small x, and a continued
+   fraction approximation for erfc(x) for larger x;
    combined with the relations erf(-x) = -erf(x) and erfc(x) = 1.0 - erf(x),
    this gives us erf(x) and erfc(x) for all x.
 
@@ -958,8 +957,8 @@ static PyObject * math_ceil(PyObject *self, PyObject *number) {
 }
 
 PyDoc_STRVAR(math_ceil_doc,
-             "ceil(x)\n\nReturn the ceiling of x as an int.\n"
-             "This is the smallest integral value >= x.");
+             "ceil(x)\n\nReturn the ceiling of x as an Integral.\n"
+             "This is the smallest integer >= x.");
 
 FUNC2(copysign, copysign,
       "copysign(x, y)\n\nReturn a float with the magnitude (absolute value) "
@@ -998,8 +997,8 @@ static PyObject * math_floor(PyObject *self, PyObject *number) {
 }
 
 PyDoc_STRVAR(math_floor_doc,
-             "floor(x)\n\nReturn the floor of x as an int.\n"
-             "This is the largest integral value <= x.");
+             "floor(x)\n\nReturn the floor of x as an Integral.\n"
+             "This is the largest integer <= x.");
 
 FUNC1A(gamma, m_tgamma,
       "gamma(x)\n\nGamma function at x.")
@@ -2047,7 +2046,7 @@ math_isclose(PyObject *self, PyObject *args, PyObject *kwargs)
 }
 
 PyDoc_STRVAR(math_isclose_doc,
-"is_close(a, b, *, rel_tol=1e-09, abs_tol=0.0) -> bool\n"
+"isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) -> bool\n"
 "\n"
 "Determine whether two floating point numbers are close in value.\n"
 "\n"
index daab52b..bb98a99 100644 (file)
@@ -719,7 +719,7 @@ mmap__sizeof__method(mmap_object *self, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(mmap_object);
+    res = _PyObject_SIZE(Py_TYPE(self));
     if (self->tagname)
         res += strlen(self->tagname) + 1;
     return PyLong_FromSsize_t(res);
index ef77c88..f85e5bc 100644 (file)
 #  define T_POINTER T_ULONGLONG
 #endif
 
+/* Compatibility with Python 3.3 */
+#if PY_VERSION_HEX < 0x03040000
+#    define PyMem_RawMalloc PyMem_Malloc
+#    define PyMem_RawFree PyMem_Free
+#endif
+
 #define F_HANDLE F_POINTER
 #define F_ULONG_PTR F_POINTER
 #define F_DWORD "k"
@@ -238,7 +244,7 @@ PostToQueueCallback(PVOID lpParameter, BOOL TimerOrWaitFired)
     PostQueuedCompletionStatus(p->CompletionPort, TimerOrWaitFired,
                                0, p->Overlapped);
     /* ignore possible error! */
-    PyMem_Free(p);
+    PyMem_RawFree(p);
 }
 
 PyDoc_STRVAR(
@@ -262,7 +268,10 @@ overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args)
                           &Milliseconds))
         return NULL;
 
-    pdata = PyMem_Malloc(sizeof(struct PostCallbackData));
+    /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since
+       PostToQueueCallback() will call PyMem_Free() from a new C thread
+       which doesn't hold the GIL. */
+    pdata = PyMem_RawMalloc(sizeof(struct PostCallbackData));
     if (pdata == NULL)
         return SetFromWindowsErr(0);
 
@@ -273,7 +282,7 @@ overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args)
             pdata, Milliseconds,
             WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE))
     {
-        PyMem_Free(pdata);
+        PyMem_RawFree(pdata);
         return SetFromWindowsErr(0);
     }
 
index 8023558..6471b8e 100644 (file)
@@ -397,7 +397,7 @@ parser_sizeof(PyST_Object *st, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(PyST_Object) + _PyNode_SizeOf(st->st_node);
+    res = _PyObject_SIZE(Py_TYPE(st)) + _PyNode_SizeOf(st->st_node);
     return PyLong_FromSsize_t(res);
 }
 
index 854a749..e5f58ab 100644 (file)
@@ -32,6 +32,8 @@
 #include "winreparse.h"
 #endif
 
+#include <stdio.h>  /* needed for ctermid() */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -1345,16 +1347,16 @@ win32_chdir(LPCSTR path)
 static BOOL __stdcall
 win32_wchdir(LPCWSTR path)
 {
-    wchar_t _new_path[MAX_PATH], *new_path = _new_path;
+    wchar_t path_buf[MAX_PATH], *new_path = path_buf;
     int result;
     wchar_t env[4] = L"=x:";
 
     if(!SetCurrentDirectoryW(path))
         return FALSE;
-    result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
+    result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
     if (!result)
         return FALSE;
-    if (result > Py_ARRAY_LENGTH(new_path)) {
+    if (result > Py_ARRAY_LENGTH(path_buf)) {
         new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
         if (!new_path) {
             SetLastError(ERROR_OUTOFMEMORY);
@@ -1372,7 +1374,7 @@ win32_wchdir(LPCWSTR path)
         return TRUE;
     env[1] = new_path[0];
     result = SetEnvironmentVariableW(env, new_path);
-    if (new_path != _new_path)
+    if (new_path != path_buf)
         PyMem_RawFree(new_path);
     return result;
 }
@@ -11928,13 +11930,15 @@ typedef struct {
 static void
 ScandirIterator_close(ScandirIterator *iterator)
 {
-    if (iterator->handle == INVALID_HANDLE_VALUE)
+    HANDLE handle = iterator->handle;
+
+    if (handle == INVALID_HANDLE_VALUE)
         return;
 
+    iterator->handle = INVALID_HANDLE_VALUE;
     Py_BEGIN_ALLOW_THREADS
-    FindClose(iterator->handle);
+    FindClose(handle);
     Py_END_ALLOW_THREADS
-    iterator->handle = INVALID_HANDLE_VALUE;
 }
 
 static PyObject *
@@ -11942,12 +11946,11 @@ ScandirIterator_iternext(ScandirIterator *iterator)
 {
     WIN32_FIND_DATAW *file_data = &iterator->file_data;
     BOOL success;
+    PyObject *entry;
 
     /* Happens if the iterator is iterated twice */
-    if (iterator->handle == INVALID_HANDLE_VALUE) {
-        PyErr_SetNone(PyExc_StopIteration);
+    if (iterator->handle == INVALID_HANDLE_VALUE)
         return NULL;
-    }
 
     while (1) {
         if (!iterator->first_time) {
@@ -11955,9 +11958,9 @@ ScandirIterator_iternext(ScandirIterator *iterator)
             success = FindNextFileW(iterator->handle, file_data);
             Py_END_ALLOW_THREADS
             if (!success) {
+                /* Error or no more files */
                 if (GetLastError() != ERROR_NO_MORE_FILES)
-                    return path_error(&iterator->path);
-                /* No more files found in directory, stop iterating */
+                    path_error(&iterator->path);
                 break;
             }
         }
@@ -11965,15 +11968,18 @@ ScandirIterator_iternext(ScandirIterator *iterator)
 
         /* Skip over . and .. */
         if (wcscmp(file_data->cFileName, L".") != 0 &&
-                wcscmp(file_data->cFileName, L"..") != 0)
-            return DirEntry_from_find_data(&iterator->path, file_data);
+            wcscmp(file_data->cFileName, L"..") != 0) {
+            entry = DirEntry_from_find_data(&iterator->path, file_data);
+            if (!entry)
+                break;
+            return entry;
+        }
 
         /* Loop till we get a non-dot directory or finish iterating */
     }
 
+    /* Error or no more files */
     ScandirIterator_close(iterator);
-
-    PyErr_SetNone(PyExc_StopIteration);
     return NULL;
 }
 
@@ -11982,13 +11988,15 @@ ScandirIterator_iternext(ScandirIterator *iterator)
 static void
 ScandirIterator_close(ScandirIterator *iterator)
 {
-    if (!iterator->dirp)
+    DIR *dirp = iterator->dirp;
+
+    if (!dirp)
         return;
 
+    iterator->dirp = NULL;
     Py_BEGIN_ALLOW_THREADS
-    closedir(iterator->dirp);
+    closedir(dirp);
     Py_END_ALLOW_THREADS
-    iterator->dirp = NULL;
     return;
 }
 
@@ -11998,12 +12006,11 @@ ScandirIterator_iternext(ScandirIterator *iterator)
     struct dirent *direntp;
     Py_ssize_t name_len;
     int is_dot;
+    PyObject *entry;
 
     /* Happens if the iterator is iterated twice */
-    if (!iterator->dirp) {
-        PyErr_SetNone(PyExc_StopIteration);
+    if (!iterator->dirp)
         return NULL;
-    }
 
     while (1) {
         errno = 0;
@@ -12012,9 +12019,9 @@ ScandirIterator_iternext(ScandirIterator *iterator)
         Py_END_ALLOW_THREADS
 
         if (!direntp) {
+            /* Error or no more files */
             if (errno != 0)
-                return path_error(&iterator->path);
-            /* No more files found in directory, stop iterating */
+                path_error(&iterator->path);
             break;
         }
 
@@ -12023,20 +12030,22 @@ ScandirIterator_iternext(ScandirIterator *iterator)
         is_dot = direntp->d_name[0] == '.' &&
                  (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
         if (!is_dot) {
-            return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
+            entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
                                             name_len, direntp->d_ino
 #ifdef HAVE_DIRENT_D_TYPE
                                             , direntp->d_type
 #endif
                                             );
+            if (!entry)
+                break;
+            return entry;
         }
 
         /* Loop till we get a non-dot directory or finish iterating */
     }
 
+    /* Error or no more files */
     ScandirIterator_close(iterator);
-
-    PyErr_SetNone(PyExc_StopIteration);
     return NULL;
 }
 
index a6581b0..8c00dec 100644 (file)
@@ -78,10 +78,12 @@ on_completion_display_matches_hook(char **matches,
 static char *completer_word_break_characters;
 
 typedef struct {
+  /* Specify hook functions in Python */
   PyObject *completion_display_matches_hook;
   PyObject *startup_hook;
   PyObject *pre_input_hook;
-  PyObject *completer;
+
+  PyObject *completer; /* Specify a word completer in Python */
   PyObject *begidx;
   PyObject *endidx;
 } readlinestate;
@@ -147,7 +149,7 @@ parse_and_bind(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(doc_parse_and_bind,
 "parse_and_bind(string) -> None\n\
-Parse and execute single line of a readline init file.");
+Execute the init line provided in the string argument.");
 
 
 /* Exported function to parse a readline init file */
@@ -172,7 +174,7 @@ read_init_file(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(doc_read_init_file,
 "read_init_file([filename]) -> None\n\
-Parse a readline initialization file.\n\
+Execute a readline initialization file.\n\
 The default filename is the last filename used.");
 
 
@@ -269,7 +271,7 @@ append_history_file(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(doc_append_history_file,
 "append_history_file(nelements[, filename]) -> None\n\
-Append the last nelements of the history list to file.\n\
+Append the last nelements items of the history list to file.\n\
 The default filename is ~/.history.");
 #endif
 
@@ -288,7 +290,7 @@ set_history_length(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(set_history_length_doc,
 "set_history_length(length) -> None\n\
-set the maximal number of items which will be written to\n\
+set the maximal number of lines which will be written to\n\
 the history file. A negative length is used to inhibit\n\
 history truncation.");
 
@@ -303,7 +305,7 @@ get_history_length(PyObject *self, PyObject *noarg)
 
 PyDoc_STRVAR(get_history_length_doc,
 "get_history_length() -> int\n\
-return the maximum number of items that will be written to\n\
+return the maximum number of lines that will be written to\n\
 the history file.");
 
 
@@ -336,13 +338,6 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args)
 }
 
 
-/* Exported functions to specify hook functions in Python */
-
-
-#ifdef HAVE_RL_PRE_INPUT_HOOK
-
-#endif
-
 static PyObject *
 set_completion_display_matches_hook(PyObject *self, PyObject *args)
 {
@@ -378,7 +373,7 @@ set_startup_hook(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(doc_set_startup_hook,
 "set_startup_hook([function]) -> None\n\
-Set or remove the startup_hook function.\n\
+Set or remove the function invoked by the rl_startup_hook callback.\n\
 The function is called with no arguments just\n\
 before readline prints the first prompt.");
 
@@ -395,7 +390,7 @@ set_pre_input_hook(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(doc_set_pre_input_hook,
 "set_pre_input_hook([function]) -> None\n\
-Set or remove the pre_input_hook function.\n\
+Set or remove the function invoked by the rl_pre_input_hook callback.\n\
 The function is called with no arguments after the first prompt\n\
 has been printed and just before readline starts reading input\n\
 characters.");
@@ -403,14 +398,6 @@ characters.");
 #endif
 
 
-/* Exported function to specify a word completer in Python */
-
-
-
-
-
-
-
 /* Get the completion type for the scope of the tab-completion */
 static PyObject *
 get_completion_type(PyObject *self, PyObject *noarg)
@@ -434,7 +421,7 @@ get_begidx(PyObject *self, PyObject *noarg)
 
 PyDoc_STRVAR(doc_get_begidx,
 "get_begidx() -> int\n\
-get the beginning index of the readline tab-completion scope");
+get the beginning index of the completion scope");
 
 
 /* Get the ending index for the scope of the tab-completion */
@@ -448,7 +435,7 @@ get_endidx(PyObject *self, PyObject *noarg)
 
 PyDoc_STRVAR(doc_get_endidx,
 "get_endidx() -> int\n\
-get the ending index of the readline tab-completion scope");
+get the ending index of the completion scope");
 
 
 /* Set the tab-completion word-delimiters that readline uses */
@@ -477,7 +464,7 @@ set_completer_delims(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(doc_set_completer_delims,
 "set_completer_delims(string) -> None\n\
-set the readline word delimiters for tab-completion");
+set the word delimiters for completion");
 
 /* _py_free_history_entry: Utility function to free a history entry. */
 
@@ -517,7 +504,7 @@ py_remove_history(PyObject *self, PyObject *args)
     int entry_number;
     HIST_ENTRY *entry;
 
-    if (!PyArg_ParseTuple(args, "i:remove_history", &entry_number))
+    if (!PyArg_ParseTuple(args, "i:remove_history_item", &entry_number))
         return NULL;
     if (entry_number < 0) {
         PyErr_SetString(PyExc_ValueError,
@@ -547,7 +534,7 @@ py_replace_history(PyObject *self, PyObject *args)
     char *line;
     HIST_ENTRY *old_entry;
 
-    if (!PyArg_ParseTuple(args, "is:replace_history", &entry_number,
+    if (!PyArg_ParseTuple(args, "is:replace_history_item", &entry_number,
                           &line)) {
         return NULL;
     }
@@ -588,7 +575,7 @@ py_add_history(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(doc_add_history,
 "add_history(string) -> None\n\
-add a line to the history buffer");
+add an item to the history buffer");
 
 
 /* Get the tab-completion word-delimiters that readline uses */
@@ -601,7 +588,7 @@ get_completer_delims(PyObject *self, PyObject *noarg)
 
 PyDoc_STRVAR(doc_get_completer_delims,
 "get_completer_delims() -> string\n\
-get the readline word delimiters for tab-completion");
+get the word delimiters for completion");
 
 
 /* Set the completer function */
@@ -662,7 +649,7 @@ get_history_item(PyObject *self, PyObject *args)
     int idx = 0;
     HIST_ENTRY *hist_ent;
 
-    if (!PyArg_ParseTuple(args, "i:index", &idx))
+    if (!PyArg_ParseTuple(args, "i:get_history_item", &idx))
         return NULL;
 #ifdef  __APPLE__
     if (using_libedit_emulation) {
@@ -754,7 +741,7 @@ insert_text(PyObject *self, PyObject *args)
 
 PyDoc_STRVAR(doc_insert_text,
 "insert_text(string) -> None\n\
-Insert text into the command line.");
+Insert text into the line buffer at the cursor position.");
 
 
 /* Redisplay the line buffer */
@@ -941,6 +928,26 @@ on_completion_display_matches_hook(char **matches,
 
 #endif
 
+#ifdef HAVE_RL_RESIZE_TERMINAL
+static volatile sig_atomic_t sigwinch_received;
+static PyOS_sighandler_t sigwinch_ohandler;
+
+static void
+readline_sigwinch_handler(int signum)
+{
+    sigwinch_received = 1;
+    if (sigwinch_ohandler &&
+            sigwinch_ohandler != SIG_IGN && sigwinch_ohandler != SIG_DFL)
+        sigwinch_ohandler(signum);
+
+#ifndef HAVE_SIGACTION
+    /* If the handler was installed with signal() rather than sigaction(),
+    we need to reinstall it. */
+    PyOS_setsig(SIGWINCH, readline_sigwinch_handler);
+#endif
+}
+#endif
+
 /* C function to call the Python completer. */
 
 static char *
@@ -1046,6 +1053,10 @@ setup_readline(readlinestate *mod_state)
     /* Bind both ESC-TAB and ESC-ESC to the completion function */
     rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
     rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
+#ifdef HAVE_RL_RESIZE_TERMINAL
+    /* Set up signal handler for window resize */
+    sigwinch_ohandler = PyOS_setsig(SIGWINCH, readline_sigwinch_handler);
+#endif
     /* Set our hook functions */
     rl_startup_hook = on_startup_hook;
 #ifdef HAVE_RL_PRE_INPUT_HOOK
@@ -1064,7 +1075,7 @@ setup_readline(readlinestate *mod_state)
 
 #ifndef __APPLE__
     if (!isatty(STDOUT_FILENO)) {
-        /* Issue #19884: stdout is no a terminal. Disable meta modifier
+        /* Issue #19884: stdout is not a terminal. Disable meta modifier
            keys to not write the ANSI sequence "\033[1034h" into stdout. On
            terminals supporting 8 bit characters like TERM=xterm-256color
            (which is now the default Fedora since Fedora 18), the meta key is
@@ -1131,6 +1142,13 @@ readline_until_enter_or_signal(const char *prompt, int *signal)
             struct timeval *timeoutp = NULL;
             if (PyOS_InputHook)
                 timeoutp = &timeout;
+#ifdef HAVE_RL_RESIZE_TERMINAL
+            /* Update readline's view of the window size after SIGWINCH */
+            if (sigwinch_received) {
+                sigwinch_received = 0;
+                rl_resize_terminal();
+            }
+#endif
             FD_SET(fileno(rl_instream), &selectset);
             /* select resets selectset if no input was available */
             has_input = select(fileno(rl_instream) + 1, &selectset,
@@ -1153,6 +1171,9 @@ readline_until_enter_or_signal(const char *prompt, int *signal)
 #endif
             if (s < 0) {
                 rl_free_line_state();
+#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0700
+                rl_callback_sigcleanup();
+#endif
                 rl_cleanup_after_signal();
                 rl_callback_handler_remove();
                 *signal = 1;
index b3ac807..00324a5 100644 (file)
@@ -1438,7 +1438,7 @@ PyDoc_STRVAR(pyepoll_register_doc,
 Registers a new fd or raises an OSError if the fd is already registered.\n\
 fd is the target file descriptor of the operation.\n\
 events is a bit set composed of the various EPOLL constants; the default\n\
-is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
+is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
 \n\
 The epoll interface supports all file descriptors that support poll.");
 
index 8c4def0..70c2b5b 100644 (file)
@@ -100,7 +100,7 @@ static void SHAcopy(SHAobject *src, SHAobject *dest)
  * algorithms in a highly modular and flexible manner.
  *
  * The library is free for all purposes without any express
- * gurantee it works.
+ * guarantee it works.
  *
  * Tom St Denis, tomstdenis@iahu.ca, http://libtom.org
  */
index 8237d86..76942aa 100644 (file)
@@ -111,7 +111,7 @@ static void SHAcopy(SHAobject *src, SHAobject *dest)
  * algorithms in a highly modular and flexible manner.
  *
  * The library is free for all purposes without any express
- * gurantee it works.
+ * guarantee it works.
  *
  * Tom St Denis, tomstdenis@iahu.ca, http://libtom.org
  */
index 70f3052..da454de 100644 (file)
@@ -1266,8 +1266,7 @@ PyInit__signal(void)
     if (Handlers[SIGINT].func == DefaultHandler) {
         /* Install default int handler */
         Py_INCREF(IntHandler);
-        Py_DECREF(Handlers[SIGINT].func);
-        Handlers[SIGINT].func = IntHandler;
+        Py_SETREF(Handlers[SIGINT].func, IntHandler);
         old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
     }
 
index bae9634..8f571a2 100644 (file)
@@ -84,6 +84,11 @@ Local naming conventions:
 */
 
 #ifdef __APPLE__
+#include <AvailabilityMacros.h>
+/* for getaddrinfo thread safety test on old versions of OS X */
+#ifndef MAC_OS_X_VERSION_10_5
+#define MAC_OS_X_VERSION_10_5 1050
+#endif
   /*
    * inet_aton is not available on OSX 10.3, yet we want to use a binary
    * that was build on 10.4 or later to work on that release, weak linking
@@ -179,15 +184,32 @@ if_indextoname(index) -- return the corresponding interface name\n\
 # define USE_GETHOSTBYNAME_LOCK
 #endif
 
-/* To use __FreeBSD_version */
+/* To use __FreeBSD_version, __OpenBSD__, and __NetBSD_Version__ */
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
 /* On systems on which getaddrinfo() is believed to not be thread-safe,
-   (this includes the getaddrinfo emulation) protect access with a lock. */
-#if defined(WITH_THREAD) && (defined(__APPLE__) || \
+   (this includes the getaddrinfo emulation) protect access with a lock.
+
+   getaddrinfo is thread-safe on Mac OS X 10.5 and later. Originally it was
+   a mix of code including an unsafe implementation from an old BSD's
+   libresolv. In 10.5 Apple reimplemented it as a safe IPC call to the
+   mDNSResponder process. 10.5 is the first be UNIX '03 certified, which
+   includes the requirement that getaddrinfo be thread-safe. See issue #25924.
+
+   It's thread-safe in OpenBSD starting with 5.4, released Nov 2013:
+   http://www.openbsd.org/plus54.html
+
+   It's thread-safe in NetBSD starting with 4.0, released Dec 2007:
+
+http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82&r2=1.83
+ */
+#if defined(WITH_THREAD) && ( \
+    (defined(__APPLE__) && \
+        MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) || \
     (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \
-    defined(__OpenBSD__) || defined(__NetBSD__) || \
+    (defined(__OpenBSD__) && OpenBSD+0 < 201311) || \
+    (defined(__NetBSD__) && __NetBSD_Version__+0 < 400000000) || \
     !defined(HAVE_GETADDRINFO))
 #define USE_GETADDRINFO_LOCK
 #endif
@@ -4519,6 +4541,19 @@ PyDoc_STRVAR(gethostbyname_doc,
 Return the IP address (a string of the form '255.255.255.255') for a host.");
 
 
+static PyObject*
+sock_decode_hostname(const char *name)
+{
+#ifdef MS_WINDOWS
+    /* Issue #26227: gethostbyaddr() returns a string encoded
+     * to the ANSI code page */
+    return PyUnicode_DecodeFSDefault(name);
+#else
+    /* Decode from UTF-8 */
+    return PyUnicode_FromString(name);
+#endif
+}
+
 /* Convenience function common to gethostbyname_ex and gethostbyaddr */
 
 static PyObject *
@@ -4529,6 +4564,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
     PyObject *name_list = (PyObject *)NULL;
     PyObject *addr_list = (PyObject *)NULL;
     PyObject *tmp;
+    PyObject *name;
 
     if (h == NULL) {
         /* Let's get real error message to return */
@@ -4637,7 +4673,10 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
             goto err;
     }
 
-    rtn_tuple = Py_BuildValue("sOO", h->h_name, name_list, addr_list);
+    name = sock_decode_hostname(h->h_name);
+    if (name == NULL)
+        goto err;
+    rtn_tuple = Py_BuildValue("NOO", name, name_list, addr_list);
 
  err:
     Py_XDECREF(name_list);
@@ -5623,6 +5662,7 @@ socket_getnameinfo(PyObject *self, PyObject *args)
     struct addrinfo hints, *res = NULL;
     int error;
     PyObject *ret = (PyObject *)NULL;
+    PyObject *name;
 
     flags = flowinfo = scope_id = 0;
     if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags))
@@ -5686,7 +5726,11 @@ socket_getnameinfo(PyObject *self, PyObject *args)
         set_gaierror(error);
         goto fail;
     }
-    ret = Py_BuildValue("ss", hbuf, pbuf);
+
+    name = sock_decode_hostname(hbuf);
+    if (name == NULL)
+        goto fail;
+    ret = Py_BuildValue("Ns", name, pbuf);
 
 fail:
     if (res)
index 06abb31..e840271 100644 (file)
@@ -155,8 +155,7 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
             tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
             if (tmp == NULL)
                 goto error;
-            Py_DECREF(self->prefix);
-            self->prefix = tmp;
+            Py_SETREF(self->prefix, tmp);
         }
     }
     else
@@ -325,17 +324,14 @@ get_module_info(ZipImporter *self, PyObject *fullname)
 }
 
 typedef enum {
-    FL_ERROR,
-    FL_NOT_FOUND,
-    FL_MODULE_FOUND,
-    FL_NS_FOUND
+    FL_ERROR = -1,       /* error */
+    FL_NOT_FOUND,        /* no loader or namespace portions found */
+    FL_MODULE_FOUND,     /* module/package found */
+    FL_NS_FOUND          /* namespace portion found: */
+                         /* *namespace_portion will point to the name */
 } find_loader_result;
 
-/* The guts of "find_loader" and "find_module". Return values:
-   -1: error
-    0: no loader or namespace portions found
-    1: module/package found
-    2: namespace portion found: *namespace_portion will point to the name
+/* The guts of "find_loader" and "find_module".
 */
 static find_loader_result
 find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
@@ -350,21 +346,34 @@ find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
     if (mi == MI_NOT_FOUND) {
         /* Not a module or regular package. See if this is a directory, and
            therefore possibly a portion of a namespace package. */
-        int is_dir = check_is_directory(self, self->prefix, fullname);
+        find_loader_result result = FL_NOT_FOUND;
+        PyObject *subname;
+        int is_dir;
+
+        /* We're only interested in the last path component of fullname;
+           earlier components are recorded in self->prefix. */
+        subname = get_subname(fullname);
+        if (subname == NULL) {
+            return FL_ERROR;
+        }
+
+        is_dir = check_is_directory(self, self->prefix, subname);
         if (is_dir < 0)
-            return -1;
-        if (is_dir) {
+            result = FL_ERROR;
+        else if (is_dir) {
             /* This is possibly a portion of a namespace
                package. Return the string representing its path,
                without a trailing separator. */
             *namespace_portion = PyUnicode_FromFormat("%U%c%U%U",
                                                       self->archive, SEP,
-                                                      self->prefix, fullname);
+                                                      self->prefix, subname);
             if (*namespace_portion == NULL)
-                return FL_ERROR;
-            return FL_NS_FOUND;
+                result = FL_ERROR;
+            else
+                result = FL_NS_FOUND;
         }
-        return FL_NOT_FOUND;
+        Py_DECREF(subname);
+        return result;
     }
     /* This is a module or package. */
     return FL_MODULE_FOUND;
@@ -398,6 +407,9 @@ zipimporter_find_module(PyObject *obj, PyObject *args)
     case FL_MODULE_FOUND:
         result = (PyObject *)self;
         break;
+    default:
+        PyErr_BadInternalCall();
+        return NULL;
     }
     Py_INCREF(result);
     return result;
@@ -434,6 +446,9 @@ zipimporter_find_loader(PyObject *obj, PyObject *args)
         result = Py_BuildValue("O[O]", Py_None, namespace_portion);
         Py_DECREF(namespace_portion);
         return result;
+    default:
+        PyErr_BadInternalCall();
+        return NULL;
     }
     return result;
 }
@@ -812,23 +827,43 @@ static PyTypeObject ZipImporter_Type = {
 
 /* implementation */
 
-/* Given a buffer, return the long that is represented by the first
+/* Given a buffer, return the unsigned int that is represented by the first
    4 bytes, encoded as little endian. This partially reimplements
    marshal.c:r_long() */
-static long
-get_long(unsigned char *buf) {
-    long x;
+static unsigned int
+get_uint32(const unsigned char *buf)
+{
+    unsigned int x;
     x =  buf[0];
-    x |= (long)buf[1] <<  8;
-    x |= (long)buf[2] << 16;
-    x |= (long)buf[3] << 24;
-#if SIZEOF_LONG > 4
-    /* Sign extension for 64-bit machines */
-    x |= -(x & 0x80000000L);
-#endif
+    x |= (unsigned int)buf[1] <<  8;
+    x |= (unsigned int)buf[2] << 16;
+    x |= (unsigned int)buf[3] << 24;
+    return x;
+}
+
+/* Given a buffer, return the unsigned int that is represented by the first
+   2 bytes, encoded as little endian. This partially reimplements
+   marshal.c:r_short() */
+static unsigned short
+get_uint16(const unsigned char *buf)
+{
+    unsigned short x;
+    x =  buf[0];
+    x |= (unsigned short)buf[1] <<  8;
     return x;
 }
 
+static void
+set_file_error(PyObject *archive, int eof)
+{
+    if (eof) {
+        PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
+    }
+    else {
+        PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, archive);
+    }
+}
+
 /*
    read_directory(archive) -> files dict (new reference)
 
@@ -856,20 +891,18 @@ read_directory(PyObject *archive)
 {
     PyObject *files = NULL;
     FILE *fp;
-    unsigned short flags;
-    short compress, time, date, name_size;
-    long crc, data_size, file_size, header_size;
-    Py_ssize_t file_offset, header_position, header_offset;
-    long l, count;
-    Py_ssize_t i;
+    unsigned short flags, compress, time, date, name_size;
+    unsigned int crc, data_size, file_size, header_size, header_offset;
+    unsigned long file_offset, header_position;
+    unsigned long arc_offset;  /* Absolute offset to start of the zip-archive. */
+    unsigned int count, i;
+    unsigned char buffer[46];
     char name[MAXPATHLEN + 5];
-    char dummy[8]; /* Buffer to read unused header values into */
     PyObject *nameobj = NULL;
-    char *p, endof_central_dir[22];
-    Py_ssize_t arc_offset;  /* Absolute offset to start of the zip-archive. */
     PyObject *path;
     const char *charset;
     int bootstrap;
+    const char *errmsg = NULL;
 
     fp = _Py_fopen_obj(archive, "rb");
     if (fp == NULL) {
@@ -883,91 +916,112 @@ read_directory(PyObject *archive)
     }
 
     if (fseek(fp, -22, SEEK_END) == -1) {
-        fclose(fp);
-        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
-        return NULL;
+        goto file_error;
     }
-    header_position = ftell(fp);
-    if (fread(endof_central_dir, 1, 22, fp) != 22) {
-        fclose(fp);
-        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
-        return NULL;
+    header_position = (unsigned long)ftell(fp);
+    if (header_position == (unsigned long)-1) {
+        goto file_error;
+    }
+    assert(header_position <= (unsigned long)LONG_MAX);
+    if (fread(buffer, 1, 22, fp) != 22) {
+        goto file_error;
     }
-    if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
+    if (get_uint32(buffer) != 0x06054B50u) {
         /* Bad: End of Central Dir signature */
-        fclose(fp);
-        PyErr_Format(ZipImportError, "not a Zip file: %R", archive);
-        return NULL;
+        errmsg = "not a Zip file";
+        goto invalid_header;
     }
 
-    header_size = get_long((unsigned char *)endof_central_dir + 12);
-    header_offset = get_long((unsigned char *)endof_central_dir + 16);
-    arc_offset = header_position - header_offset - header_size;
-    header_offset += arc_offset;
+    header_size = get_uint32(buffer + 12);
+    header_offset = get_uint32(buffer + 16);
+    if (header_position < header_size) {
+        errmsg = "bad central directory size";
+        goto invalid_header;
+    }
+    if (header_position < header_offset) {
+        errmsg = "bad central directory offset";
+        goto invalid_header;
+    }
+    if (header_position - header_size < header_offset) {
+        errmsg = "bad central directory size or offset";
+        goto invalid_header;
+    }
+    header_position -= header_size;
+    arc_offset = header_position - header_offset;
 
     files = PyDict_New();
-    if (files == NULL)
+    if (files == NULL) {
         goto error;
-
+    }
     /* Start of Central Directory */
     count = 0;
-    if (fseek(fp, header_offset, 0) == -1)
+    if (fseek(fp, (long)header_position, 0) == -1) {
         goto file_error;
+    }
     for (;;) {
         PyObject *t;
+        size_t n;
         int err;
 
+        n = fread(buffer, 1, 46, fp);
+        if (n < 4) {
+            goto eof_error;
+        }
         /* Start of file header */
-        l = PyMarshal_ReadLongFromFile(fp);
-        if (l == -1 && PyErr_Occurred())
-            goto error;
-        if (l != 0x02014B50)
+        if (get_uint32(buffer) != 0x02014B50u) {
             break;              /* Bad: Central Dir File Header */
+        }
+        if (n != 46) {
+            goto eof_error;
+        }
+        flags = get_uint16(buffer + 8);
+        compress = get_uint16(buffer + 10);
+        time = get_uint16(buffer + 12);
+        date = get_uint16(buffer + 14);
+        crc = get_uint32(buffer + 16);
+        data_size = get_uint32(buffer + 20);
+        file_size = get_uint32(buffer + 24);
+        name_size = get_uint16(buffer + 28);
+        header_size = (unsigned int)name_size +
+           get_uint16(buffer + 30) /* extra field */ +
+           get_uint16(buffer + 32) /* comment */;
+
+        file_offset = get_uint32(buffer + 42);
+        if (file_offset > header_offset) {
+            errmsg = "bad local header offset";
+            goto invalid_header;
+        }
+        file_offset += arc_offset;
 
-        /* On Windows, calling fseek to skip over the fields we don't use is
-        slower than reading the data into a dummy buffer because fseek flushes
-        stdio's internal buffers. See issue #8745. */
-        if (fread(dummy, 1, 4, fp) != 4) /* Skip unused fields, avoid fseek */
-            goto file_error;
-
-        flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
-        compress = PyMarshal_ReadShortFromFile(fp);
-        time = PyMarshal_ReadShortFromFile(fp);
-        date = PyMarshal_ReadShortFromFile(fp);
-        crc = PyMarshal_ReadLongFromFile(fp);
-        data_size = PyMarshal_ReadLongFromFile(fp);
-        file_size = PyMarshal_ReadLongFromFile(fp);
-        name_size = PyMarshal_ReadShortFromFile(fp);
-        header_size = name_size +
-           PyMarshal_ReadShortFromFile(fp) +
-           PyMarshal_ReadShortFromFile(fp);
-        if (PyErr_Occurred())
-            goto error;
-
-        if (fread(dummy, 1, 8, fp) != 8) /* Skip unused fields, avoid fseek */
-            goto file_error;
-        file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
-        if (PyErr_Occurred())
-            goto error;
-
-        if (name_size > MAXPATHLEN)
+        if (name_size > MAXPATHLEN) {
             name_size = MAXPATHLEN;
-
-        p = name;
-        for (i = 0; i < (Py_ssize_t)name_size; i++) {
-            *p = (char)getc(fp);
-            if (*p == '/')
-                *p = SEP;
-            p++;
         }
-        *p = 0;         /* Add terminating null byte */
-        for (; i < header_size; i++) /* Skip the rest of the header */
-            if(getc(fp) == EOF) /* Avoid fseek */
+        if (fread(name, 1, name_size, fp) != name_size) {
+            goto file_error;
+        }
+        name[name_size] = '\0';  /* Add terminating null byte */
+        if (SEP != '/') {
+            for (i = 0; i < name_size; i++) {
+                if (name[i] == '/') {
+                    name[i] = SEP;
+                }
+            }
+        }
+        /* Skip the rest of the header.
+         * On Windows, calling fseek to skip over the fields we don't use is
+         * slower than reading the data because fseek flushes stdio's
+         * internal buffers.  See issue #8745. */
+        assert(header_size <= 3*0xFFFFu);
+        for (i = name_size; i < header_size; i++) {
+            if (getc(fp) == EOF) {
                 goto file_error;
+            }
+        }
 
         bootstrap = 0;
-        if (flags & 0x0800)
+        if (flags & 0x0800) {
             charset = "utf-8";
+        }
         else if (!PyThreadState_GET()->interp->codecs_initialized) {
             /* During bootstrap, we may need to load the encodings
                package from a ZIP file. But the cp437 encoding is implemented
@@ -978,44 +1032,59 @@ read_directory(PyObject *archive)
             charset = "ascii";
             bootstrap = 1;
         }
-        else
+        else {
             charset = "cp437";
+        }
         nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
         if (nameobj == NULL) {
-            if (bootstrap)
+            if (bootstrap) {
                 PyErr_Format(PyExc_NotImplementedError,
                     "bootstrap issue: python%i%i.zip contains non-ASCII "
                     "filenames without the unicode flag",
                     PY_MAJOR_VERSION, PY_MINOR_VERSION);
+            }
             goto error;
         }
-        if (PyUnicode_READY(nameobj) == -1)
+        if (PyUnicode_READY(nameobj) == -1) {
             goto error;
+        }
         path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
-        if (path == NULL)
+        if (path == NULL) {
             goto error;
-        t = Py_BuildValue("Nhllnhhl", path, compress, data_size,
+        }
+        t = Py_BuildValue("NHIIkHHI", path, compress, data_size,
                           file_size, file_offset, time, date, crc);
-        if (t == NULL)
+        if (t == NULL) {
             goto error;
+        }
         err = PyDict_SetItem(files, nameobj, t);
         Py_CLEAR(nameobj);
         Py_DECREF(t);
-        if (err != 0)
+        if (err != 0) {
             goto error;
+        }
         count++;
     }
     fclose(fp);
-    if (Py_VerboseFlag)
-        PySys_FormatStderr("# zipimport: found %ld names in %R\n",
+    if (Py_VerboseFlag) {
+        PySys_FormatStderr("# zipimport: found %u names in %R\n",
                            count, archive);
+    }
     return files;
+
+eof_error:
+    set_file_error(archive, !ferror(fp));
+    goto error;
+
 file_error:
-    fclose(fp);
-    Py_XDECREF(files);
-    Py_XDECREF(nameobj);
     PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
-    return NULL;
+    goto error;
+
+invalid_header:
+    assert(errmsg != NULL);
+    PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
+    goto error;
+
 error:
     fclose(fp);
     Py_XDECREF(files);
@@ -1061,84 +1130,80 @@ get_decompress_func(void)
 static PyObject *
 get_data(PyObject *archive, PyObject *toc_entry)
 {
-    PyObject *raw_data, *data = NULL, *decompress;
+    PyObject *raw_data = NULL, *data, *decompress;
     char *buf;
     FILE *fp;
-    int err;
-    Py_ssize_t bytes_read = 0;
-    long l;
     PyObject *datapath;
-    long compress, data_size, file_size, file_offset, bytes_size;
-    long time, date, crc;
-
-    if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
+    unsigned short compress, time, date;
+    unsigned int crc;
+    Py_ssize_t data_size, file_size, bytes_size;
+    long file_offset, header_size;
+    unsigned char buffer[30];
+    const char *errmsg = NULL;
+
+    if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress,
                           &data_size, &file_size, &file_offset, &time,
                           &date, &crc)) {
         return NULL;
     }
+    if (data_size < 0) {
+        PyErr_Format(ZipImportError, "negative data size");
+        return NULL;
+    }
 
     fp = _Py_fopen_obj(archive, "rb");
-    if (!fp)
+    if (!fp) {
         return NULL;
-
+    }
     /* Check to make sure the local file header is correct */
     if (fseek(fp, file_offset, 0) == -1) {
-        fclose(fp);
-        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
-        return NULL;
+        goto file_error;
     }
-
-    l = PyMarshal_ReadLongFromFile(fp);
-    if (l != 0x04034B50) {
+    if (fread(buffer, 1, 30, fp) != 30) {
+        goto eof_error;
+    }
+    if (get_uint32(buffer) != 0x04034B50u) {
         /* Bad: Local File Header */
-        if (!PyErr_Occurred())
-            PyErr_Format(ZipImportError,
-                         "bad local file header in %U",
-                         archive);
-        fclose(fp);
-        return NULL;
+        errmsg = "bad local file header";
+        goto invalid_header;
     }
-    if (fseek(fp, file_offset + 26, 0) == -1) {
-        fclose(fp);
-        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
-        return NULL;
+
+    header_size = (unsigned int)30 +
+        get_uint16(buffer + 26) /* file name */ +
+        get_uint16(buffer + 28) /* extra field */;
+    if (file_offset > LONG_MAX - header_size) {
+        errmsg = "bad local file header size";
+        goto invalid_header;
     }
+    file_offset += header_size;  /* Start of file data */
 
-    l = 30 + PyMarshal_ReadShortFromFile(fp) +
-        PyMarshal_ReadShortFromFile(fp);        /* local header size */
-    if (PyErr_Occurred()) {
+    if (data_size > LONG_MAX - 1) {
         fclose(fp);
+        PyErr_NoMemory();
         return NULL;
     }
-    file_offset += l;           /* Start of file data */
-
     bytes_size = compress == 0 ? data_size : data_size + 1;
-    if (bytes_size == 0)
+    if (bytes_size == 0) {
         bytes_size++;
+    }
     raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
-
     if (raw_data == NULL) {
-        fclose(fp);
-        return NULL;
+        goto error;
     }
     buf = PyBytes_AsString(raw_data);
 
-    err = fseek(fp, file_offset, 0);
-    if (err == 0) {
-        bytes_read = fread(buf, 1, data_size, fp);
-    } else {
-        fclose(fp);
-        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
-        return NULL;
+    if (fseek(fp, file_offset, 0) == -1) {
+        goto file_error;
     }
-    fclose(fp);
-    if (err || bytes_read != data_size) {
+    if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
         PyErr_SetString(PyExc_IOError,
                         "zipimport: can't read data");
-        Py_DECREF(raw_data);
-        return NULL;
+        goto error;
     }
 
+    fclose(fp);
+    fp = NULL;
+
     if (compress != 0) {
         buf[data_size] = 'Z';  /* saw this in zipfile.py */
         data_size++;
@@ -1161,9 +1226,28 @@ get_data(PyObject *archive, PyObject *toc_entry)
     }
     data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
     Py_DECREF(decompress);
-error:
     Py_DECREF(raw_data);
     return data;
+
+eof_error:
+    set_file_error(archive, !ferror(fp));
+    goto error;
+
+file_error:
+    PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
+    goto error;
+
+invalid_header:
+    assert(errmsg != NULL);
+    PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
+    goto error;
+
+error:
+    if (fp != NULL) {
+        fclose(fp);
+    }
+    Py_XDECREF(raw_data);
+    return NULL;
 }
 
 /* Lenient date/time comparison function. The precision of the mtime
@@ -1188,37 +1272,39 @@ static PyObject *
 unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
 {
     PyObject *code;
-    char *buf = PyBytes_AsString(data);
+    unsigned char *buf = (unsigned char *)PyBytes_AsString(data);
     Py_ssize_t size = PyBytes_Size(data);
 
-    if (size <= 9) {
+    if (size < 12) {
         PyErr_SetString(ZipImportError,
                         "bad pyc data");
         return NULL;
     }
 
-    if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
-        if (Py_VerboseFlag)
+    if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
+        if (Py_VerboseFlag) {
             PySys_FormatStderr("# %R has bad magic\n",
                                pathname);
+        }
         Py_INCREF(Py_None);
         return Py_None;  /* signal caller to try alternative */
     }
 
-    if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
-                                mtime)) {
-        if (Py_VerboseFlag)
+    if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) {
+        if (Py_VerboseFlag) {
             PySys_FormatStderr("# %R has bad mtime\n",
                                pathname);
+        }
         Py_INCREF(Py_None);
         return Py_None;  /* signal caller to try alternative */
     }
 
     /* XXX the pyc's size field is ignored; timestamp collisions are probably
        unimportant with zip files. */
-    code = PyMarshal_ReadObjectFromString(buf + 12, size - 12);
-    if (code == NULL)
+    code = PyMarshal_ReadObjectFromString((char *)buf + 12, size - 12);
+    if (code == NULL) {
         return NULL;
+    }
     if (!PyCode_Check(code)) {
         Py_DECREF(code);
         PyErr_Format(PyExc_TypeError,
index 37307be..16cc178 100644 (file)
     #define LEAVE_ZLIB(obj)
 #endif
 
+#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
+#define AT_LEAST_ZLIB_1_2_2_1
+#endif
+
 /* The following parameters are copied from zutil.h, version 0.95 */
 #define DEFLATED   8
 #if MAX_MEM_LEVEL >= 8
@@ -271,7 +275,7 @@ zlib.decompress
     data: Py_buffer
         Compressed data.
     wbits: int(c_default="MAX_WBITS") = MAX_WBITS
-        The window buffer size.
+        The window buffer size and container format.
     bufsize: capped_uint(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE
         The initial output buffer size.
     /
@@ -282,7 +286,7 @@ Returns a bytes object containing the uncompressed data.
 static PyObject *
 zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits,
                      unsigned int bufsize)
-/*[clinic end generated code: output=444d0987f3429574 input=da095118b3243b27]*/
+/*[clinic end generated code: output=444d0987f3429574 input=75123b0d4ff0541d]*/
 {
     PyObject *result_str = NULL;
     Byte *input;
@@ -390,12 +394,16 @@ zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits,
 zlib.compressobj
 
     level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION
-        The compression level (an integer in the range 0-9; default is 6).
-        Higher compression levels are slower, but produce smaller results.
+        The compression level (an integer in the range 0-9 or -1; default is
+        currently equivalent to 6).  Higher compression levels are slower,
+        but produce smaller results.
     method: int(c_default="DEFLATED") = DEFLATED
         The compression algorithm.  If given, this must be DEFLATED.
     wbits: int(c_default="MAX_WBITS") = MAX_WBITS
-        The base two logarithm of the window size (range: 8..15).
+        +9 to +15: The base-two logarithm of the window size.  Include a zlib
+            container.
+        -9 to -15: Generate a raw stream.
+        +25 to +31: Include a gzip container.
     memLevel: int(c_default="DEF_MEM_LEVEL") = DEF_MEM_LEVEL
         Controls the amount of memory used for internal compression state.
         Valid values range from 1 to 9.  Higher values result in higher memory
@@ -413,7 +421,7 @@ Return a compressor object.
 static PyObject *
 zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits,
                       int memLevel, int strategy, Py_buffer *zdict)
-/*[clinic end generated code: output=2949bbb9a5723ccd input=b034847f8821f6af]*/
+/*[clinic end generated code: output=2949bbb9a5723ccd input=2fa3d026f90ab8d5]*/
 {
     compobject *self = NULL;
     int err;
@@ -470,11 +478,36 @@ zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits,
     return (PyObject*)self;
 }
 
+static int
+set_inflate_zdict(compobject *self)
+{
+    Py_buffer zdict_buf;
+    int err;
+
+    if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) {
+        return -1;
+    }
+    if ((size_t)zdict_buf.len > UINT_MAX) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "zdict length does not fit in an unsigned int");
+        PyBuffer_Release(&zdict_buf);
+        return -1;
+    }
+    err = inflateSetDictionary(&(self->zst),
+                               zdict_buf.buf, (unsigned int)zdict_buf.len);
+    PyBuffer_Release(&zdict_buf);
+    if (err != Z_OK) {
+        zlib_error(self->zst, err, "while setting zdict");
+        return -1;
+    }
+    return 0;
+}
+
 /*[clinic input]
 zlib.decompressobj
 
     wbits: int(c_default="MAX_WBITS") = MAX_WBITS
-        The window buffer size.
+        The window buffer size and container format.
     zdict: object(c_default="NULL") = b''
         The predefined compression dictionary.  This must be the same
         dictionary as used by the compressor that produced the input data.
@@ -484,7 +517,7 @@ Return a decompressor object.
 
 static PyObject *
 zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict)
-/*[clinic end generated code: output=8ccd583fbd631798 input=67f05145a6920127]*/
+/*[clinic end generated code: output=8ccd583fbd631798 input=d3832b8511fc977b]*/
 {
     int err;
     compobject *self;
@@ -511,6 +544,20 @@ zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict)
     switch(err) {
     case (Z_OK):
         self->is_initialised = 1;
+        if (self->zdict != NULL && wbits < 0) {
+#ifdef AT_LEAST_ZLIB_1_2_2_1
+            if (set_inflate_zdict(self) < 0) {
+                Py_DECREF(self);
+                return NULL;
+            }
+#else
+            PyErr_Format(ZlibError,
+                         "zlib version %s does not allow raw inflate with dictionary",
+                         ZLIB_VERSION);
+            Py_DECREF(self);
+            return NULL;
+#endif
+        }
         return (PyObject*)self;
     case(Z_STREAM_ERROR):
         Py_DECREF(self);
@@ -667,8 +714,7 @@ save_unconsumed_input(compobject *self, int err)
                       PyBytes_AS_STRING(self->unused_data), old_size);
             Py_MEMCPY(PyBytes_AS_STRING(new_data) + old_size,
                       self->zst.next_in, self->zst.avail_in);
-            Py_DECREF(self->unused_data);
-            self->unused_data = new_data;
+            Py_SETREF(self->unused_data, new_data);
             self->zst.avail_in = 0;
         }
     }
@@ -680,8 +726,7 @@ save_unconsumed_input(compobject *self, int err)
                 (char *)self->zst.next_in, self->zst.avail_in);
         if (new_data == NULL)
             return -1;
-        Py_DECREF(self->unconsumed_tail);
-        self->unconsumed_tail = new_data;
+        Py_SETREF(self->unconsumed_tail, new_data);
     }
     return 0;
 }
@@ -739,29 +784,12 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data,
     Py_END_ALLOW_THREADS
 
     if (err == Z_NEED_DICT && self->zdict != NULL) {
-        Py_buffer zdict_buf;
-        if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) {
+        if (set_inflate_zdict(self) < 0) {
             Py_DECREF(RetVal);
             RetVal = NULL;
             goto error;
         }
 
-        if ((size_t)zdict_buf.len > UINT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                    "zdict length does not fit in an unsigned int");
-            PyBuffer_Release(&zdict_buf);
-            Py_CLEAR(RetVal);
-            goto error;
-        }
-
-        err = inflateSetDictionary(&(self->zst),
-                                   zdict_buf.buf, (unsigned int)zdict_buf.len);
-        PyBuffer_Release(&zdict_buf);
-        if (err != Z_OK) {
-            zlib_error(self->zst, err, "while decompressing data");
-            Py_CLEAR(RetVal);
-            goto error;
-        }
         /* Repeat the call to inflate. */
         Py_BEGIN_ALLOW_THREADS
         err = inflate(&(self->zst), Z_SYNC_FLUSH);
@@ -963,14 +991,11 @@ zlib_Compress_copy_impl(compobject *self)
         goto error;
     }
     Py_INCREF(self->unused_data);
+    Py_XSETREF(retval->unused_data, self->unused_data);
     Py_INCREF(self->unconsumed_tail);
+    Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail);
     Py_XINCREF(self->zdict);
-    Py_XDECREF(retval->unused_data);
-    Py_XDECREF(retval->unconsumed_tail);
-    Py_XDECREF(retval->zdict);
-    retval->unused_data = self->unused_data;
-    retval->unconsumed_tail = self->unconsumed_tail;
-    retval->zdict = self->zdict;
+    Py_XSETREF(retval->zdict, self->zdict);
     retval->eof = self->eof;
 
     /* Mark it as being initialized */
@@ -1022,14 +1047,11 @@ zlib_Decompress_copy_impl(compobject *self)
     }
 
     Py_INCREF(self->unused_data);
+    Py_XSETREF(retval->unused_data, self->unused_data);
     Py_INCREF(self->unconsumed_tail);
+    Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail);
     Py_XINCREF(self->zdict);
-    Py_XDECREF(retval->unused_data);
-    Py_XDECREF(retval->unconsumed_tail);
-    Py_XDECREF(retval->zdict);
-    retval->unused_data = self->unused_data;
-    retval->unconsumed_tail = self->unconsumed_tail;
-    retval->zdict = self->zdict;
+    Py_XSETREF(retval->zdict, self->zdict);
     retval->eof = self->eof;
 
     /* Mark it as being initialized */
@@ -1336,7 +1358,7 @@ PyDoc_STRVAR(zlib_module_documentation,
 "decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n"
 "decompressobj([wbits[, zdict]]]) -- Return a decompressor object.\n"
 "\n"
-"'wbits' is window buffer size.\n"
+"'wbits' is window buffer size and container format.\n"
 "Compressor objects support compress() and flush() methods; decompressor\n"
 "objects support decompress() and flush().");
 
index 5647b57..277be59 100644 (file)
@@ -2565,21 +2565,18 @@ static PyObject *
 bytearray_remove_impl(PyByteArrayObject *self, int value)
 /*[clinic end generated code: output=d659e37866709c13 input=47560b11fd856c24]*/
 {
-    Py_ssize_t where, n = Py_SIZE(self);
+    Py_ssize_t n = Py_SIZE(self);
     char *buf = PyByteArray_AS_STRING(self);
+    char *where = memchr(buf, value, n);
 
-    for (where = 0; where < n; where++) {
-        if (buf[where] == value)
-            break;
-    }
-    if (where == n) {
+    if (!where) {
         PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
         return NULL;
     }
     if (!_canresize(self))
         return NULL;
 
-    memmove(buf + where, buf + where + 1, n - where);
+    memmove(where, where + 1, buf + n - where);
     if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
         return NULL;
 
@@ -2974,7 +2971,7 @@ bytearray_sizeof_impl(PyByteArrayObject *self)
 {
     Py_ssize_t res;
 
-    res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
+    res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char);
     return PyLong_FromSsize_t(res);
 }
 
@@ -3091,7 +3088,7 @@ bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
 bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
 bytearray() -> empty bytes array\n\
 \n\
-Construct an mutable bytearray object from:\n\
+Construct a mutable bytearray object from:\n\
   - an iterable yielding integers in range(256)\n\
   - a text string encoded using the specified encoding\n\
   - a bytes or a buffer object\n\
@@ -3186,8 +3183,8 @@ bytearrayiter_next(bytesiterobject *it)
         return item;
     }
 
-    Py_DECREF(seq);
     it->it_seq = NULL;
+    Py_DECREF(seq);
     return NULL;
 }
 
index 08275ad..c2aa65c 100644 (file)
@@ -34,7 +34,7 @@ static PyBytesObject *nullstring;
    For PyBytes_FromString(), the parameter `str' points to a null-terminated
    string containing exactly `size' bytes.
 
-   For PyBytes_FromStringAndSize(), the parameter the parameter `str' is
+   For PyBytes_FromStringAndSize(), the parameter `str' is
    either NULL or else points to a string containing at least `size' bytes.
    For PyBytes_FromStringAndSize(), the string in the `str' parameter does
    not have to be null-terminated.  (Therefore it is safe to construct a
@@ -3146,7 +3146,7 @@ static PyNumberMethods bytes_as_number = {
 };
 
 static PyObject *
-str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 
 static PyObject *
 bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
@@ -3161,7 +3161,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     _Py_IDENTIFIER(__bytes__);
 
     if (type != &PyBytes_Type)
-        return str_subtype_new(type, args, kwds);
+        return bytes_subtype_new(type, args, kwds);
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x,
                                      &encoding, &errors))
         return NULL;
@@ -3175,11 +3175,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         return PyBytes_FromStringAndSize(NULL, 0);
     }
 
-    if (PyUnicode_Check(x)) {
+    if (encoding != NULL) {
         /* Encode via the codec registry */
-        if (encoding == NULL) {
+        if (!PyUnicode_Check(x)) {
             PyErr_SetString(PyExc_TypeError,
-                            "string argument without an encoding");
+                            "encoding without a string argument");
             return NULL;
         }
         new = PyUnicode_AsEncodedString(x, encoding, errors);
@@ -3189,10 +3189,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         return new;
     }
 
-    /* If it's not unicode, there can't be encoding or errors */
-    if (encoding != NULL || errors != NULL) {
+    if (errors != NULL) {
         PyErr_SetString(PyExc_TypeError,
-            "encoding or errors without a string argument");
+                        PyUnicode_Check(x) ?
+                        "string argument without an encoding" :
+                        "errors without a string argument");
         return NULL;
     }
 
@@ -3217,6 +3218,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     else if (PyErr_Occurred())
         return NULL;
 
+    if (PyUnicode_Check(x)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "string argument without an encoding");
+        return NULL;
+    }
     /* Is it an integer? */
     size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
     if (size == -1 && PyErr_Occurred()) {
@@ -3388,7 +3394,7 @@ PyBytes_FromObject(PyObject *x)
 }
 
 static PyObject *
-str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
     PyObject *tmp, *pnew;
     Py_ssize_t n;
@@ -3397,7 +3403,7 @@ str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     tmp = bytes_new(&PyBytes_Type, args, kwds);
     if (tmp == NULL)
         return NULL;
-    assert(PyBytes_CheckExact(tmp));
+    assert(PyBytes_Check(tmp));
     n = PyBytes_GET_SIZE(tmp);
     pnew = type->tp_alloc(type, n);
     if (pnew != NULL) {
@@ -3514,8 +3520,7 @@ PyBytes_Concat(PyObject **pv, PyObject *w)
         /* Multiple references, need to create new object */
         PyObject *v;
         v = bytes_concat(*pv, w);
-        Py_DECREF(*pv);
-        *pv = v;
+        Py_SETREF(*pv, v);
     }
 }
 
@@ -3623,8 +3628,8 @@ striter_next(striterobject *it)
         return item;
     }
 
-    Py_DECREF(seq);
     it->it_seq = NULL;
+    Py_DECREF(seq);
     return NULL;
 }
 
index eb5ad98..9f4eddb 100644 (file)
@@ -150,8 +150,8 @@ PyTypeObject PyCell_Type = {
     "cell",
     sizeof(PyCellObject),
     0,
-    (destructor)cell_dealloc,               /* tp_dealloc */
-    0,                                      /* tp_print */
+    (destructor)cell_dealloc,                   /* tp_dealloc */
+    0,                                          /* tp_print */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
     0,                                          /* tp_reserved */
@@ -165,7 +165,7 @@ PyTypeObject PyCell_Type = {
     PyObject_GenericGetAttr,                    /* tp_getattro */
     0,                                          /* tp_setattro */
     0,                                          /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
     0,                                          /* tp_doc */
     (traverseproc)cell_traverse,                /* tp_traverse */
     (inquiry)cell_clear,                        /* tp_clear */
index 353f414..964ae62 100644 (file)
@@ -384,7 +384,7 @@ code_sizeof(PyCodeObject *co, void *unused)
 {
     Py_ssize_t res;
 
-    res = sizeof(PyCodeObject);
+    res = _PyObject_SIZE(Py_TYPE(co));
     if (co->co_cell2arg != NULL && co->co_cellvars != NULL)
         res += PyTuple_GET_SIZE(co->co_cellvars) * sizeof(unsigned char);
     return PyLong_FromSsize_t(res);
@@ -409,11 +409,135 @@ code_repr(PyCodeObject *co)
     }
 }
 
+PyObject*
+_PyCode_ConstantKey(PyObject *op)
+{
+    PyObject *key;
+
+    /* Py_None and Py_Ellipsis are singleton */
+    if (op == Py_None || op == Py_Ellipsis
+       || PyLong_CheckExact(op)
+       || PyBool_Check(op)
+       || PyBytes_CheckExact(op)
+       || PyUnicode_CheckExact(op)
+          /* code_richcompare() uses _PyCode_ConstantKey() internally */
+       || PyCode_Check(op)) {
+        key = PyTuple_Pack(2, Py_TYPE(op), op);
+    }
+    else if (PyFloat_CheckExact(op)) {
+        double d = PyFloat_AS_DOUBLE(op);
+        /* all we need is to make the tuple different in either the 0.0
+         * or -0.0 case from all others, just to avoid the "coercion".
+         */
+        if (d == 0.0 && copysign(1.0, d) < 0.0)
+            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
+        else
+            key = PyTuple_Pack(2, Py_TYPE(op), op);
+    }
+    else if (PyComplex_CheckExact(op)) {
+        Py_complex z;
+        int real_negzero, imag_negzero;
+        /* For the complex case we must make complex(x, 0.)
+           different from complex(x, -0.) and complex(0., y)
+           different from complex(-0., y), for any x and y.
+           All four complex zeros must be distinguished.*/
+        z = PyComplex_AsCComplex(op);
+        real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
+        imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
+        /* use True, False and None singleton as tags for the real and imag
+         * sign, to make tuples different */
+        if (real_negzero && imag_negzero) {
+            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
+        }
+        else if (imag_negzero) {
+            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
+        }
+        else if (real_negzero) {
+            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
+        }
+        else {
+            key = PyTuple_Pack(2, Py_TYPE(op), op);
+        }
+    }
+    else if (PyTuple_CheckExact(op)) {
+        Py_ssize_t i, len;
+        PyObject *tuple;
+
+        len = PyTuple_GET_SIZE(op);
+        tuple = PyTuple_New(len);
+        if (tuple == NULL)
+            return NULL;
+
+        for (i=0; i < len; i++) {
+            PyObject *item, *item_key;
+
+            item = PyTuple_GET_ITEM(op, i);
+            item_key = _PyCode_ConstantKey(item);
+            if (item_key == NULL) {
+                Py_DECREF(tuple);
+                return NULL;
+            }
+
+            PyTuple_SET_ITEM(tuple, i, item_key);
+        }
+
+        key = PyTuple_Pack(3, Py_TYPE(op), op, tuple);
+        Py_DECREF(tuple);
+    }
+    else if (PyFrozenSet_CheckExact(op)) {
+        Py_ssize_t pos = 0;
+        PyObject *item;
+        Py_hash_t hash;
+        Py_ssize_t i, len;
+        PyObject *tuple, *set;
+
+        len = PySet_GET_SIZE(op);
+        tuple = PyTuple_New(len);
+        if (tuple == NULL)
+            return NULL;
+
+        i = 0;
+        while (_PySet_NextEntry(op, &pos, &item, &hash)) {
+            PyObject *item_key;
+
+            item_key = _PyCode_ConstantKey(item);
+            if (item_key == NULL) {
+                Py_DECREF(tuple);
+                return NULL;
+            }
+
+            assert(i < len);
+            PyTuple_SET_ITEM(tuple, i, item_key);
+            i++;
+        }
+        set = PyFrozenSet_New(tuple);
+        Py_DECREF(tuple);
+        if (set == NULL)
+            return NULL;
+
+        key = PyTuple_Pack(3, Py_TYPE(op), op, set);
+        Py_DECREF(set);
+        return key;
+    }
+    else {
+        /* for other types, use the object identifier as a unique identifier
+         * to ensure that they are seen as unequal. */
+        PyObject *obj_id = PyLong_FromVoidPtr(op);
+        if (obj_id == NULL)
+            return NULL;
+
+        key = PyTuple_Pack(3, Py_TYPE(op), op, obj_id);
+        Py_DECREF(obj_id);
+    }
+    return key;
+}
+
 static PyObject *
 code_richcompare(PyObject *self, PyObject *other, int op)
 {
     PyCodeObject *co, *cp;
     int eq;
+    PyObject *consts1, *consts2;
     PyObject *res;
 
     if ((op != Py_EQ && op != Py_NE) ||
@@ -439,8 +563,21 @@ code_richcompare(PyObject *self, PyObject *other, int op)
     if (!eq) goto unequal;
     eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
     if (eq <= 0) goto unequal;
-    eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
+
+    /* compare constants */
+    consts1 = _PyCode_ConstantKey(co->co_consts);
+    if (!consts1)
+        return NULL;
+    consts2 = _PyCode_ConstantKey(cp->co_consts);
+    if (!consts2) {
+        Py_DECREF(consts1);
+        return NULL;
+    }
+    eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
+    Py_DECREF(consts1);
+    Py_DECREF(consts2);
     if (eq <= 0) goto unequal;
+
     eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
     if (eq <= 0) goto unequal;
     eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
index 9ffbca7..da68e3b 100644 (file)
@@ -1386,27 +1386,27 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
         return NULL;
     }
     args = cached_args;
-    if (!args || Py_REFCNT(args) != 1) {
-        Py_CLEAR(cached_args);
-        if (!(cached_args = args = PyTuple_New(1)))
+    cached_args = NULL;
+    if (!args) {
+        args = PyTuple_New(1);
+        if (!args)
             return NULL;
+        _PyObject_GC_UNTRACK(args);
     }
-    Py_INCREF(args);
-    assert (Py_REFCNT(args) == 2);
     Py_INCREF(obj);
     PyTuple_SET_ITEM(args, 0, obj);
     ret = PyObject_Call(gs->prop_get, args, NULL);
-    if (args == cached_args) {
-        if (Py_REFCNT(args) == 2) {
-            obj = PyTuple_GET_ITEM(args, 0);
-            PyTuple_SET_ITEM(args, 0, NULL);
-            Py_XDECREF(obj);
-        }
-        else {
-            Py_CLEAR(cached_args);
-        }
+    if (cached_args == NULL && Py_REFCNT(args) == 1) {
+        assert(Py_SIZE(args) == 1);
+        assert(PyTuple_GET_ITEM(args, 0) == obj);
+        cached_args = args;
+        Py_DECREF(obj);
+    }
+    else {
+        assert(Py_REFCNT(args) >= 1);
+        _PyObject_GC_TRACK(args);
+        Py_DECREF(args);
     }
-    Py_DECREF(args);
     return ret;
 }
 
@@ -1509,8 +1509,7 @@ property_init(PyObject *self, PyObject *args, PyObject *kwds)
         PyObject *get_doc = _PyObject_GetAttrId(get, &PyId___doc__);
         if (get_doc) {
             if (Py_TYPE(self) == &PyProperty_Type) {
-                Py_XDECREF(prop->prop_doc);
-                prop->prop_doc = get_doc;
+                Py_XSETREF(prop->prop_doc, get_doc);
             }
             else {
                 /* If this is a property subclass, put __doc__
index 624ae9b..d774586 100644 (file)
@@ -1064,8 +1064,7 @@ PyDict_GetItem(PyObject *op, PyObject *key)
        Let's just hope that no exception occurs then...  This must be
        _PyThreadState_Current and not PyThreadState_GET() because in debug
        mode, the latter complains if tstate is NULL. */
-    tstate = (PyThreadState*)_Py_atomic_load_relaxed(
-        &_PyThreadState_Current);
+    tstate = _PyThreadState_UncheckedGet();
     if (tstate != NULL && tstate->curexc_type != NULL) {
         /* preserve the existing exception */
         PyObject *err_type, *err_value, *err_tb;
@@ -1102,8 +1101,7 @@ _PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
        Let's just hope that no exception occurs then...  This must be
        _PyThreadState_Current and not PyThreadState_GET() because in debug
        mode, the latter complains if tstate is NULL. */
-    tstate = (PyThreadState*)_Py_atomic_load_relaxed(
-        &_PyThreadState_Current);
+    tstate = _PyThreadState_UncheckedGet();
     if (tstate != NULL && tstate->curexc_type != NULL) {
         /* preserve the existing exception */
         PyObject *err_type, *err_value, *err_tb;
@@ -2554,20 +2552,20 @@ dict_tp_clear(PyObject *op)
 
 static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
 
-PyObject *
+Py_ssize_t
 _PyDict_SizeOf(PyDictObject *mp)
 {
     Py_ssize_t size, res;
 
     size = DK_SIZE(mp->ma_keys);
-    res = sizeof(PyDictObject);
+    res = _PyObject_SIZE(Py_TYPE(mp));
     if (mp->ma_values)
         res += size * sizeof(PyObject*);
     /* If the dictionary is split, the keys portion is accounted-for
        in the type object. */
     if (mp->ma_keys->dk_refcnt == 1)
         res += sizeof(PyDictKeysObject) + (size-1) * sizeof(PyDictKeyEntry);
-    return PyLong_FromSsize_t(res);
+    return res;
 }
 
 Py_ssize_t
@@ -2576,6 +2574,12 @@ _PyDict_KeysSize(PyDictKeysObject *keys)
     return sizeof(PyDictKeysObject) + (DK_SIZE(keys)-1) * sizeof(PyDictKeyEntry);
 }
 
+static PyObject *
+dict_sizeof(PyDictObject *mp)
+{
+    return PyLong_FromSsize_t(_PyDict_SizeOf(mp));
+}
+
 PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
 
 PyDoc_STRVAR(sizeof__doc__,
@@ -2623,7 +2627,7 @@ static PyMethodDef mapp_methods[] = {
     DICT___CONTAINS___METHODDEF
     {"__getitem__", (PyCFunction)dict_subscript,        METH_O | METH_COEXIST,
      getitem__doc__},
-    {"__sizeof__",      (PyCFunction)_PyDict_SizeOf,       METH_NOARGS,
+    {"__sizeof__",      (PyCFunction)dict_sizeof,       METH_NOARGS,
      sizeof__doc__},
     {"get",         (PyCFunction)dict_get,          METH_VARARGS,
      get__doc__},
@@ -2981,8 +2985,8 @@ static PyObject *dictiter_iternextkey(dictiterobject *di)
     return key;
 
 fail:
-    Py_DECREF(d);
     di->di_dict = NULL;
+    Py_DECREF(d);
     return NULL;
 }
 
@@ -3062,8 +3066,8 @@ static PyObject *dictiter_iternextvalue(dictiterobject *di)
     return value;
 
 fail:
-    Py_DECREF(d);
     di->di_dict = NULL;
+    Py_DECREF(d);
     return NULL;
 }
 
@@ -3157,8 +3161,8 @@ static PyObject *dictiter_iternextitem(dictiterobject *di)
     return result;
 
 fail:
-    Py_DECREF(d);
     di->di_dict = NULL;
+    Py_DECREF(d);
     return NULL;
 }
 
@@ -3444,7 +3448,7 @@ dictviews_sub(PyObject* self, PyObject *other)
     if (result == NULL)
         return NULL;
 
-    tmp = _PyObject_CallMethodId(result, &PyId_difference_update, "O", other);
+    tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_difference_update, other, NULL);
     if (tmp == NULL) {
         Py_DECREF(result);
         return NULL;
@@ -3464,7 +3468,7 @@ _PyDictView_Intersect(PyObject* self, PyObject *other)
     if (result == NULL)
         return NULL;
 
-    tmp = _PyObject_CallMethodId(result, &PyId_intersection_update, "O", other);
+    tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_intersection_update, other, NULL);
     if (tmp == NULL) {
         Py_DECREF(result);
         return NULL;
@@ -3484,7 +3488,7 @@ dictviews_or(PyObject* self, PyObject *other)
     if (result == NULL)
         return NULL;
 
-    tmp = _PyObject_CallMethodId(result, &PyId_update, "O", other);
+    tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_update, other, NULL);
     if (tmp == NULL) {
         Py_DECREF(result);
         return NULL;
@@ -3504,8 +3508,7 @@ dictviews_xor(PyObject* self, PyObject *other)
     if (result == NULL)
         return NULL;
 
-    tmp = _PyObject_CallMethodId(result, &PyId_symmetric_difference_update, "O",
-                              other);
+    tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_symmetric_difference_update, other, NULL);
     if (tmp == NULL) {
         Py_DECREF(result);
         return NULL;
index f5a1a2b..aaff0bc 100644 (file)
@@ -206,8 +206,7 @@ BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
     seq = PySequence_Tuple(val);
     if (!seq)
         return -1;
-    Py_CLEAR(self->args);
-    self->args = seq;
+    Py_XSETREF(self->args, seq);
     return 0;
 }
 
@@ -236,8 +235,7 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb)
     }
 
     Py_XINCREF(tb);
-    Py_XDECREF(self->traceback);
-    self->traceback = tb;
+    Py_XSETREF(self->traceback, tb);
     return 0;
 }
 
@@ -563,12 +561,14 @@ SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
 
     if (size == 0)
         return 0;
-    Py_CLEAR(self->code);
-    if (size == 1)
-        self->code = PyTuple_GET_ITEM(args, 0);
-    else /* size > 1 */
-        self->code = args;
-    Py_INCREF(self->code);
+    if (size == 1) {
+        Py_INCREF(PyTuple_GET_ITEM(args, 0));
+        Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0));
+    }
+    else { /* size > 1 */
+        Py_INCREF(args);
+        Py_XSETREF(self->code, args);
+    }
     return 0;
 }
 
@@ -627,9 +627,8 @@ ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds)
 #define GET_KWD(kwd) { \
     kwd = PyDict_GetItemString(kwds, #kwd); \
     if (kwd) { \
-        Py_CLEAR(self->kwd); \
-        self->kwd = kwd;   \
-        Py_INCREF(self->kwd);\
+        Py_INCREF(kwd); \
+        Py_XSETREF(self->kwd, kwd); \
         if (PyDict_DelItemString(kwds, #kwd)) \
             return -1; \
     } \
@@ -647,9 +646,8 @@ ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds)
     if (!PyArg_UnpackTuple(args, "ImportError", 1, 1, &msg))
         return -1;
 
-    Py_CLEAR(self->msg);          /* replacing */
-    self->msg = msg;
-    Py_INCREF(self->msg);
+    Py_INCREF(msg);
+    Py_XSETREF(self->msg, msg);
 
     return 0;
 }
@@ -859,8 +857,7 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args,
 #endif
 
     /* Steals the reference to args */
-    Py_CLEAR(self->args);
-    self->args = args;
+    Py_XSETREF(self->args, args);
     *p_args = args = NULL;
 
     return 0;
@@ -879,7 +876,7 @@ oserror_use_init(PyTypeObject *type)
        solution, given __new__ takes a variable number of arguments,
        is to defer arg parsing and initialization to __init__.
 
-       But when __new__ is overriden as well, it should call our __new__
+       But when __new__ is overridden as well, it should call our __new__
        with the right arguments.
 
        (see http://bugs.python.org/issue12555#msg148829 )
@@ -1279,9 +1276,8 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
         return -1;
 
     if (lenargs >= 1) {
-        Py_CLEAR(self->msg);
-        self->msg = PyTuple_GET_ITEM(args, 0);
-        Py_INCREF(self->msg);
+        Py_INCREF(PyTuple_GET_ITEM(args, 0));
+        Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0));
     }
     if (lenargs == 2) {
         info = PyTuple_GET_ITEM(args, 1);
@@ -1296,21 +1292,17 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
             return -1;
         }
 
-        Py_CLEAR(self->filename);
-        self->filename = PyTuple_GET_ITEM(info, 0);
-        Py_INCREF(self->filename);
+        Py_INCREF(PyTuple_GET_ITEM(info, 0));
+        Py_XSETREF(self->filename, PyTuple_GET_ITEM(info, 0));
 
-        Py_CLEAR(self->lineno);
-        self->lineno = PyTuple_GET_ITEM(info, 1);
-        Py_INCREF(self->lineno);
+        Py_INCREF(PyTuple_GET_ITEM(info, 1));
+        Py_XSETREF(self->lineno, PyTuple_GET_ITEM(info, 1));
 
-        Py_CLEAR(self->offset);
-        self->offset = PyTuple_GET_ITEM(info, 2);
-        Py_INCREF(self->offset);
+        Py_INCREF(PyTuple_GET_ITEM(info, 2));
+        Py_XSETREF(self->offset, PyTuple_GET_ITEM(info, 2));
 
-        Py_CLEAR(self->text);
-        self->text = PyTuple_GET_ITEM(info, 3);
-        Py_INCREF(self->text);
+        Py_INCREF(PyTuple_GET_ITEM(info, 3));
+        Py_XSETREF(self->text, PyTuple_GET_ITEM(info, 3));
 
         Py_DECREF(info);
 
@@ -1555,8 +1547,7 @@ set_unicodefromstring(PyObject **attr, const char *value)
     PyObject *obj = PyUnicode_FromString(value);
     if (!obj)
         return -1;
-    Py_CLEAR(*attr);
-    *attr = obj;
+    Py_XSETREF(*attr, obj);
     return 0;
 }
 
@@ -1962,8 +1953,7 @@ UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
         Py_buffer view;
         if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)
             goto error;
-        Py_CLEAR(ude->object);
-        ude->object = PyBytes_FromStringAndSize(view.buf, view.len);
+        Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len));
         PyBuffer_Release(&view);
         if (!ude->object)
             goto error;
@@ -2872,9 +2862,8 @@ _check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)
     }
     if (PyUnicode_Tailmatch(self->text, print_prefix,
                             start, text_len, -1)) {
-        Py_CLEAR(self->msg);
-        self->msg = PyUnicode_FromString(
-                   "Missing parentheses in call to 'print'");
+        Py_XSETREF(self->msg,
+                  PyUnicode_FromString("Missing parentheses in call to 'print'"));
         return 1;
     }
 
@@ -2887,9 +2876,8 @@ _check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)
     }
     if (PyUnicode_Tailmatch(self->text, exec_prefix,
                             start, text_len, -1)) {
-        Py_CLEAR(self->msg);
-        self->msg = PyUnicode_FromString(
-                    "Missing parentheses in call to 'exec'");
+        Py_XSETREF(self->msg,
+                  PyUnicode_FromString("Missing parentheses in call to 'exec'"));
         return 1;
     }
     /* Fall back to the default error message */
index b8d6f2b..d92bec3 100644 (file)
@@ -1568,7 +1568,7 @@ float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     tmp = float_new(&PyFloat_Type, args, kwds);
     if (tmp == NULL)
         return NULL;
-    assert(PyFloat_CheckExact(tmp));
+    assert(PyFloat_Check(tmp));
     newobj = type->tp_alloc(type, 0);
     if (newobj == NULL) {
         Py_DECREF(tmp);
index 172f2cb..9aadd61 100644 (file)
@@ -349,15 +349,13 @@ frame_gettrace(PyFrameObject *f, void *closure)
 static int
 frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
 {
-    PyObject* old_value;
-
     /* We rely on f_lineno being accurate when f_trace is set. */
     f->f_lineno = PyFrame_GetLineNumber(f);
 
-    old_value = f->f_trace;
+    if (v == Py_None)
+        v = NULL;
     Py_XINCREF(v);
-    f->f_trace = v;
-    Py_XDECREF(old_value);
+    Py_XSETREF(f->f_trace, v);
 
     return 0;
 }
@@ -857,8 +855,7 @@ dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
             }
         } else if (values[j] != value) {
             Py_XINCREF(value);
-            Py_XDECREF(values[j]);
-            values[j] = value;
+            Py_XSETREF(values[j], value);
         }
         Py_XDECREF(value);
     }
index b043934..e6c327d 100644 (file)
@@ -127,8 +127,7 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
         PyErr_SetString(PyExc_SystemError, "non-tuple default args");
         return -1;
     }
-    Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);
-    ((PyFunctionObject *) op) -> func_defaults = defaults;
+    Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults);
     return 0;
 }
 
@@ -159,8 +158,7 @@ PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults)
                         "non-dict keyword only default args");
         return -1;
     }
-    Py_XDECREF(((PyFunctionObject *)op) -> func_kwdefaults);
-    ((PyFunctionObject *) op) -> func_kwdefaults = defaults;
+    Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults);
     return 0;
 }
 
@@ -192,8 +190,7 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure)
                      closure->ob_type->tp_name);
         return -1;
     }
-    Py_XDECREF(((PyFunctionObject *) op) -> func_closure);
-    ((PyFunctionObject *) op) -> func_closure = closure;
+    Py_XSETREF(((PyFunctionObject *)op)->func_closure, closure);
     return 0;
 }
 
@@ -224,8 +221,7 @@ PyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
                         "non-dict annotations");
         return -1;
     }
-    Py_XDECREF(((PyFunctionObject *)op) -> func_annotations);
-    ((PyFunctionObject *) op) -> func_annotations = annotations;
+    Py_XSETREF(((PyFunctionObject *)op)->func_annotations, annotations);
     return 0;
 }
 
@@ -531,8 +527,7 @@ func_new(PyTypeObject* type, PyObject* args, PyObject* kw)
 
     if (name != Py_None) {
         Py_INCREF(name);
-        Py_DECREF(newfunc->func_name);
-        newfunc->func_name = name;
+        Py_SETREF(newfunc->func_name, name);
     }
     if (defaults != Py_None) {
         Py_INCREF(defaults);
index 00ebbf1..b3e0a46 100644 (file)
@@ -78,7 +78,7 @@ gen_dealloc(PyGenObject *gen)
 }
 
 static PyObject *
-gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
+gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
 {
     PyThreadState *tstate = PyThreadState_GET();
     PyFrameObject *f = gen->gi_frame;
@@ -92,9 +92,18 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
         return NULL;
     }
     if (f == NULL || f->f_stacktop == NULL) {
-        /* Only set exception if called from send() */
-        if (arg && !exc)
+        if (PyCoro_CheckExact(gen) && !closing) {
+            /* `gen` is an exhausted coroutine: raise an error,
+               except when called from gen_close(), which should
+               always be a silent method. */
+            PyErr_SetString(
+                PyExc_RuntimeError,
+                "cannot reuse already awaited coroutine");
+        } else if (arg && !exc) {
+            /* `gen` is an exhausted generator:
+               only set exception if called from send(). */
             PyErr_SetNone(PyExc_StopIteration);
+        }
         return NULL;
     }
 
@@ -220,7 +229,7 @@ return next yielded value or raise StopIteration.");
 PyObject *
 _PyGen_Send(PyGenObject *gen, PyObject *arg)
 {
-    return gen_send_ex(gen, arg, 0);
+    return gen_send_ex(gen, arg, 0, 0);
 }
 
 PyDoc_STRVAR(close_doc,
@@ -258,8 +267,8 @@ gen_close_iter(PyObject *yf)
     return 0;
 }
 
-static PyObject *
-gen_yf(PyGenObject *gen)
+PyObject *
+_PyGen_yf(PyGenObject *gen)
 {
     PyObject *yf = NULL;
     PyFrameObject *f = gen->gi_frame;
@@ -281,7 +290,7 @@ static PyObject *
 gen_close(PyGenObject *gen, PyObject *args)
 {
     PyObject *retval;
-    PyObject *yf = gen_yf(gen);
+    PyObject *yf = _PyGen_yf(gen);
     int err = 0;
 
     if (yf) {
@@ -292,7 +301,7 @@ gen_close(PyGenObject *gen, PyObject *args)
     }
     if (err == 0)
         PyErr_SetNone(PyExc_GeneratorExit);
-    retval = gen_send_ex(gen, Py_None, 1);
+    retval = gen_send_ex(gen, Py_None, 1, 1);
     if (retval) {
         char *msg = "generator ignored GeneratorExit";
         if (PyCoro_CheckExact(gen))
@@ -321,7 +330,7 @@ gen_throw(PyGenObject *gen, PyObject *args)
     PyObject *typ;
     PyObject *tb = NULL;
     PyObject *val = NULL;
-    PyObject *yf = gen_yf(gen);
+    PyObject *yf = _PyGen_yf(gen);
     _Py_IDENTIFIER(throw);
 
     if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
@@ -336,7 +345,7 @@ gen_throw(PyGenObject *gen, PyObject *args)
             gen->gi_running = 0;
             Py_DECREF(yf);
             if (err < 0)
-                return gen_send_ex(gen, Py_None, 1);
+                return gen_send_ex(gen, Py_None, 1, 0);
             goto throw_here;
         }
         if (PyGen_CheckExact(yf)) {
@@ -369,10 +378,10 @@ gen_throw(PyGenObject *gen, PyObject *args)
             /* Termination repetition of YIELD_FROM */
             gen->gi_frame->f_lasti++;
             if (_PyGen_FetchStopIterationValue(&val) == 0) {
-                ret = gen_send_ex(gen, val, 0);
+                ret = gen_send_ex(gen, val, 0, 0);
                 Py_DECREF(val);
             } else {
-                ret = gen_send_ex(gen, Py_None, 1);
+                ret = gen_send_ex(gen, Py_None, 1, 0);
             }
         }
         return ret;
@@ -426,7 +435,7 @@ throw_here:
     }
 
     PyErr_Restore(typ, val, tb);
-    return gen_send_ex(gen, Py_None, 1);
+    return gen_send_ex(gen, Py_None, 1, 0);
 
 failed_throw:
     /* Didn't use our arguments, so restore their original refcounts */
@@ -440,7 +449,7 @@ failed_throw:
 static PyObject *
 gen_iternext(PyGenObject *gen)
 {
-    return gen_send_ex(gen, NULL, 0);
+    return gen_send_ex(gen, NULL, 0, 0);
 }
 
 /*
@@ -555,7 +564,7 @@ gen_set_qualname(PyGenObject *op, PyObject *value)
 static PyObject *
 gen_getyieldfrom(PyGenObject *gen)
 {
-    PyObject *yf = gen_yf(gen);
+    PyObject *yf = _PyGen_yf(gen);
     if (yf == NULL)
         Py_RETURN_NONE;
     return yf;
@@ -790,7 +799,7 @@ coro_await(PyCoroObject *coro)
 static PyObject *
 coro_get_cr_await(PyCoroObject *coro)
 {
-    PyObject *yf = gen_yf((PyGenObject *) coro);
+    PyObject *yf = _PyGen_yf((PyGenObject *) coro);
     if (yf == NULL)
         Py_RETURN_NONE;
     return yf;
@@ -901,13 +910,13 @@ coro_wrapper_dealloc(PyCoroWrapper *cw)
 static PyObject *
 coro_wrapper_iternext(PyCoroWrapper *cw)
 {
-    return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0);
+    return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0);
 }
 
 static PyObject *
 coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
 {
-    return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0);
+    return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0);
 }
 
 static PyObject *
@@ -983,3 +992,97 @@ PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
 {
     return gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
 }
+
+
+/* __aiter__ wrapper; see http://bugs.python.org/issue27243 for details. */
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *aw_aiter;
+} PyAIterWrapper;
+
+
+static PyObject *
+aiter_wrapper_iternext(PyAIterWrapper *aw)
+{
+    PyErr_SetObject(PyExc_StopIteration, aw->aw_aiter);
+    return NULL;
+}
+
+static int
+aiter_wrapper_traverse(PyAIterWrapper *aw, visitproc visit, void *arg)
+{
+    Py_VISIT((PyObject *)aw->aw_aiter);
+    return 0;
+}
+
+static void
+aiter_wrapper_dealloc(PyAIterWrapper *aw)
+{
+    _PyObject_GC_UNTRACK((PyObject *)aw);
+    Py_CLEAR(aw->aw_aiter);
+    PyObject_GC_Del(aw);
+}
+
+static PyAsyncMethods aiter_wrapper_as_async = {
+    PyObject_SelfIter,                          /* am_await */
+    0,                                          /* am_aiter */
+    0                                           /* am_anext */
+};
+
+PyTypeObject _PyAIterWrapper_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "aiter_wrapper",
+    sizeof(PyAIterWrapper),                     /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    (destructor)aiter_wrapper_dealloc,          /* destructor tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    &aiter_wrapper_as_async,                    /* 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 */
+    PyObject_GenericGetAttr,                    /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
+    "A wrapper object for __aiter__ bakwards compatibility.",
+    (traverseproc)aiter_wrapper_traverse,       /* tp_traverse */
+    0,                                          /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    PyObject_SelfIter,                          /* tp_iter */
+    (iternextfunc)aiter_wrapper_iternext,       /* tp_iternext */
+    0,                                          /* 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 */
+    0,                                          /* tp_init */
+    0,                                          /* tp_alloc */
+    0,                                          /* tp_new */
+    PyObject_Del,                               /* tp_free */
+};
+
+
+PyObject *
+_PyAIterWrapper_New(PyObject *aiter)
+{
+    PyAIterWrapper *aw = PyObject_GC_New(PyAIterWrapper,
+                                         &_PyAIterWrapper_Type);
+    if (aw == NULL) {
+        return NULL;
+    }
+    Py_INCREF(aiter);
+    aw->aw_aiter = aiter;
+    _PyObject_GC_TRACK(aw);
+    return (PyObject *)aw;
+}
index 2fb0c88..ab29ff8 100644 (file)
@@ -69,8 +69,8 @@ iter_iternext(PyObject *iterator)
         PyErr_ExceptionMatches(PyExc_StopIteration))
     {
         PyErr_Clear();
-        Py_DECREF(seq);
         it->it_seq = NULL;
+        Py_DECREF(seq);
     }
     return NULL;
 }
index 45e54ce..d688179 100644 (file)
@@ -2324,7 +2324,7 @@ list_sizeof(PyListObject *self)
 {
     Py_ssize_t res;
 
-    res = sizeof(PyListObject) + self->allocated * sizeof(void*);
+    res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*);
     return PyLong_FromSsize_t(res);
 }
 
@@ -2782,8 +2782,8 @@ listiter_next(listiterobject *it)
         return item;
     }
 
-    Py_DECREF(seq);
     it->it_seq = NULL;
+    Py_DECREF(seq);
     return NULL;
 }
 
@@ -2912,9 +2912,17 @@ static PyObject *
 listreviter_next(listreviterobject *it)
 {
     PyObject *item;
-    Py_ssize_t index = it->it_index;
-    PyListObject *seq = it->it_seq;
+    Py_ssize_t index;
+    PyListObject *seq;
+
+    assert(it != NULL);
+    seq = it->it_seq;
+    if (seq == NULL) {
+        return NULL;
+    }
+    assert(PyList_Check(seq));
 
+    index = it->it_index;
     if (index>=0 && index < PyList_GET_SIZE(seq)) {
         item = PyList_GET_ITEM(seq, index);
         it->it_index--;
@@ -2922,10 +2930,8 @@ listreviter_next(listreviterobject *it)
         return item;
     }
     it->it_index = -1;
-    if (seq != NULL) {
-        it->it_seq = NULL;
-        Py_DECREF(seq);
-    }
+    it->it_seq = NULL;
+    Py_DECREF(seq);
     return NULL;
 }
 
index 5f22455..f68d15e 100644 (file)
@@ -4611,7 +4611,7 @@ long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
     if (tmp == NULL)
         return NULL;
-    assert(PyLong_CheckExact(tmp));
+    assert(PyLong_Check(tmp));
     n = Py_SIZE(tmp);
     if (n < 0)
         n = -n;
@@ -5049,27 +5049,9 @@ long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds)
         little_endian, is_signed);
     Py_DECREF(bytes);
 
-    /* If from_bytes() was used on subclass, allocate new subclass
-     * instance, initialize it with decoded int value and return it.
-     */
-    if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) {
-        PyLongObject *newobj;
-        int i;
-        Py_ssize_t n = Py_ABS(Py_SIZE(long_obj));
-
-        newobj = (PyLongObject *)type->tp_alloc(type, n);
-        if (newobj == NULL) {
-            Py_DECREF(long_obj);
-            return NULL;
-        }
-        assert(PyLong_Check(newobj));
-        Py_SIZE(newobj) = Py_SIZE(long_obj);
-        for (i = 0; i < n; i++) {
-            newobj->ob_digit[i] =
-                ((PyLongObject *)long_obj)->ob_digit[i];
-        }
-        Py_DECREF(long_obj);
-        return (PyObject *)newobj;
+    if (type != &PyLong_Type) {
+        Py_SETREF(long_obj, PyObject_CallFunctionObjArgs((PyObject *)type,
+                                                         long_obj, NULL));
     }
 
     return long_obj;
index 7b41b0b..a4cdc20 100644 (file)
@@ -69,8 +69,7 @@ module_init_dict(PyModuleObject *mod, PyObject *md_dict,
         return -1;
     if (PyUnicode_CheckExact(name)) {
         Py_INCREF(name);
-        Py_XDECREF(mod->md_name);
-        mod->md_name = name;
+        Py_XSETREF(mod->md_name, name);
     }
 
     return 0;
index 6fc4df1..8024889 100644 (file)
@@ -1865,7 +1865,7 @@ _PyObject_DebugTypeStats(FILE *out)
 
 /* These methods are used to control infinite recursion in repr, str, print,
    etc.  Container objects that may recursively contain themselves,
-   e.g. builtin dictionaries and lists, should used Py_ReprEnter() and
+   e.g. builtin dictionaries and lists, should use Py_ReprEnter() and
    Py_ReprLeave() to avoid infinite recursion.
 
    Py_ReprEnter() returns 0 the first time it is called for a particular
index 5ad88bc..1abdd02 100644 (file)
@@ -772,19 +772,17 @@ _odict_clear_nodes(PyODictObject *od)
 {
     _ODictNode *node, *next;
 
-    if (!_odict_EMPTY(od)) {
-        node = _odict_FIRST(od);
-        while (node != NULL) {
-            next = _odictnode_NEXT(node);
-            _odictnode_DEALLOC(node);
-            node = next;
-        }
-        _odict_FIRST(od) = NULL;
-        _odict_LAST(od) = NULL;
-    }
-
     _odict_free_fast_nodes(od);
     od->od_fast_nodes = NULL;
+
+    node = _odict_FIRST(od);
+    _odict_FIRST(od) = NULL;
+    _odict_LAST(od) = NULL;
+    while (node != NULL) {
+        next = _odictnode_NEXT(node);
+        _odictnode_DEALLOC(node);
+        node = next;
+    }
 }
 
 /* There isn't any memory management of nodes past this point. */
@@ -940,29 +938,7 @@ PyDoc_STRVAR(odict_sizeof__doc__, "");
 static PyObject *
 odict_sizeof(PyODictObject *od)
 {
-    PyObject *pylong;
-    Py_ssize_t res, temp;
-
-    pylong = _PyDict_SizeOf((PyDictObject *)od);
-    if (pylong == NULL)
-        return NULL;
-    res = PyLong_AsSsize_t(pylong);
-    Py_DECREF(pylong);
-    if (res == -1 && PyErr_Occurred())
-        return NULL;
-
-    res += sizeof(PyODictObject) - sizeof(PyDictObject);
-
-    /* instance dict */
-    pylong = _PyDict_SizeOf((PyDictObject *)od->od_inst_dict);
-    if (pylong == NULL)
-        return NULL;
-    temp = PyLong_AsSsize_t(pylong);
-    Py_DECREF(pylong);
-    if (temp == -1 && PyErr_Occurred())
-        return NULL;
-    res += temp;
-
+    Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
     res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od);  /* od_fast_nodes */
     if (!_odict_EMPTY(od)) {
         res += sizeof(_ODictNode) * PyODict_SIZE(od);  /* linked-list */
@@ -1255,8 +1231,6 @@ odict_clear(register PyODictObject *od)
 {
     PyDict_Clear((PyObject *)od);
     _odict_clear_nodes(od);
-    _odict_FIRST(od) = NULL;
-    _odict_LAST(od) = NULL;
     if (_odict_resize(od) < 0)
         return NULL;
     Py_RETURN_NONE;
@@ -1578,8 +1552,13 @@ PyDoc_STRVAR(odict_doc,
 static int
 odict_traverse(PyODictObject *od, visitproc visit, void *arg)
 {
+    _ODictNode *node;
+
     Py_VISIT(od->od_inst_dict);
     Py_VISIT(od->od_weakreflist);
+    _odict_FOREACH(od, node) {
+        Py_VISIT(_odictnode_KEY(node));
+    }
     return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
 }
 
index da1d703..0e9eb20 100644 (file)
@@ -5,7 +5,7 @@
 
 /* Support objects whose length is > PY_SSIZE_T_MAX.
 
-   This could be sped up for small PyLongs if they fit in an Py_ssize_t.
+   This could be sped up for small PyLongs if they fit in a Py_ssize_t.
    This only matters on Win64.  Though we could use PY_LONG_LONG which
    would presumably help perf.
 */
@@ -1001,8 +1001,7 @@ longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
         return NULL;
     cmp = PyObject_RichCompareBool(state, zero, Py_LT);
     if (cmp > 0) {
-        Py_CLEAR(r->index);
-        r->index = zero;
+        Py_XSETREF(r->index, zero);
         Py_RETURN_NONE;
     }
     Py_DECREF(zero);
@@ -1015,9 +1014,8 @@ longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
     if (cmp > 0)
         state = r->len;
 
-    Py_CLEAR(r->index);
-    r->index = state;
-    Py_INCREF(r->index);
+    Py_INCREF(state);
+    Py_XSETREF(r->index, state);
     Py_RETURN_NONE;
 }
 
@@ -1066,8 +1064,7 @@ longrangeiter_next(longrangeiterobject *r)
     result = PyNumber_Add(r->start, product);
     Py_DECREF(product);
     if (result) {
-        Py_DECREF(r->index);
-        r->index = new_index;
+        Py_SETREF(r->index, new_index);
     }
     else {
         Py_DECREF(new_index);
index 704d7e2..4ef692d 100644 (file)
@@ -4,9 +4,6 @@
    Written and maintained by Raymond D. Hettinger <python@rcn.com>
    Derived from Lib/sets.py and Objects/dictobject.c.
 
-   Copyright (c) 2003-2015 Python Software Foundation.
-   All rights reserved.
-
    The basic lookup function used by all operations.
    This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
 
@@ -842,8 +839,8 @@ static PyObject *setiter_iternext(setiterobject *si)
     return key;
 
 fail:
-    Py_DECREF(so);
     si->si_set = NULL;
+    Py_DECREF(so);
     return NULL;
 }
 
@@ -1940,7 +1937,7 @@ set_sizeof(PySetObject *so)
 {
     Py_ssize_t res;
 
-    res = sizeof(PySetObject);
+    res = _PyObject_SIZE(Py_TYPE(so));
     if (so->table != so->smalltable)
         res = res + (so->mask + 1) * sizeof(setentry);
     return PyLong_FromSsize_t(res);
index 1049523..2f32355 100644 (file)
@@ -102,7 +102,7 @@ void PySlice_Fini(void)
     PySliceObject *obj = slice_cache;
     if (obj != NULL) {
         slice_cache = NULL;
-        PyObject_Del(obj);
+        PyObject_GC_Del(obj);
     }
 }
 
@@ -119,7 +119,7 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
         slice_cache = NULL;
         _Py_NewReference((PyObject *)obj);
     } else {
-        obj = PyObject_New(PySliceObject, &PySlice_Type);
+        obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
         if (obj == NULL)
             return NULL;
     }
@@ -135,6 +135,7 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
     obj->start = start;
     obj->stop = stop;
 
+    _PyObject_GC_TRACK(obj);
     return (PyObject *) obj;
 }
 
@@ -288,13 +289,14 @@ Create a slice object.  This is used for extended slicing (e.g. a[0:10:2]).");
 static void
 slice_dealloc(PySliceObject *r)
 {
+    _PyObject_GC_UNTRACK(r);
     Py_DECREF(r->step);
     Py_DECREF(r->start);
     Py_DECREF(r->stop);
     if (slice_cache == NULL)
         slice_cache = r;
     else
-        PyObject_Del(r);
+        PyObject_GC_Del(r);
 }
 
 static PyObject *
@@ -586,6 +588,15 @@ slice_richcompare(PyObject *v, PyObject *w, int op)
     return res;
 }
 
+static int
+slice_traverse(PySliceObject *v, visitproc visit, void *arg)
+{
+    Py_VISIT(v->start);
+    Py_VISIT(v->stop);
+    Py_VISIT(v->step);
+    return 0;
+}
+
 PyTypeObject PySlice_Type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "slice",                    /* Name of this type */
@@ -606,9 +617,9 @@ PyTypeObject PySlice_Type = {
     PyObject_GenericGetAttr,                    /* tp_getattro */
     0,                                          /* tp_setattro */
     0,                                          /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
     slice_doc,                                  /* tp_doc */
-    0,                                          /* tp_traverse */
+    (traverseproc)slice_traverse,               /* tp_traverse */
     0,                                          /* tp_clear */
     slice_richcompare,                          /* tp_richcompare */
     0,                                          /* tp_weaklistoffset */
index aec221a..be09b5f 100644 (file)
@@ -1226,7 +1226,7 @@ static PyTypeObject PyFieldNameIter_Type = {
     0};
 
 /* unicode_formatter_field_name_split is used to implement
-   string.Formatter.vformat.  it takes an PEP 3101 "field name", and
+   string.Formatter.vformat.  it takes a PEP 3101 "field name", and
    returns a tuple of (first, rest): "first", the part before the
    first '.' or '['; and "rest", an iterator for the rest of the field
    name.  it's a wrapper around stringlib/string_format.h's
index 7efa1a6..7920fec 100644 (file)
@@ -964,8 +964,8 @@ tupleiter_next(tupleiterobject *it)
         return item;
     }
 
-    Py_DECREF(seq);
     it->it_seq = NULL;
+    Py_DECREF(seq);
     return NULL;
 }
 
index f87d58f..317334f 100644 (file)
@@ -315,9 +315,8 @@ assign_version_tag(PyTypeObject *type)
            are borrowed reference */
         for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
             method_cache[i].value = NULL;
-            Py_XDECREF(method_cache[i].name);
-            method_cache[i].name = Py_None;
             Py_INCREF(Py_None);
+            Py_XSETREF(method_cache[i].name, Py_None);
         }
         /* mark all version tags as invalid */
         PyType_Modified(&PyBaseObject_Type);
@@ -402,9 +401,8 @@ type_qualname(PyTypeObject *type, void *context)
 static int
 type_set_name(PyTypeObject *type, PyObject *value, void *context)
 {
-    PyHeapTypeObject* et;
-    char *tp_name;
-    PyObject *tmp;
+    const char *tp_name;
+    Py_ssize_t name_size;
 
     if (!check_set_special_type_attr(type, value, "__name__"))
         return -1;
@@ -415,33 +413,18 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context)
         return -1;
     }
 
-    /* Check absence of null characters */
-    tmp = PyUnicode_FromStringAndSize("\0", 1);
-    if (tmp == NULL)
+    tp_name = PyUnicode_AsUTF8AndSize(value, &name_size);
+    if (tp_name == NULL)
         return -1;
-    if (PyUnicode_Contains(value, tmp) != 0) {
-        Py_DECREF(tmp);
-        PyErr_Format(PyExc_ValueError,
-                     "__name__ must not contain null bytes");
+    if (strlen(tp_name) != (size_t)name_size) {
+        PyErr_SetString(PyExc_ValueError,
+                        "type name must not contain null characters");
         return -1;
     }
-    Py_DECREF(tmp);
-
-    tp_name = _PyUnicode_AsString(value);
-    if (tp_name == NULL)
-        return -1;
-
-    et = (PyHeapTypeObject*)type;
-
-    Py_INCREF(value);
-
-    /* Wait until et is a sane state before Py_DECREF'ing the old et->ht_name
-       value.  (Bug #16447.)  */
-    tmp = et->ht_name;
-    et->ht_name = value;
 
     type->tp_name = tp_name;
-    Py_DECREF(tmp);
+    Py_INCREF(value);
+    Py_SETREF(((PyHeapTypeObject*)type)->ht_name, value);
 
     return 0;
 }
@@ -462,8 +445,7 @@ type_set_qualname(PyTypeObject *type, PyObject *value, void *context)
 
     et = (PyHeapTypeObject*)type;
     Py_INCREF(value);
-    Py_DECREF(et->ht_qualname);
-    et->ht_qualname = value;
+    Py_SETREF(et->ht_qualname, value);
     return 0;
 }
 
@@ -2287,8 +2269,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
     PyTypeObject *type = NULL, *base, *tmptype, *winner;
     PyHeapTypeObject *et;
     PyMemberDef *mp;
-    Py_ssize_t i, nbases, nslots, slotoffset, add_dict, add_weak;
-    int j, may_add_dict, may_add_weak;
+    Py_ssize_t i, nbases, nslots, slotoffset, name_size;
+    int j, may_add_dict, may_add_weak, add_dict, add_weak;
     _Py_IDENTIFIER(__qualname__);
     _Py_IDENTIFIER(__slots__);
 
@@ -2511,9 +2493,14 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
     type->tp_as_sequence = &et->as_sequence;
     type->tp_as_mapping = &et->as_mapping;
     type->tp_as_buffer = &et->as_buffer;
-    type->tp_name = _PyUnicode_AsString(name);
+    type->tp_name = PyUnicode_AsUTF8AndSize(name, &name_size);
     if (!type->tp_name)
         goto error;
+    if (strlen(type->tp_name) != (size_t)name_size) {
+        PyErr_SetString(PyExc_ValueError,
+                        "type name must not contain null characters");
+        goto error;
+    }
 
     /* Set tp_base and tp_bases */
     type->tp_bases = bases;
@@ -2588,8 +2575,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
         tmp = PyStaticMethod_New(tmp);
         if (tmp == NULL)
             goto error;
-        if (_PyDict_SetItemId(dict, &PyId___new__, tmp) < 0)
+        if (_PyDict_SetItemId(dict, &PyId___new__, tmp) < 0) {
+            Py_DECREF(tmp);
             goto error;
+        }
         Py_DECREF(tmp);
     }
 
@@ -2910,8 +2899,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
         else
             method_cache_misses++;
 #endif
-        Py_DECREF(method_cache[h].name);
-        method_cache[h].name = name;
+        Py_SETREF(method_cache[h].name, name);
     }
     return res;
 }
@@ -3834,7 +3822,7 @@ _PyType_GetSlotNames(PyTypeObject *cls)
 }
 
 Py_LOCAL(PyObject *)
-_PyObject_GetState(PyObject *obj)
+_PyObject_GetState(PyObject *obj, int required)
 {
     PyObject *state;
     PyObject *getstate;
@@ -3849,6 +3837,13 @@ _PyObject_GetState(PyObject *obj)
         }
         PyErr_Clear();
 
+        if (required && obj->ob_type->tp_itemsize) {
+            PyErr_Format(PyExc_TypeError,
+                         "can't pickle %.200s objects",
+                         Py_TYPE(obj)->tp_name);
+            return NULL;
+        }
+
         {
             PyObject **dict;
             dict = _PyObject_GetDictPtr(obj);
@@ -3889,8 +3884,10 @@ _PyObject_GetState(PyObject *obj)
                 PyObject *name, *value;
 
                 name = PyList_GET_ITEM(slotnames, i);
+                Py_INCREF(name);
                 value = PyObject_GetAttr(obj, name);
                 if (value == NULL) {
+                    Py_DECREF(name);
                     if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
                         goto error;
                     }
@@ -3899,13 +3896,14 @@ _PyObject_GetState(PyObject *obj)
                 }
                 else {
                     int err = PyDict_SetItem(slots, name, value);
+                    Py_DECREF(name);
                     Py_DECREF(value);
                     if (err) {
                         goto error;
                     }
                 }
 
-                /* The list is stored on the class so it may mutates while we
+                /* The list is stored on the class so it may mutate while we
                    iterate over it */
                 if (slotnames_size != Py_SIZE(slotnames)) {
                     PyErr_Format(PyExc_RuntimeError,
@@ -4039,7 +4037,7 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs)
     }
 
     /* The object does not have __getnewargs_ex__ and __getnewargs__. This may
-       means __new__ does not takes any arguments on this object, or that the
+       mean __new__ does not takes any arguments on this object, or that the
        object does not implement the reduce protocol for pickling or
        copying. */
     *args = NULL;
@@ -4099,29 +4097,24 @@ reduce_newobj(PyObject *obj, int proto)
     PyObject *copyreg;
     PyObject *newobj, *newargs, *state, *listitems, *dictitems;
     PyObject *result;
+    int hasargs;
 
     if (Py_TYPE(obj)->tp_new == NULL) {
         PyErr_Format(PyExc_TypeError,
-                     "can't pickle %s objects",
+                     "can't pickle %.200s objects",
                      Py_TYPE(obj)->tp_name);
         return NULL;
     }
     if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0)
         return NULL;
 
-    if (args == NULL) {
-        args = PyTuple_New(0);
-        if (args == NULL) {
-            Py_XDECREF(kwargs);
-            return NULL;
-        }
-    }
     copyreg = import_copyreg();
     if (copyreg == NULL) {
-        Py_DECREF(args);
+        Py_XDECREF(args);
         Py_XDECREF(kwargs);
         return NULL;
     }
+    hasargs = (args != NULL);
     if (kwargs == NULL || PyDict_Size(kwargs) == 0) {
         _Py_IDENTIFIER(__newobj__);
         PyObject *cls;
@@ -4131,13 +4124,13 @@ reduce_newobj(PyObject *obj, int proto)
         newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj__);
         Py_DECREF(copyreg);
         if (newobj == NULL) {
-            Py_DECREF(args);
+            Py_XDECREF(args);
             return NULL;
         }
-        n = PyTuple_GET_SIZE(args);
+        n = args ? PyTuple_GET_SIZE(args) : 0;
         newargs = PyTuple_New(n+1);
         if (newargs == NULL) {
-            Py_DECREF(args);
+            Py_XDECREF(args);
             Py_DECREF(newobj);
             return NULL;
         }
@@ -4149,7 +4142,7 @@ reduce_newobj(PyObject *obj, int proto)
             Py_INCREF(v);
             PyTuple_SET_ITEM(newargs, i+1, v);
         }
-        Py_DECREF(args);
+        Py_XDECREF(args);
     }
     else if (proto >= 4) {
         _Py_IDENTIFIER(__newobj_ex__);
@@ -4180,7 +4173,8 @@ reduce_newobj(PyObject *obj, int proto)
         return NULL;
     }
 
-    state = _PyObject_GetState(obj);
+    state = _PyObject_GetState(obj,
+                !hasargs && !PyList_Check(obj) && !PyDict_Check(obj));
     if (state == NULL) {
         Py_DECREF(newobj);
         Py_DECREF(newargs);
@@ -7344,9 +7338,9 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
         Py_INCREF(obj);
     }
     Py_INCREF(type);
-    su->type = type;
-    su->obj = obj;
-    su->obj_type = obj_type;
+    Py_XSETREF(su->type, type);
+    Py_XSETREF(su->obj, obj);
+    Py_XSETREF(su->obj_type, obj_type);
     return 0;
 }
 
index 0b78301..f11a082 100644 (file)
@@ -675,7 +675,7 @@ Py_LOCAL_INLINE(Py_ssize_t) findchar(const void *s, int kind,
 }
 
 #ifdef Py_DEBUG
-/* Fill the data of an Unicode string with invalid characters to detect bugs
+/* Fill the data of a Unicode string with invalid characters to detect bugs
    earlier.
 
    _PyUnicode_CheckConsistency(str, 1) detects invalid characters, at least for
@@ -748,6 +748,8 @@ resize_compact(PyObject *unicode, Py_ssize_t length)
     else if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) {
         PyObject_DEL(_PyUnicode_WSTR(unicode));
         _PyUnicode_WSTR(unicode) = NULL;
+        if (!PyUnicode_IS_ASCII(unicode))
+            _PyUnicode_WSTR_LENGTH(unicode) = 0;
     }
 #ifdef Py_DEBUG
     unicode_fill_invalid(unicode, old_length);
@@ -1665,8 +1667,7 @@ unicode_resize(PyObject **p_unicode, Py_ssize_t length)
         _Py_INCREF_UNICODE_EMPTY();
         if (!unicode_empty)
             return -1;
-        Py_DECREF(*p_unicode);
-        *p_unicode = unicode_empty;
+        Py_SETREF(*p_unicode, unicode_empty);
         return 0;
     }
 
@@ -1674,8 +1675,7 @@ unicode_resize(PyObject **p_unicode, Py_ssize_t length)
         PyObject *copy = resize_copy(unicode, length);
         if (copy == NULL)
             return -1;
-        Py_DECREF(*p_unicode);
-        *p_unicode = copy;
+        Py_SETREF(*p_unicode, copy);
         return 0;
     }
 
@@ -8574,17 +8574,14 @@ unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch,
    translated into writer, raise an exception and return -1 on error. */
 static int
 unicode_fast_translate(PyObject *input, PyObject *mapping,
-                       _PyUnicodeWriter *writer, int ignore)
+                       _PyUnicodeWriter *writer, int ignore,
+                       Py_ssize_t *input_pos)
 {
     Py_UCS1 ascii_table[128], ch, ch2;
     Py_ssize_t len;
     Py_UCS1 *in, *end, *out;
     int res = 0;
 
-    if (PyUnicode_READY(input) == -1)
-        return -1;
-    if (!PyUnicode_IS_ASCII(input))
-        return 0;
     len = PyUnicode_GET_LENGTH(input);
 
     memset(ascii_table, 0xff, 128);
@@ -8621,6 +8618,7 @@ unicode_fast_translate(PyObject *input, PyObject *mapping,
 
 exit:
     writer->pos = out - PyUnicode_1BYTE_DATA(writer->buffer);
+    *input_pos = in - PyUnicode_1BYTE_DATA(input);
     return res;
 }
 
@@ -8666,15 +8664,21 @@ _PyUnicode_TranslateCharmap(PyObject *input,
 
     ignore = (errors != NULL && strcmp(errors, "ignore") == 0);
 
-    res = unicode_fast_translate(input, mapping, &writer, ignore);
-    if (res < 0) {
-        _PyUnicodeWriter_Dealloc(&writer);
+    if (PyUnicode_READY(input) == -1)
         return NULL;
+    if (PyUnicode_IS_ASCII(input)) {
+        res = unicode_fast_translate(input, mapping, &writer, ignore, &i);
+        if (res < 0) {
+            _PyUnicodeWriter_Dealloc(&writer);
+            return NULL;
+        }
+        if (res == 1)
+            return _PyUnicodeWriter_Finish(&writer);
+    }
+    else {
+        i = 0;
     }
-    if (res == 1)
-        return _PyUnicodeWriter_Finish(&writer);
 
-    i = writer.pos;
     while (i<size) {
         /* try to encode it */
         int translate;
@@ -9319,7 +9323,7 @@ tailmatch(PyObject *self,
                             PyUnicode_GET_LENGTH(substring) *
                                 PyUnicode_KIND(substring));
         }
-        /* otherwise we have to compare each character by first accesing it */
+        /* otherwise we have to compare each character by first accessing it */
         else {
             /* We do not need to compare 0 and len(substring)-1 because
                the if statement above ensured already that they are equal
@@ -13322,8 +13326,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
             return -1;
         _PyUnicode_FastCopyCharacters(newbuffer, 0,
                                       writer->buffer, 0, writer->pos);
-        Py_DECREF(writer->buffer);
-        writer->buffer = newbuffer;
+        Py_SETREF(writer->buffer, newbuffer);
     }
     _PyUnicodeWriter_Update(writer);
     return 0;
@@ -14194,8 +14197,8 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx,
         if (key == NULL)
             return -1;
         if (ctx->args_owned) {
-            Py_DECREF(ctx->args);
             ctx->args_owned = 0;
+            Py_DECREF(ctx->args);
         }
         ctx->args = PyObject_GetItem(ctx->dict, key);
         Py_DECREF(key);
@@ -15009,8 +15012,7 @@ PyUnicode_InternInPlace(PyObject **p)
 
     if (t) {
         Py_INCREF(t);
-        Py_DECREF(*p);
-        *p = t;
+        Py_SETREF(*p, t);
         return;
     }
 
@@ -15147,8 +15149,8 @@ unicodeiter_next(unicodeiterobject *it)
         return item;
     }
 
-    Py_DECREF(seq);
     it->it_seq = NULL;
+    Py_DECREF(seq);
     return NULL;
 }
 
index d4d52e6..7e6f364 100644 (file)
@@ -268,7 +268,6 @@ static int
 parse_weakref_init_args(char *funcname, PyObject *args, PyObject *kwargs,
                         PyObject **obp, PyObject **callbackp)
 {
-    /* XXX Should check that kwargs == NULL or is empty. */
     return PyArg_UnpackTuple(args, funcname, 1, 2, obp, callbackp);
 }
 
@@ -331,6 +330,9 @@ weakref___init__(PyObject *self, PyObject *args, PyObject *kwargs)
 {
     PyObject *tmp;
 
+    if (!_PyArg_NoKeywords("ref()", kwargs))
+        return -1;
+
     if (parse_weakref_init_args("__init__", args, kwargs, &tmp, &tmp))
         return 0;
     else
index 2ab474e..4dc5009 100644 (file)
@@ -37,7 +37,6 @@
   <PropertyGroup Label="Globals">
     <ProjectGuid>{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}</ProjectGuid>
     <RootNamespace>wininst</RootNamespace>
-    <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
     <SupportPGO>false</SupportPGO>
   </PropertyGroup>
   <Import Project="..\..\PCBuild\python.props" />
@@ -70,6 +69,8 @@
       <Optimization>MinSpace</Optimization>
       <AdditionalIncludeDirectories>$(PySourcePath)Modules\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary Condition="'$(Configuration)'=='Debug'">MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(Configuration)'=='Release'">MultiThreaded</RuntimeLibrary>
     </ClCompile>
     <ResourceCompile>
       <AdditionalIncludeDirectories>$(PySourcePath)PC\bdist_wininst;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
index f39b381..cb037ff 100644 (file)
@@ -153,6 +153,13 @@ char *failure_reason = NULL;
 HANDLE hBitmap;
 char *bitmap_bytes;
 
+static const char *REGISTRY_SUFFIX_6432 =
+#ifdef MS_WIN64
+                                          "";
+#else
+                                          "-32";
+#endif
+
 
 #define WM_NUMFILES WM_USER+1
 /* wParam: 0, lParam: total number of files */
@@ -657,8 +664,8 @@ static HINSTANCE LoadPythonDll(char *fname)
     if (h)
         return h;
     wsprintf(subkey_name,
-             "SOFTWARE\\Python\\PythonCore\\%d.%d\\InstallPath",
-             py_major, py_minor);
+             "SOFTWARE\\Python\\PythonCore\\%d.%d%s\\InstallPath",
+             py_major, py_minor, REGISTRY_SUFFIX_6432);
     if (ERROR_SUCCESS != RegQueryValue(HKEY_CURRENT_USER, subkey_name,
                                        fullpath, &size) &&
         ERROR_SUCCESS != RegQueryValue(HKEY_LOCAL_MACHINE, subkey_name,
@@ -666,7 +673,9 @@ static HINSTANCE LoadPythonDll(char *fname)
         return NULL;
     strcat(fullpath, "\\");
     strcat(fullpath, fname);
-    return LoadLibrary(fullpath);
+    // We use LOAD_WITH_ALTERED_SEARCH_PATH to ensure any dependent DLLs
+    // next to the Python DLL (eg, the CRT DLL) are also loaded.
+    return LoadLibraryEx(fullpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
 }
 
 static int prepare_script_environment(HINSTANCE hPython)
@@ -2250,6 +2259,8 @@ int DoInstall(void)
     GetPrivateProfileString("Setup", "user_access_control", "",
                              user_access_control, sizeof(user_access_control), ini_file);
 
+    strcat(target_version, REGISTRY_SUFFIX_6432);
+
     // See if we need to do the Vista UAC magic.
     if (strcmp(user_access_control, "force")==0) {
         if (!MyIsUserAnAdmin()) {
index 22b332f..338e33d 100644 (file)
@@ -120,7 +120,7 @@ PyDoc_STRVAR(winreg_ConnectRegistry__doc__,
 "ConnectRegistry($module, computer_name, key, /)\n"
 "--\n"
 "\n"
-"Establishes a connection to the registry on on another computer.\n"
+"Establishes a connection to the registry on another computer.\n"
 "\n"
 "  computer_name\n"
 "    The name of the remote computer, of the form r\"\\\\computername\".  If\n"
@@ -913,7 +913,7 @@ PyDoc_STRVAR(winreg_SetValueEx__doc__,
 "                     references to environment variables (for example,\n"
 "                     %PATH%).\n"
 "    REG_LINK -- A Unicode symbolic link.\n"
-"    REG_MULTI_SZ -- An sequence of null-terminated strings, terminated\n"
+"    REG_MULTI_SZ -- A sequence of null-terminated strings, terminated\n"
 "                    by two null characters.  Note that Python handles\n"
 "                    this termination automatically.\n"
 "    REG_NONE -- No defined value type.\n"
@@ -1056,4 +1056,4 @@ winreg_QueryReflectionKey(PyModuleDef *module, PyObject *arg)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=71f5bc30b646807b input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5e346dccc296f9f1 input=a9049054013a1b77]*/
index 25b328b..c7ddf1e 100644 (file)
@@ -321,7 +321,6 @@ getpythonregpath(HKEY keyBase, int skipcore)
     dataBuf = PyMem_RawMalloc((dataSize+1) * sizeof(WCHAR));
     if (dataBuf) {
         WCHAR *szCur = dataBuf;
-        DWORD reqdSize = dataSize;
         /* Copy our collected strings */
         for (index=0;index<numKeys;index++) {
             if (index > 0) {
@@ -349,6 +348,10 @@ getpythonregpath(HKEY keyBase, int skipcore)
             */
             rc = RegQueryValueExW(newKey, NULL, 0, NULL,
                                   (LPBYTE)szCur, &dataSize);
+            if (rc != ERROR_SUCCESS) {
+                PyMem_RawFree(dataBuf);
+                goto done;
+            }
         }
         /* And set the result - caller must free */
         retval = dataBuf;
diff --git a/PC/icons/baselogo.svg b/PC/icons/baselogo.svg
deleted file mode 100644 (file)
index fff6b17..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg version="1.0" width="744.09448" height="1052.3622" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-  <defs>
-    <linearGradient id="pyYellowGradient">
-      <stop  offset="0" style="stop-color:#ffc130;stop-opacity:1"/>
-      <stop  offset="1" style="stop-color:#ffea5b;stop-opacity:1"/>
-    </linearGradient>
-    <linearGradient id="pyBlueGradient">
-      <stop style="stop-color:#426684;stop-opacity:1" offset="0"/>
-      <stop style="stop-color:#357cb5;stop-opacity:1" offset="1"/>
-    </linearGradient>
-    <linearGradient id="pyYellow" xlink:href="#pyYellowGradient" x1="1108.9739" y1="3365.6448" x2="949.80927" y2="3144.1941" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.317715,0,0,0.317715,-172.579,-583.027)"/>
-    <linearGradient id="pyBlue" xlink:href="#pyBlueGradient" x1="607.27795" y1="1841.619" x2="472.67371" y2="1660.6002" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"/>
-  </defs>
-
-  <g
-     id="layer1">
-    <path
-       d="M 88.126188,110.89374 C 88.126188,99.932569 97.021954,91.036422 107.98312,91.023301 L 147.69781,91.023301 C 158.65898,91.036435 167.55475,99.932569 167.55475,110.88023 L 167.55475,148.11929 C 167.55475,159.08046 158.65898,167.97661 147.69781,167.97661 L 107.98312,167.97661 C 94.281853,167.97661 83.161955,179.0965 83.161955,192.79777 L 83.161955,210.17955 L 68.268873,210.16643 C 57.307706,210.17955 48.411559,201.27028 48.411559,190.30911 L 48.411559,150.59472 C 48.411559,139.64668 57.307706,130.73741 68.268873,130.73741 L 127.84044,130.75054 L 127.84044,125.78631 L 88.126061,125.78631 L 88.126061,110.89361 L 88.126188,110.89374 z M 105.49443,100.96489 C 109.61173,100.96489 112.94774,104.3009 112.94774,108.40504 C 112.94774,112.52196 109.61173,115.85797 105.49443,115.85797 C 101.39066,115.85797 98.041501,112.52196 98.041501,108.40504 C 98.041501,104.3009 101.39063,100.96489 105.49443,100.96489 z "
-       style="fill:#426684;fill-rule:evenodd"
-       id="path6" />
-    <g
-       transform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"
-       style="fill-rule:evenodd"
-       id="_19410248">
-   <g
-   id="g9">
-    <path
-   d="M 1102.42,902.293 C 1160.3365,901.33394 1186.6279,955.8347 1187.0861,1017.668 C 1187.0861,1072.1676 1159.8369,1123.293 1101.4196,1125.21 C 1077.5861,1125.21 1057.1283,1117.9179 1037.17,1105.7513 L 1037.17,1231.8353 L 1002.1279,1219.168 L 1002.6287,939.293 C 1002.1279,939.293 1029.8779,902.7934 1101.9204,901.793 L 1102.42,902.29379 L 1102.42,902.293 z M 1093.6279,1099.917 C 1140.3783,1097.0009 1146.2118,1051.2509 1146.2118,1015.2095 C 1146.2118,980.1674 1140.3783,927.5835 1096.087,925.6678 C 1065.9205,923.70953 1041.5449,937.8343 1036.7118,942.7087 L 1036.7118,1081.4177 C 1048.3787,1088.7098 1071.7527,1101.376 1093.6279,1099.9173 L 1093.6279,1099.917 z "
-   style="fill:#6a6a6a"
-   id="_19410568" />
-
-    <path
-   d="M 1261,1051.25 L 1261,901.791 L 1224.9587,913.9587 L 1224.9587,1061.9577 C 1224.9587,1101.3746 1261.4996,1124.249 1293.6244,1124.249 C 1335.4579,1124.249 1359.3327,1112.5833 1370.0405,1107.7077 C 1370.4988,1113.0416 1370.0405,1111.5829 1370.0405,1116.9581 C 1370.0405,1132.5416 1369.5409,1159.2912 1362.2488,1172.9164 C 1347.6244,1200.6664 1308.7071,1204.5416 1281.4579,1208.4581 L 1287.2902,1230.8329 C 1323.2902,1229.875 1373.9158,1216.2498 1391.9162,1182.1668 C 1402.1658,1162.7081 1403.6245,1125.2081 1403.6245,1100.4168 L 1403.6245,907.16579 L 1368.0828,907.16579 L 1368.0828,1080.9168 C 1356.4159,1088.7085 1335.0001,1099.4164 1315.9997,1099.916 C 1284.3745,1100.4168 1261.0005,1083.3747 1261.0005,1050.7491 L 1261.0005,1051.2499 L 1261,1051.25 z "
-   style="fill:#6a6a6a"
-   id="_19412384" />
-
-    <path
-   d="M 1463.29,930.043 L 1463.29,1069.751 C 1463.29,1106.2506 1491.5396,1127.6675 1538.7483,1123.2927 L 1538.7483,1104.7931 C 1513.9144,1103.7927 1498.8318,1097.0014 1498.8318,1068.7506 L 1498.8318,930.0436 L 1538.7483,930.0436 L 1538.7483,907.168 L 1498.8318,907.168 L 1498.8318,835.1267 L 1463.2901,847.7928 L 1463.2901,907.168 L 1438.957,907.168 L 1438.957,930.0436 L 1463.2901,930.0436 L 1463.29,930.043 z "
-   style="fill:#6a6a6a"
-   id="_19413104" />
-
-    <path
-   d="M 1754.5,1120.33 L 1754.5,971.914 C 1754.5,934.9136 1729.1665,905.7061 1691.2083,905.7061 C 1662.5004,905.7061 1638.1674,914.95531 1616.7504,930.4974 L 1616.7504,781.0804 L 1581.2087,792.2879 L 1581.2087,1120.3299 L 1616.7504,1120.3299 L 1616.7504,955.8309 C 1634.7504,943.1636 1655.2083,930.0392 1677.5831,930.0392 C 1706.2922,930.0392 1718.4587,958.2475 1718.4587,983.0801 L 1718.4587,1120.3301 L 1754.5,1120.3301 L 1754.5,1120.33 z "
-   style="fill:#6a6a6a"
-   id="_19415136" />
-
-    <path
-   d="M 1786.29,1009.88 C 1786.29,1068.7544 1817.4569,1124.254 1883.1652,1124.755 C 1949.3731,1124.2542 1981.4991,1068.7542 1981.4991,1009.88 C 1980.9983,952.4217 1944.9983,902.297 1883.6648,901.796 C 1822.8321,902.29679 1786.29,952.4216 1786.29,1009.88 L 1786.29,1009.88 z M 1824.7491,1009.88 C 1824.7491,971.4221 1834.4979,929.0879 1883.1652,926.1304 C 1928.9152,928.58827 1942.5404,971.4221 1942.5404,1009.88 C 1942.5404,1050.7544 1933.7896,1101.38 1884.1231,1102.8387 C 1838.3731,1102.3379 1825.2487,1050.7544 1825.2487,1009.88 L 1824.7491,1009.88 L 1824.7491,1009.88 z "
-   style="fill:#6a6a6a"
-   id="_19416104" />
-
-    <path
-   d="M 2184.04,1120.33 L 2184.04,957.288 C 2184.04,928.5801 2161.1644,910.0805 2135.3727,904.2471 C 2110.0392,898.41364 2086.207,903.24671 2068.7066,908.1223 C 2046.2893,913.95576 2030.2475,924.2054 2012.2062,937.3298 L 2012.2062,1120.3298 L 2047.7479,1120.3298 L 2047.7479,941.7058 C 2058.9566,933.91407 2076.9566,925.6641 2095.957,925.1633 C 2127.0814,924.66369 2148.4983,942.705 2148.4983,975.2881 L 2148.4983,1120.3301 L 2184.04,1120.3301 L 2184.04,1120.33 z "
-   style="fill:#6a6a6a"
-   id="_19416592" />
-
-   </g>
-
-  </g>
-    <path
-       d="M 167.55462,230.0232 C 167.55462,240.98437 158.65885,249.88051 147.69769,249.89364 L 107.98299,249.89364 C 97.021827,249.88051 88.126061,240.98437 88.126061,230.0367 L 88.126061,192.79765 C 88.126061,181.83648 97.021827,172.94071 107.98299,172.94071 L 147.69769,172.94071 C 161.39896,172.94071 172.51923,161.82043 172.51923,148.11916 L 172.51923,130.73739 L 187.41193,130.75052 C 198.3731,130.73739 207.26925,139.64667 207.26925,150.60784 L 207.26925,190.3222 C 207.26925,201.27025 198.3731,210.17952 187.41193,210.17952 L 127.84037,210.16639 L 127.84037,215.13063 L 167.55475,215.13063 L 167.55475,230.02333 L 167.55462,230.0232 z M 150.17323,239.95205 C 146.06946,239.95205 142.73345,236.61604 142.73345,232.51227 C 142.73345,228.39497 146.06946,225.05897 150.17323,225.05897 C 154.29015,225.05897 157.62615,228.39497 157.62615,232.51227 C 157.62615,236.61604 154.29015,239.95205 150.17323,239.95205 z "
-       style="fill:#d3aa3f;fill-rule:evenodd"
-       id="path17" />
-    <g
-       transform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"
-       style="fill-rule:evenodd"
-       id="g1699">
-      <polygon
-         points="335.222,626.069 334.291,620.493 334.291,615.508 338.458,615.508 338.458,620.493 337.486,626.069 335.222,626.069 "
-         style="fill:#000000;fill-rule:nonzero"
-         id="_19419944" />
-      <path
-         d="M 341.798,634.527 C 341.798,630.52779 342.90942,627.56204 345.13816,625.6392 C 346.99249,624.04117 349.25666,623.23566 351.9295,623.23566 C 354.90233,623.23566 357.33186,624.20889 359.21454,626.16007 C 361.10312,628.10416 362.04092,630.79117 362.04092,634.22227 C 362.04092,637.00613 361.62399,639.19471 360.79013,640.78447 C 359.95745,642.38132 358.7421,643.61793 357.15233,644.49904 C 355.5543,645.38132 353.81808,645.81951 351.9295,645.81951 C 348.90942,645.81951 346.46454,644.85337 344.59604,642.90927 C 342.72872,640.97226 341.79801,638.18014 341.79801,634.52699 L 341.798,634.527 z M 345.56217,634.527 C 345.56217,637.29787 346.16571,639.36834 347.37398,640.74314 C 348.58225,642.12503 350.10351,642.81243 351.92949,642.81243 C 353.74957,642.81243 355.26256,642.11794 356.47083,640.73605 C 357.67319,639.35416 358.27674,637.24235 358.27674,634.41007 C 358.27674,631.73605 357.6732,629.7081 356.45784,628.3333 C 355.24249,626.9585 353.7354,626.2711 351.92949,626.2711 C 350.10351,626.2711 348.58225,626.9585 347.37398,628.32622 C 346.16571,629.69394 345.56217,631.76323 345.56217,634.52701 L 345.56217,634.527 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path21" />
-      <path
-         d="M 366.298,645.333 L 366.298,623.7295 L 369.58973,623.7295 L 369.58973,626.99997 C 370.42949,625.4728 371.20784,624.45824 371.92241,623.9728 C 372.63107,623.48619 373.41532,623.23579 374.27044,623.23579 C 375.50587,623.23579 376.75666,623.63264 378.03343,624.41689 L 376.76965,627.81965 C 375.88146,627.28461 374.985,627.02123 374.08973,627.02123 C 373.28422,627.02123 372.56847,627.26453 371.92949,627.74288 C 371.29051,628.2295 370.83933,628.89564 370.56886,629.74957 C 370.15902,631.04878 369.95823,632.47201 369.95823,634.02044 L 369.95823,645.33304 L 366.29799,645.33304 L 366.298,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path23" />
-      <path
-         d="M 380.228,619.722 L 380.228,615.50783 L 383.89414,615.50783 L 383.89414,619.722 L 380.228,619.722 z M 380.228,645.333 L 380.228,623.7295 L 383.89414,623.7295 L 383.89414,645.333 L 380.228,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path25" />
-      <path
-         d="M 388.796,647.125 L 392.3582,647.65295 C 392.50466,648.75019 392.92041,649.54862 393.59481,650.05531 C 394.50426,650.72854 395.74678,651.0687 397.31646,651.0687 C 399.01843,651.0687 400.32355,650.72855 401.24717,650.05531 C 402.17079,649.375 402.78851,648.42303 403.11449,647.20767 C 403.30937,646.45767 403.39323,644.89625 403.37906,642.50688 C 401.78221,644.38838 399.78851,645.33326 397.40032,645.33326 C 394.42749,645.33326 392.12906,644.26436 390.50386,642.1183 C 388.87984,639.97932 388.06016,637.40334 388.06016,634.41043 C 388.06016,632.34704 388.43457,630.44429 389.17748,628.70216 C 389.92748,626.95885 391.01173,625.61122 392.42787,624.66043 C 393.84401,623.71555 395.51055,623.23602 397.42039,623.23602 C 399.96921,623.23602 402.07393,624.27067 403.7263,626.33405 L 403.7263,623.72972 L 407.1078,623.72972 L 407.1078,642.40292 C 407.1078,645.76434 406.76055,648.15253 406.08024,649.55568 C 405.39283,650.95765 404.30977,652.06907 402.82394,652.88166 C 401.33693,653.69426 399.51095,654.1041 397.33772,654.1041 C 394.76055,654.1041 392.67827,653.52064 391.09441,652.36079 C 389.50465,651.20095 388.74047,649.45764 388.79598,647.12496 L 388.796,647.125 z M 391.82317,634.1459 C 391.82317,636.97936 392.38656,639.04866 393.51805,640.34787 C 394.64364,641.65299 396.0527,642.29905 397.74758,642.29905 C 399.42711,642.29905 400.83734,641.65299 401.97593,640.36086 C 403.11451,639.06283 403.68499,637.03488 403.68499,634.26401 C 403.68499,631.61834 403.10153,629.62582 401.92751,628.28527 C 400.75349,626.94472 399.33735,626.27149 397.68499,626.27149 C 396.05979,626.27149 394.6779,626.93054 393.53223,628.25692 C 392.39365,629.57621 391.82317,631.54157 391.82317,634.1459 L 391.82317,634.1459 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path27" />
-      <path
-         d="M 412.657,619.722 L 412.657,615.50783 L 416.32314,615.50783 L 416.32314,619.722 L 412.657,619.722 z M 412.657,645.333 L 412.657,623.7295 L 416.32314,623.7295 L 416.32314,645.333 L 412.657,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path29" />
-      <path
-         d="M 421.899,645.333 L 421.899,623.7295 L 425.19073,623.7295 L 425.19073,626.79919 C 426.78167,624.42399 429.07301,623.2358 432.06593,623.2358 C 433.37105,623.2358 434.56514,623.47202 435.65648,623.93737 C 436.75372,624.40982 437.56514,625.02045 438.10727,625.78462 C 438.65648,626.5417 439.03089,627.44407 439.25294,628.4858 C 439.38522,629.16729 439.45491,630.3543 439.45491,632.04919 L 439.45491,645.33309 L 435.78759,645.33309 L 435.78759,632.18739 C 435.78759,630.70156 435.6494,629.58306 435.36475,628.84015 C 435.08011,628.10432 434.57223,627.51377 433.85058,627.07676 C 433.12184,626.63266 432.27381,626.40943 431.29467,626.40943 C 429.73207,626.40943 428.3927,626.91022 427.25294,627.89644 C 426.12144,628.88857 425.55924,630.76416 425.55924,633.53502 L 425.55924,645.33302 L 421.899,645.33302 L 421.899,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path31" />
-      <path
-         d="M 459.17,642.666 C 457.80819,643.81876 456.50307,644.63135 455.25346,645.11088 C 453.99559,645.58332 452.64913,645.81954 451.21173,645.81954 C 448.83653,645.81954 447.01764,645.24316 445.73968,644.08332 C 444.46881,642.92348 443.82984,641.43765 443.82984,639.63883 C 443.82984,638.57584 444.06606,637.61088 444.55149,636.73568 C 445.03102,635.86048 445.66291,635.16009 446.44125,634.63214 C 447.22551,634.10419 448.1007,633.70143 449.07983,633.43096 C 449.7944,633.24317 450.87865,633.05537 452.32904,632.88175 C 455.2877,632.52742 457.46802,632.11049 458.86408,631.61797 C 458.87826,631.11836 458.88534,630.79828 458.88534,630.666 C 458.88534,629.17309 458.5381,628.11836 457.84361,627.51364 C 456.9129,626.68096 455.51684,626.27112 453.67668,626.27112 C 451.95463,626.27112 450.68377,626.56994 449.85699,627.17348 C 449.03731,627.77821 448.43376,628.8471 448.03809,630.38135 L 444.46171,629.88883 C 444.7877,628.36166 445.32274,627.11796 446.06565,626.18017 C 446.80857,625.23647 447.89163,624.50655 449.30187,623.99986 C 450.71093,623.49317 452.34321,623.23569 454.20463,623.23569 C 456.05187,623.23569 457.54479,623.45892 458.69754,623.88884 C 459.8503,624.32703 460.69715,624.86797 461.24636,625.52821 C 461.78731,626.18726 462.1629,627.01404 462.38494,628.02034 C 462.50305,628.64632 462.56565,629.77073 462.56565,631.39593 L 462.56565,636.27743 C 462.56565,639.68727 462.64124,641.84042 462.80187,642.7357 C 462.95423,643.63806 463.26723,644.50617 463.72549,645.33294 L 459.89872,645.33294 C 459.52432,644.57585 459.27392,643.68766 459.16998,642.66601 L 459.17,642.666 z M 458.86409,634.48569 C 457.53063,635.0349 455.53811,635.49317 452.88535,635.87467 C 451.37826,636.08963 450.30818,636.33294 449.69047,636.60341 C 449.06567,636.87506 448.57905,637.27073 448.24598,637.79869 C 447.90583,638.31956 447.7322,638.89593 447.7322,639.53491 C 447.7322,640.51404 448.1078,641.32664 448.84362,641.97861 C 449.57945,642.62467 450.66252,642.95066 452.08693,642.95066 C 453.49599,642.95066 454.75268,642.64593 455.84992,642.02704 C 456.94716,641.40932 457.75976,640.56247 458.27354,639.49239 C 458.66921,638.66679 458.8641,637.44435 458.8641,635.83333 L 458.8641,634.48569 L 458.86409,634.48569 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path33" />
-      <polygon
-         points="468.163,645.333 468.163,615.508 471.822,615.508 471.822,645.333 468.163,645.333 "
-         style="fill:#000000;fill-rule:nonzero"
-         id="polygon35" />
-      <polygon
-         points="477.516,626.069 476.585,620.493 476.585,615.508 480.752,615.508 480.752,620.493 479.78,626.069 477.516,626.069 "
-         style="fill:#000000;fill-rule:nonzero"
-         id="polygon37" />
-      <polygon
-         points="496.954,645.333 496.954,615.508 500.613,615.508 500.613,645.333 496.954,645.333 "
-         style="fill:#000000;fill-rule:nonzero"
-         id="polygon39" />
-      <path
-         d="M 504.925,634.527 C 504.925,630.52779 506.03642,627.56204 508.26516,625.6392 C 510.11949,624.04117 512.38366,623.23566 515.0565,623.23566 C 518.02933,623.23566 520.45886,624.20889 522.34154,626.16007 C 524.23012,628.10416 525.16792,630.79117 525.16792,634.22227 C 525.16792,637.00613 524.75099,639.19471 523.91713,640.78447 C 523.08445,642.38132 521.8691,643.61793 520.27933,644.49904 C 518.6813,645.38132 516.94508,645.81951 515.0565,645.81951 C 512.03642,645.81951 509.59154,644.85337 507.72304,642.90927 C 505.85572,640.97226 504.92501,638.18014 504.92501,634.52699 L 504.925,634.527 z M 508.68917,634.527 C 508.68917,637.29787 509.29271,639.36834 510.50098,640.74314 C 511.70925,642.12503 513.23051,642.81243 515.05649,642.81243 C 516.87657,642.81243 518.38956,642.11794 519.59783,640.73605 C 520.80019,639.35416 521.40374,637.24235 521.40374,634.41007 C 521.40374,631.73605 520.8002,629.7081 519.58484,628.3333 C 518.36949,626.9585 516.8624,626.2711 515.05649,626.2711 C 513.23051,626.2711 511.70925,626.9585 510.50098,628.32622 C 509.29271,629.69394 508.68917,631.76323 508.68917,634.52701 L 508.68917,634.527 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path41" />
-      <path
-         d="M 528.793,647.125 L 532.3552,647.65295 C 532.50166,648.75019 532.9174,649.54862 533.59181,650.05531 C 534.50126,650.72854 535.74378,651.0687 537.31346,651.0687 C 539.01543,651.0687 540.32055,650.72855 541.24417,650.05531 C 542.16779,649.375 542.78551,648.42303 543.11149,647.20767 C 543.30637,646.45767 543.39023,644.89625 543.37606,642.50688 C 541.77921,644.38838 539.78551,645.33326 537.39732,645.33326 C 534.42449,645.33326 532.12606,644.26436 530.50086,642.1183 C 528.87684,639.97932 528.05716,637.40334 528.05716,634.41043 C 528.05716,632.34704 528.43157,630.44429 529.17448,628.70216 C 529.92448,626.95885 531.00873,625.61122 532.42487,624.66043 C 533.84101,623.71555 535.50755,623.23602 537.41739,623.23602 C 539.96621,623.23602 542.07093,624.27067 543.7233,626.33405 L 543.7233,623.72972 L 547.1048,623.72972 L 547.1048,642.40292 C 547.1048,645.76434 546.75755,648.15253 546.07724,649.55568 C 545.38983,650.95765 544.30677,652.06907 542.82094,652.88166 C 541.33393,653.69426 539.50795,654.1041 537.33472,654.1041 C 534.75755,654.1041 532.67527,653.52064 531.09141,652.36079 C 529.50165,651.20095 528.73747,649.45764 528.79298,647.12496 L 528.793,647.125 z M 531.82017,634.1459 C 531.82017,636.97936 532.38356,639.04866 533.51505,640.34787 C 534.64064,641.65299 536.0497,642.29905 537.74458,642.29905 C 539.42411,642.29905 540.83434,641.65299 541.97293,640.36086 C 543.11151,639.06283 543.68199,637.03488 543.68199,634.26401 C 543.68199,631.61834 543.09852,629.62582 541.92451,628.28527 C 540.75049,626.94472 539.33435,626.27149 537.68199,626.27149 C 536.05679,626.27149 534.6749,626.93054 533.52923,628.25692 C 532.39065,629.57621 531.82017,631.54157 531.82017,634.1459 L 531.82017,634.1459 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path43" />
-      <path
-         d="M 551.271,634.527 C 551.271,630.52779 552.38242,627.56204 554.61116,625.6392 C 556.46549,624.04117 558.72966,623.23566 561.4025,623.23566 C 564.37533,623.23566 566.80486,624.20889 568.68754,626.16007 C 570.57612,628.10416 571.51392,630.79117 571.51392,634.22227 C 571.51392,637.00613 571.09699,639.19471 570.26313,640.78447 C 569.43045,642.38132 568.2151,643.61793 566.62533,644.49904 C 565.0273,645.38132 563.29108,645.81951 561.4025,645.81951 C 558.38242,645.81951 555.93754,644.85337 554.06904,642.90927 C 552.20172,640.97226 551.27101,638.18014 551.27101,634.52699 L 551.271,634.527 z M 555.03517,634.527 C 555.03517,637.29787 555.63871,639.36834 556.84698,640.74314 C 558.05525,642.12503 559.57651,642.81243 561.40249,642.81243 C 563.22257,642.81243 564.73556,642.11794 565.94383,640.73605 C 567.14619,639.35416 567.74974,637.24235 567.74974,634.41007 C 567.74974,631.73605 567.1462,629.7081 565.93084,628.3333 C 564.71549,626.9585 563.2084,626.2711 561.40249,626.2711 C 559.57651,626.2711 558.05525,626.9585 556.84698,628.32622 C 555.63871,629.69394 555.03517,631.76323 555.03517,634.52701 L 555.03517,634.527 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path45" />
-      <path
-         d="M 588.256,645.333 L 588.256,626.5759 L 585.02687,626.5759 L 585.02687,623.72944 L 588.256,623.72944 L 588.256,621.43101 C 588.256,619.97944 588.38828,618.89636 588.64458,618.19479 C 588.99891,617.24282 589.61781,616.47274 590.506,615.88219 C 591.39537,615.29164 592.63789,614.99991 594.24183,614.99991 C 595.27057,614.99991 596.40915,615.11802 597.65876,615.36841 L 597.11073,618.56329 C 596.35364,618.42392 595.63081,618.35424 594.95049,618.35424 C 593.83907,618.35424 593.05482,618.59046 592.59655,619.06998 C 592.1312,619.54242 591.90206,620.43061 591.90206,621.73573 L 591.90206,623.72943 L 596.11033,623.72943 L 596.11033,626.57589 L 591.90206,626.57589 L 591.90206,645.33299 L 588.256,645.33299 L 588.256,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path47" />
-      <path
-         d="M 598.923,645.333 L 598.923,623.7295 L 602.21473,623.7295 L 602.21473,626.99997 C 603.05449,625.4728 603.83284,624.45824 604.54741,623.9728 C 605.25607,623.48619 606.04032,623.23579 606.89544,623.23579 C 608.13087,623.23579 609.38166,623.63264 610.65843,624.41689 L 609.39465,627.81965 C 608.50646,627.28461 607.61,627.02123 606.71473,627.02123 C 605.90922,627.02123 605.19347,627.26453 604.55449,627.74288 C 603.91551,628.2295 603.46433,628.89564 603.19386,629.74957 C 602.78402,631.04878 602.58323,632.47201 602.58323,634.02044 L 602.58323,645.33304 L 598.92299,645.33304 L 598.923,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path49" />
-      <path
-         d="M 611.471,634.527 C 611.471,630.52779 612.58242,627.56204 614.81116,625.6392 C 616.66549,624.04117 618.92966,623.23566 621.6025,623.23566 C 624.57533,623.23566 627.00486,624.20889 628.88754,626.16007 C 630.77612,628.10416 631.71392,630.79117 631.71392,634.22227 C 631.71392,637.00613 631.29699,639.19471 630.46313,640.78447 C 629.63045,642.38132 628.4151,643.61793 626.82533,644.49904 C 625.2273,645.38132 623.49108,645.81951 621.6025,645.81951 C 618.58242,645.81951 616.13754,644.85337 614.26904,642.90927 C 612.40172,640.97226 611.47101,638.18014 611.47101,634.52699 L 611.471,634.527 z M 615.23517,634.527 C 615.23517,637.29787 615.83871,639.36834 617.04698,640.74314 C 618.25525,642.12503 619.77651,642.81243 621.60249,642.81243 C 623.42257,642.81243 624.93556,642.11794 626.14383,640.73605 C 627.34619,639.35416 627.94974,637.24235 627.94974,634.41007 C 627.94974,631.73605 627.3462,629.7081 626.13084,628.3333 C 624.91549,626.9585 623.4084,626.2711 621.60249,626.2711 C 619.77651,626.2711 618.25525,626.9585 617.04698,628.32622 C 615.83871,629.69394 615.23517,631.76323 615.23517,634.52701 L 615.23517,634.527 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path51" />
-      <path
-         d="M 636.012,645.333 L 636.012,623.7295 L 639.28365,623.7295 L 639.28365,626.75667 C 639.96396,625.70195 640.86633,624.84683 641.99192,624.20903 C 643.11633,623.56297 644.40137,623.2358 645.83877,623.2358 C 647.43562,623.2358 648.74783,623.57005 649.76948,624.23619 C 650.79704,624.90351 651.51869,625.82595 651.93562,627.02123 C 653.65058,624.50076 655.87342,623.2358 658.60885,623.2358 C 660.75491,623.2358 662.40019,623.83344 663.55294,625.02045 C 664.7057,626.20864 665.28207,628.03462 665.28207,630.49958 L 665.28207,645.33308 L 661.64427,645.33308 L 661.64427,631.72208 C 661.64427,630.25751 661.52616,629.20161 661.28994,628.55554 C 661.04663,627.91657 660.61553,627.3957 659.99781,627.00003 C 659.37301,626.61145 658.63718,626.40948 657.79624,626.40948 C 656.27616,626.40948 655.01829,626.91735 654.01199,627.93074 C 653.0116,628.93822 652.5049,630.55515 652.5049,632.77798 L 652.5049,645.33308 L 648.84584,645.33308 L 648.84584,631.29918 C 648.84584,629.6669 648.54702,628.44446 647.94938,627.63186 C 647.35293,626.81926 646.37969,626.40942 645.01907,626.40942 C 643.99151,626.40942 643.03954,626.68107 642.16553,627.22911 C 641.29034,627.77123 640.65136,628.56257 640.26277,629.60431 C 639.86592,630.65313 639.67222,632.16022 639.67222,634.12439 L 639.67222,645.33309 L 636.01198,645.33309 L 636.012,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path53" />
-      <path
-         d="M 685.671,645.333 L 682.27533,645.333 L 682.27533,615.5078 L 685.93439,615.5078 L 685.93439,626.146 C 687.48282,624.20899 689.45526,623.23576 691.85053,623.23576 C 693.18399,623.23576 694.44187,623.50741 695.62888,624.04127 C 696.81589,624.57631 697.78794,625.3334 698.55919,626.29836 C 699.32336,627.27041 699.92691,628.43734 700.35801,629.81214 C 700.79502,631.18104 701.01116,632.6456 701.01116,634.20112 C 701.01116,637.90978 700.09344,640.77041 698.26037,642.79128 C 696.43439,644.81215 694.23281,645.81963 691.671,645.81963 C 689.12218,645.81963 687.12257,644.75664 685.671,642.62475 L 685.671,645.33302 L 685.671,645.333 z M 685.62848,634.3676 C 685.62848,636.95776 685.98281,638.82626 686.68439,639.97902 C 687.83715,641.8676 689.39974,642.81248 691.3651,642.81248 C 692.96904,642.81248 694.35093,642.11799 695.51786,640.72193 C 696.68479,639.33295 697.26707,637.26366 697.26707,634.50697 C 697.26707,631.68768 696.70487,629.60421 695.58754,628.26366 C 694.46904,626.92311 693.11549,626.24988 691.53163,626.24988 C 689.92769,626.24988 688.5458,626.94437 687.37887,628.33334 C 686.21194,629.72232 685.62848,631.7361 685.62848,634.36759 L 685.62848,634.3676 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path55" />
-      <path
-         d="M 720.254,638.375 L 724.03825,638.84035 C 723.44061,641.05492 722.33746,642.76988 720.72644,643.99232 C 719.10833,645.20767 717.04494,645.81949 714.53864,645.81949 C 711.37919,645.81949 708.87171,644.84627 707.02447,642.90217 C 705.17014,640.95808 704.24652,638.22855 704.24652,634.71477 C 704.24652,631.07579 705.18431,628.2565 707.05282,626.24981 C 708.92723,624.24312 711.35085,623.23564 714.33668,623.23564 C 717.22566,623.23564 719.58668,624.22186 721.41385,626.18721 C 723.24692,628.15256 724.16346,630.92343 724.16346,634.48564 C 724.16346,634.70769 724.15637,635.03486 724.1422,635.46478 L 708.032,635.46478 C 708.16428,637.83998 708.83751,639.65887 710.04578,640.91675 C 711.25405,642.18053 712.75405,642.81242 714.55995,642.81242 C 715.89932,642.81242 717.04499,642.45809 717.99696,641.74943 C 718.94775,641.04785 719.69775,639.92345 720.25405,638.37502 L 720.254,638.375 z M 708.2327,632.45177 L 720.2953,632.45177 C 720.13585,630.63878 719.6705,629.27106 718.91341,628.36752 C 717.74648,626.95846 716.23349,626.2498 714.37916,626.2498 C 712.69845,626.2498 711.28113,626.81201 710.13546,627.9376 C 708.98979,629.06201 708.3579,630.5691 708.2327,632.45177 L 708.2327,632.45177 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path57" />
-      <path
-         d="M 736.636,642.056 L 737.16277,645.29222 C 736.13521,645.50718 735.21159,645.6182 734.39899,645.6182 C 733.06671,645.6182 732.03797,645.41033 731.30214,644.98631 C 730.5734,644.56939 730.05962,644.01427 729.7608,643.32686 C 729.46198,642.64655 729.30962,641.20206 729.30962,639.00757 L 729.30962,626.57647 L 726.62143,626.57647 L 726.62143,623.73001 L 729.30962,623.73001 L 729.30962,618.37607 L 732.9545,616.18158 L 732.9545,623.73001 L 736.636,623.73001 L 736.636,626.57647 L 732.9545,626.57647 L 732.9545,639.20837 C 732.9545,640.25719 733.0171,640.92451 733.1423,641.22215 C 733.27458,641.52097 733.48245,641.75719 733.77419,641.9379 C 734.06592,642.11152 734.48285,642.20129 735.02498,642.20129 C 735.43364,642.20129 735.96868,642.15286 736.636,642.05601 L 736.636,642.056 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path59" />
-      <path
-         d="M 754.316,642.666 C 752.95419,643.81876 751.64907,644.63135 750.39946,645.11088 C 749.14159,645.58332 747.79513,645.81954 746.35773,645.81954 C 743.98253,645.81954 742.16364,645.24316 740.88568,644.08332 C 739.61481,642.92348 738.97584,641.43765 738.97584,639.63883 C 738.97584,638.57584 739.21206,637.61088 739.69749,636.73568 C 740.17702,635.86048 740.80891,635.16009 741.58725,634.63214 C 742.37151,634.10419 743.2467,633.70143 744.22583,633.43096 C 744.9404,633.24317 746.02465,633.05537 747.47504,632.88175 C 750.4337,632.52742 752.61402,632.11049 754.01008,631.61797 C 754.02426,631.11836 754.03134,630.79828 754.03134,630.666 C 754.03134,629.17309 753.6841,628.11836 752.98961,627.51364 C 752.0589,626.68096 750.66284,626.27112 748.82268,626.27112 C 747.10063,626.27112 745.82977,626.56994 745.00299,627.17348 C 744.18331,627.77821 743.57976,628.8471 743.18409,630.38135 L 739.60771,629.88883 C 739.9337,628.36166 740.46874,627.11796 741.21165,626.18017 C 741.95457,625.23647 743.03763,624.50655 744.44787,623.99986 C 745.85693,623.49317 747.48921,623.23569 749.35063,623.23569 C 751.19787,623.23569 752.69079,623.45892 753.84354,623.88884 C 754.9963,624.32703 755.84315,624.86797 756.39236,625.52821 C 756.93331,626.18726 757.3089,627.01404 757.53094,628.02034 C 757.64905,628.64632 757.71165,629.77073 757.71165,631.39593 L 757.71165,636.27743 C 757.71165,639.68727 757.78724,641.84042 757.94787,642.7357 C 758.10023,643.63806 758.41323,644.50617 758.87149,645.33294 L 755.04472,645.33294 C 754.67032,644.57585 754.41992,643.68766 754.31598,642.66601 L 754.316,642.666 z M 754.01009,634.48569 C 752.67663,635.0349 750.68411,635.49317 748.03135,635.87467 C 746.52426,636.08963 745.45418,636.33294 744.83647,636.60341 C 744.21167,636.87506 743.72505,637.27073 743.39198,637.79869 C 743.05183,638.31956 742.8782,638.89593 742.8782,639.53491 C 742.8782,640.51404 743.25379,641.32664 743.98962,641.97861 C 744.72545,642.62467 745.80852,642.95066 747.23293,642.95066 C 748.64199,642.95066 749.89868,642.64593 750.99592,642.02704 C 752.09316,641.40932 752.90576,640.56247 753.41954,639.49239 C 753.81521,638.66679 754.01009,637.44435 754.01009,635.83333 L 754.01009,634.48569 L 754.01009,634.48569 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path61" />
-      <polygon
-         points="764.426,645.333 764.426,641.159 768.6,641.159 768.6,645.333 764.426,645.333 "
-         style="fill:#000000;fill-rule:nonzero"
-         id="polygon63" />
-      <path
-         d="M 774.967,653.61 L 774.967,623.7293 L 778.30007,623.7293 L 778.30007,626.53442 C 779.0855,625.43718 779.97369,624.61159 780.967,624.06237 C 781.95322,623.51434 783.1544,623.2356 784.56464,623.2356 C 786.41188,623.2356 788.03708,623.71513 789.44614,624.66001 C 790.86228,625.61079 791.92527,626.95135 792.64102,628.68048 C 793.36267,630.40961 793.72409,632.30528 793.72409,634.36749 C 793.72409,636.57615 793.32842,638.56867 792.53,640.34032 C 791.73748,642.11079 790.58472,643.46434 789.07173,644.40922 C 787.55756,645.34701 785.96661,645.81946 784.30008,645.81946 C 783.07882,645.81946 781.98748,645.56198 781.01543,645.0482 C 780.04338,644.53442 779.25204,643.88127 778.62724,643.09702 L 778.62724,653.61002 L 774.967,653.61002 L 774.967,653.61 z M 778.27999,634.6521 C 778.27999,637.43005 778.84219,639.48517 779.96779,640.81864 C 781.0922,642.14502 782.45992,642.81234 784.05795,642.81234 C 785.68197,642.81234 787.07803,642.12494 788.23787,640.74305 C 789.39771,639.36825 789.98118,637.23636 789.98118,634.34738 C 789.98118,631.58951 789.41189,629.53439 788.27921,628.15958 C 787.14771,626.79186 785.79299,626.10446 784.22449,626.10446 C 782.66189,626.10446 781.28,626.8332 780.07882,628.29186 C 778.87646,629.74934 778.28,631.87532 778.28,634.6521 L 778.27999,634.6521 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path65" />
-      <path
-         d="M 797.974,653.653 L 797.56416,650.21481 C 798.36967,650.43095 799.06416,650.54198 799.6618,650.54198 C 800.47439,650.54198 801.12637,650.40261 801.61298,650.13213 C 802.1055,649.86048 802.50235,649.48607 802.81416,648.99237 C 803.05038,648.63214 803.41888,647.72268 803.93266,646.27111 C 804.00234,646.06206 804.11337,645.77033 804.25864,645.37465 L 796.06415,623.72975 L 800.00903,623.72975 L 804.50903,636.23645 C 805.08541,637.82621 805.61336,639.49275 806.07163,641.24315 C 806.49447,639.56244 806.99525,637.92425 807.57872,636.31912 L 812.19565,623.72973 L 815.85589,623.72973 L 807.64014,645.70173 C 806.75904,648.07574 806.07164,649.70803 805.58502,650.60448 C 804.93187,651.81275 804.18896,652.69385 803.34919,653.25724 C 802.50234,653.81945 801.50195,654.10409 800.33502,654.10409 C 799.62636,654.10409 798.84211,653.95055 797.974,653.65291 L 797.974,653.653 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path67" />
-      <path
-         d="M 826.967,642.056 L 827.49377,645.29222 C 826.46621,645.50718 825.54259,645.6182 824.72999,645.6182 C 823.39771,645.6182 822.36897,645.41033 821.63314,644.98631 C 820.9044,644.56939 820.39062,644.01427 820.0918,643.32686 C 819.79298,642.64655 819.64062,641.20206 819.64062,639.00757 L 819.64062,626.57647 L 816.95243,626.57647 L 816.95243,623.73001 L 819.64062,623.73001 L 819.64062,618.37607 L 823.2855,616.18158 L 823.2855,623.73001 L 826.967,623.73001 L 826.967,626.57647 L 823.2855,626.57647 L 823.2855,639.20837 C 823.2855,640.25719 823.3481,640.92451 823.4733,641.22215 C 823.60558,641.52097 823.81345,641.75719 824.10519,641.9379 C 824.39692,642.11152 824.81385,642.20129 825.35598,642.20129 C 825.76464,642.20129 826.29968,642.15286 826.967,642.05601 L 826.967,642.056 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path69" />
-      <path
-         d="M 830.549,645.333 L 830.549,615.5078 L 834.20924,615.5078 L 834.20924,626.2086 C 835.91711,624.22907 838.07735,623.23577 840.6805,623.23577 C 842.27853,623.23577 843.66751,623.55585 844.84743,624.18774 C 846.02853,624.81254 846.87538,625.68774 847.38208,626.79916 C 847.88877,627.9094 848.14625,629.52751 848.14625,631.63932 L 848.14625,645.33302 L 844.48011,645.33302 L 844.48011,631.63932 C 844.48011,629.81215 844.08326,628.47869 843.29192,627.64601 C 842.50058,626.81215 841.37499,626.38932 839.9246,626.38932 C 838.84035,626.38932 837.81988,626.67396 836.862,627.23617 C 835.90295,627.79837 835.22263,628.56255 834.81987,629.52751 C 834.41003,630.48656 834.20924,631.81885 834.20924,633.51373 L 834.20924,645.33303 L 830.549,645.33303 L 830.549,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path71" />
-      <path
-         d="M 852.354,634.527 C 852.354,630.52779 853.46542,627.56204 855.69416,625.6392 C 857.54849,624.04117 859.81266,623.23566 862.4855,623.23566 C 865.45833,623.23566 867.88786,624.20889 869.77054,626.16007 C 871.65912,628.10416 872.59692,630.79117 872.59692,634.22227 C 872.59692,637.00613 872.17999,639.19471 871.34613,640.78447 C 870.51345,642.38132 869.2981,643.61793 867.70833,644.49904 C 866.1103,645.38132 864.37408,645.81951 862.4855,645.81951 C 859.46542,645.81951 857.02054,644.85337 855.15204,642.90927 C 853.28472,640.97226 852.35401,638.18014 852.35401,634.52699 L 852.354,634.527 z M 856.11817,634.527 C 856.11817,637.29787 856.72171,639.36834 857.92998,640.74314 C 859.13825,642.12503 860.65951,642.81243 862.48549,642.81243 C 864.30557,642.81243 865.81856,642.11794 867.02683,640.73605 C 868.22919,639.35416 868.83274,637.24235 868.83274,634.41007 C 868.83274,631.73605 868.2292,629.7081 867.01384,628.3333 C 865.79849,626.9585 864.2914,626.2711 862.48549,626.2711 C 860.65951,626.2711 859.13825,626.9585 857.92998,628.32622 C 856.72171,629.69394 856.11817,631.76323 856.11817,634.52701 L 856.11817,634.527 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path73" />
-      <path
-         d="M 876.895,645.333 L 876.895,623.7295 L 880.18673,623.7295 L 880.18673,626.79919 C 881.77767,624.42399 884.06901,623.2358 887.06193,623.2358 C 888.36705,623.2358 889.56114,623.47202 890.65248,623.93737 C 891.74972,624.40982 892.56114,625.02045 893.10327,625.78462 C 893.65248,626.5417 894.02689,627.44407 894.24894,628.4858 C 894.38122,629.16729 894.45091,630.3543 894.45091,632.04919 L 894.45091,645.33309 L 890.78359,645.33309 L 890.78359,632.18739 C 890.78359,630.70156 890.6454,629.58306 890.36075,628.84015 C 890.07611,628.10432 889.56823,627.51377 888.84658,627.07676 C 888.11784,626.63266 887.26981,626.40943 886.29067,626.40943 C 884.72807,626.40943 883.3887,626.91022 882.24894,627.89644 C 881.11744,628.88857 880.55524,630.76416 880.55524,633.53502 L 880.55524,645.33302 L 876.895,645.33302 L 876.895,645.333 z "
-         style="fill:#000000;fill-rule:nonzero"
-         id="path75" />
-    </g>
-    <g
-       transform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"
-       style="fill-rule:evenodd"
-       id="_19428312">
-   <path
-   d="M 341.207,1443.54 L 332.98535,1421.9365 L 336.85346,1421.9365 L 341.49165,1434.8731 C 341.99244,1436.2692 342.4507,1437.7207 342.87354,1439.2278 C 343.2007,1438.0892 343.65189,1436.7203 344.23535,1435.1164 L 349.04007,1421.9365 L 352.80424,1421.9365 L 344.62393,1443.54 L 341.207,1443.54 L 341.207,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="_19439224" />
-
-   <path
-   d="M 370.825,1436.58 L 374.60925,1437.0454 C 374.01161,1439.2599 372.90846,1440.9749 371.29744,1442.1973 C 369.67933,1443.4127 367.61594,1444.0245 365.10964,1444.0245 C 361.95019,1444.0245 359.44271,1443.0513 357.59547,1441.1072 C 355.74114,1439.1631 354.81752,1436.4336 354.81752,1432.9198 C 354.81752,1429.2808 355.75532,1426.4615 357.62382,1424.4548 C 359.49823,1422.4481 361.92185,1421.4406 364.90768,1421.4406 C 367.79666,1421.4406 370.15768,1422.4269 371.98485,1424.3922 C 373.81792,1426.3576 374.73446,1429.1284 374.73446,1432.6906 C 374.73446,1432.9127 374.72737,1433.2399 374.7132,1433.6698 L 358.603,1433.6698 C 358.73528,1436.045 359.40851,1437.8639 360.61678,1439.1217 C 361.82505,1440.3855 363.32505,1441.0174 365.13095,1441.0174 C 366.47032,1441.0174 367.61599,1440.6631 368.56796,1439.9544 C 369.51875,1439.2529 370.26875,1438.1284 370.82505,1436.58 L 370.825,1436.58 z M 358.8037,1430.6568 L 370.8663,1430.6568 C 370.70685,1428.8438 370.2415,1427.4761 369.48441,1426.5725 C 368.31748,1425.1635 366.80449,1424.4548 364.95016,1424.4548 C 363.26945,1424.4548 361.85213,1425.017 360.70646,1426.1426 C 359.56079,1427.267 358.9289,1428.7741 358.8037,1430.6568 L 358.8037,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path79" />
-
-   <path
-   d="M 379.172,1443.54 L 379.172,1421.9365 L 382.46373,1421.9365 L 382.46373,1425.207 C 383.30349,1423.6798 384.08184,1422.6652 384.79641,1422.1798 C 385.50507,1421.6932 386.28932,1421.4428 387.14444,1421.4428 C 388.37987,1421.4428 389.63066,1421.8396 390.90743,1422.6239 L 389.64365,1426.0267 C 388.75546,1425.4916 387.859,1425.2282 386.96373,1425.2282 C 386.15822,1425.2282 385.44247,1425.4715 384.80349,1425.9499 C 384.16451,1426.4365 383.71333,1427.1026 383.44286,1427.9566 C 383.03302,1429.2558 382.83223,1430.679 382.83223,1432.2274 L 382.83223,1443.54 L 379.17199,1443.54 L 379.172,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path81" />
-
-   <path
-   d="M 391.623,1437.09 L 395.24072,1436.5207 C 395.44151,1437.9723 396.01198,1439.0825 396.94151,1439.8609 C 397.86513,1440.6309 399.16434,1441.0207 400.83797,1441.0207 C 402.51868,1441.0207 403.76828,1440.6735 404.58088,1439.9931 C 405.39348,1439.3057 405.80332,1438.4991 405.80332,1437.5825 C 405.80332,1436.7498 405.4419,1436.1038 404.71907,1435.6242 C 404.21946,1435.2983 402.96986,1434.8884 400.97616,1434.3888 C 398.29624,1433.7085 396.42773,1433.125 395.39309,1432.6242 C 394.35844,1432.1317 393.56711,1431.4443 393.03207,1430.5691 C 392.49821,1429.6939 392.22656,1428.729 392.22656,1427.6731 C 392.22656,1426.7081 392.4486,1425.8199 392.89388,1425.0002 C 393.33089,1424.1735 393.93561,1423.4931 394.69152,1422.951 C 395.26199,1422.5353 396.03916,1422.1739 397.01829,1421.8821 C 398.00451,1421.5904 399.06042,1421.4439 400.18483,1421.4439 C 401.87971,1421.4439 403.36554,1421.6943 404.65058,1422.1809 C 405.93444,1422.6664 406.87932,1423.3266 407.48995,1424.1593 C 408.10176,1425.0002 408.51869,1426.1105 408.74782,1427.5065 L 405.17144,1428.0002 C 405.00491,1426.8888 404.53247,1426.0207 403.75412,1425.3959 C 402.97696,1424.7711 401.87262,1424.4581 400.4494,1424.4581 C 398.76869,1424.4581 397.56751,1424.7357 396.85176,1425.292 C 396.13011,1425.8471 395.76869,1426.5002 395.76869,1427.2432 C 395.76869,1427.7215 395.92105,1428.1455 396.21987,1428.5282 C 396.51869,1428.9239 396.98405,1429.2428 397.62302,1429.5073 C 397.99034,1429.6384 399.06751,1429.9514 400.85806,1430.4369 C 403.44822,1431.1313 405.25412,1431.6947 406.2746,1432.1388 C 407.30334,1432.5758 408.10885,1433.2219 408.69232,1434.0617 C 409.27461,1434.9026 409.56634,1435.9443 409.56634,1437.1939 C 409.56634,1438.4164 409.2061,1439.562 408.49744,1440.6451 C 407.78169,1441.7223 406.75413,1442.555 405.41358,1443.1455 C 404.07421,1443.7361 402.55295,1444.0278 400.85807,1444.0278 C 398.04587,1444.0278 395.90689,1443.4443 394.43524,1442.2774 C 392.96241,1441.1105 392.02579,1439.3813 391.62304,1437.09 L 391.623,1437.09 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path83" />
-
-   <path
-   d="M 413.934,1417.93 L 413.934,1413.7158 L 417.60014,1413.7158 L 417.60014,1417.93 L 413.934,1417.93 z M 413.934,1443.541 L 413.934,1421.9375 L 417.60014,1421.9375 L 417.60014,1443.541 L 413.934,1443.541 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path85" />
-
-   <path
-   d="M 421.808,1432.74 C 421.808,1428.7408 422.91942,1425.775 425.14816,1423.8522 C 427.00249,1422.2542 429.26666,1421.4487 431.9395,1421.4487 C 434.91233,1421.4487 437.34186,1422.4219 439.22454,1424.3731 C 441.11312,1426.3172 442.05092,1429.0042 442.05092,1432.4353 C 442.05092,1435.2191 441.63399,1437.4077 440.80013,1438.9975 C 439.96745,1440.5943 438.7521,1441.8309 437.16233,1442.712 C 435.5643,1443.5943 433.82808,1444.0325 431.9395,1444.0325 C 428.91942,1444.0325 426.47454,1443.0664 424.60604,1441.1223 C 422.73872,1439.1853 421.80801,1436.3931 421.80801,1432.74 L 421.808,1432.74 z M 425.57217,1432.74 C 425.57217,1435.5109 426.17571,1437.5813 427.38398,1438.9561 C 428.59225,1440.338 430.11351,1441.0254 431.93949,1441.0254 C 433.75957,1441.0254 435.27256,1440.3309 436.48083,1438.949 C 437.68319,1437.5672 438.28674,1435.4554 438.28674,1432.6231 C 438.28674,1429.949 437.6832,1427.9211 436.46784,1426.5463 C 435.25249,1425.1715 433.7454,1424.4841 431.93949,1424.4841 C 430.11351,1424.4841 428.59225,1425.1715 427.38398,1426.5392 C 426.17571,1427.9069 425.57217,1429.9762 425.57217,1432.74 L 425.57217,1432.74 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path87" />
-
-   <path
-   d="M 446.349,1443.54 L 446.349,1421.9365 L 449.64073,1421.9365 L 449.64073,1425.0062 C 451.23167,1422.631 453.52301,1421.4428 456.51593,1421.4428 C 457.82105,1421.4428 459.01514,1421.679 460.10648,1422.1444 C 461.20372,1422.6168 462.01514,1423.2274 462.55727,1423.9916 C 463.10648,1424.7487 463.48089,1425.6511 463.70294,1426.6928 C 463.83522,1427.3743 463.90491,1428.5613 463.90491,1430.2562 L 463.90491,1443.5401 L 460.23759,1443.5401 L 460.23759,1430.3944 C 460.23759,1428.9086 460.0994,1427.7901 459.81475,1427.0471 C 459.53011,1426.3113 459.02223,1425.7208 458.30058,1425.2838 C 457.57184,1424.8397 456.72381,1424.6164 455.74467,1424.6164 C 454.18207,1424.6164 452.8427,1425.1172 451.70294,1426.1034 C 450.57144,1427.0956 450.00924,1428.9712 450.00924,1431.742 L 450.00924,1443.54 L 446.349,1443.54 L 446.349,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path89" />
-
-   <path
-   d="M 481.113,1417.93 L 481.113,1413.7158 L 484.77914,1413.7158 L 484.77914,1417.93 L 481.113,1417.93 z M 481.113,1443.541 L 481.113,1421.9375 L 484.77914,1421.9375 L 484.77914,1443.541 L 481.113,1443.541 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path91" />
-
-   <path
-   d="M 490.355,1443.54 L 490.355,1421.9365 L 493.64673,1421.9365 L 493.64673,1425.0062 C 495.23767,1422.631 497.52901,1421.4428 500.52193,1421.4428 C 501.82705,1421.4428 503.02114,1421.679 504.11248,1422.1444 C 505.20972,1422.6168 506.02114,1423.2274 506.56327,1423.9916 C 507.11248,1424.7487 507.48689,1425.6511 507.70894,1426.6928 C 507.84122,1427.3743 507.91091,1428.5613 507.91091,1430.2562 L 507.91091,1443.5401 L 504.24359,1443.5401 L 504.24359,1430.3944 C 504.24359,1428.9086 504.1054,1427.7901 503.82075,1427.0471 C 503.53611,1426.3113 503.02823,1425.7208 502.30658,1425.2838 C 501.57784,1424.8397 500.72981,1424.6164 499.75067,1424.6164 C 498.18807,1424.6164 496.8487,1425.1172 495.70894,1426.1034 C 494.57744,1427.0956 494.01524,1428.9712 494.01524,1431.742 L 494.01524,1443.54 L 490.355,1443.54 L 490.355,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path93" />
-
-   <path
-   d="M 539.264,1443.54 L 539.264,1440.3664 C 537.5762,1442.8113 535.29195,1444.0266 532.40298,1444.0266 C 531.13211,1444.0266 529.93684,1443.7833 528.83369,1443.2967 C 527.72936,1442.8113 526.90967,1442.1924 526.37463,1441.4565 C 525.83368,1440.7136 525.45809,1439.8113 525.24313,1438.7412 C 525.09667,1438.0195 525.02108,1436.8809 525.02108,1435.3184 L 525.02108,1421.9365 L 528.68014,1421.9365 L 528.68014,1433.9152 C 528.68014,1435.8321 528.75691,1437.1159 528.90219,1437.7833 C 529.13841,1438.7482 529.62502,1439.4982 530.36794,1440.0533 C 531.11794,1440.6026 532.04156,1440.873 533.13881,1440.873 C 534.23605,1440.873 535.26361,1440.5955 536.22857,1440.0333 C 537.19353,1439.4711 537.87503,1438.6998 538.2707,1437.7348 C 538.67346,1436.7628 538.87424,1435.3526 538.87424,1433.5124 L 538.87424,1421.9364 L 542.53448,1421.9364 L 542.53448,1443.5399 L 539.26401,1443.5399 L 539.264,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path95" />
-
-   <path
-   d="M 546.813,1437.09 L 550.43072,1436.5207 C 550.63151,1437.9723 551.20198,1439.0825 552.13151,1439.8609 C 553.05513,1440.6309 554.35434,1441.0207 556.02797,1441.0207 C 557.70868,1441.0207 558.95828,1440.6735 559.77088,1439.9931 C 560.58348,1439.3057 560.99332,1438.4991 560.99332,1437.5825 C 560.99332,1436.7498 560.6319,1436.1038 559.90907,1435.6242 C 559.40946,1435.2983 558.15986,1434.8884 556.16616,1434.3888 C 553.48624,1433.7085 551.61773,1433.125 550.58309,1432.6242 C 549.54844,1432.1317 548.75711,1431.4443 548.22207,1430.5691 C 547.68821,1429.6939 547.41656,1428.729 547.41656,1427.6731 C 547.41656,1426.7081 547.6386,1425.8199 548.08388,1425.0002 C 548.52089,1424.1735 549.12561,1423.4931 549.88152,1422.951 C 550.45199,1422.5353 551.22916,1422.1739 552.20829,1421.8821 C 553.19451,1421.5904 554.25042,1421.4439 555.37483,1421.4439 C 557.06971,1421.4439 558.55554,1421.6943 559.84058,1422.1809 C 561.12444,1422.6664 562.06932,1423.3266 562.67995,1424.1593 C 563.29176,1425.0002 563.70869,1426.1105 563.93782,1427.5065 L 560.36144,1428.0002 C 560.19491,1426.8888 559.72247,1426.0207 558.94412,1425.3959 C 558.16696,1424.7711 557.06262,1424.4581 555.6394,1424.4581 C 553.95869,1424.4581 552.75751,1424.7357 552.04176,1425.292 C 551.32011,1425.8471 550.95869,1426.5002 550.95869,1427.2432 C 550.95869,1427.7215 551.11105,1428.1455 551.40987,1428.5282 C 551.70869,1428.9239 552.17405,1429.2428 552.81302,1429.5073 C 553.18035,1429.6384 554.25751,1429.9514 556.04806,1430.4369 C 558.63822,1431.1313 560.44412,1431.6947 561.4646,1432.1388 C 562.49334,1432.5758 563.29885,1433.2219 563.88232,1434.0617 C 564.46461,1434.9026 564.75634,1435.9443 564.75634,1437.1939 C 564.75634,1438.4164 564.3961,1439.562 563.68744,1440.6451 C 562.97169,1441.7223 561.94413,1442.555 560.60358,1443.1455 C 559.26421,1443.7361 557.74295,1444.0278 556.04807,1444.0278 C 553.23587,1444.0278 551.09689,1443.4443 549.62524,1442.2774 C 548.15241,1441.1105 547.21579,1439.3813 546.81304,1437.09 L 546.813,1437.09 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path97" />
-
-   <path
-   d="M 583.894,1436.58 L 587.67825,1437.0454 C 587.08061,1439.2599 585.97746,1440.9749 584.36644,1442.1973 C 582.74833,1443.4127 580.68494,1444.0245 578.17864,1444.0245 C 575.01919,1444.0245 572.51171,1443.0513 570.66447,1441.1072 C 568.81014,1439.1631 567.88652,1436.4336 567.88652,1432.9198 C 567.88652,1429.2808 568.82431,1426.4615 570.69282,1424.4548 C 572.56723,1422.4481 574.99085,1421.4406 577.97668,1421.4406 C 580.86566,1421.4406 583.22668,1422.4269 585.05385,1424.3922 C 586.88692,1426.3576 587.80346,1429.1284 587.80346,1432.6906 C 587.80346,1432.9127 587.79637,1433.2399 587.7822,1433.6698 L 571.672,1433.6698 C 571.80428,1436.045 572.47751,1437.8639 573.68578,1439.1217 C 574.89405,1440.3855 576.39405,1441.0174 578.19995,1441.0174 C 579.53932,1441.0174 580.68499,1440.6631 581.63696,1439.9544 C 582.58775,1439.2529 583.33775,1438.1284 583.89405,1436.58 L 583.894,1436.58 z M 571.8727,1430.6568 L 583.9353,1430.6568 C 583.77585,1428.8438 583.3105,1427.4761 582.55341,1426.5725 C 581.38648,1425.1635 579.87349,1424.4548 578.01916,1424.4548 C 576.33845,1424.4548 574.92113,1425.017 573.77546,1426.1426 C 572.62979,1427.267 571.9979,1428.7741 571.8727,1430.6568 L 571.8727,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path99" />
-
-   <path
-   d="M 602.491,1432.74 C 602.491,1428.7408 603.60242,1425.775 605.83116,1423.8522 C 607.68549,1422.2542 609.94966,1421.4487 612.6225,1421.4487 C 615.59533,1421.4487 618.02486,1422.4219 619.90754,1424.3731 C 621.79612,1426.3172 622.73392,1429.0042 622.73392,1432.4353 C 622.73392,1435.2191 622.31699,1437.4077 621.48313,1438.9975 C 620.65045,1440.5943 619.4351,1441.8309 617.84533,1442.712 C 616.2473,1443.5943 614.51108,1444.0325 612.6225,1444.0325 C 609.60242,1444.0325 607.15754,1443.0664 605.28904,1441.1223 C 603.42172,1439.1853 602.49101,1436.3931 602.49101,1432.74 L 602.491,1432.74 z M 606.25517,1432.74 C 606.25517,1435.5109 606.85871,1437.5813 608.06698,1438.9561 C 609.27525,1440.338 610.79651,1441.0254 612.62249,1441.0254 C 614.44257,1441.0254 615.95556,1440.3309 617.16383,1438.949 C 618.36619,1437.5672 618.96974,1435.4554 618.96974,1432.6231 C 618.96974,1429.949 618.3662,1427.9211 617.15084,1426.5463 C 615.93549,1425.1715 614.4284,1424.4841 612.62249,1424.4841 C 610.79651,1424.4841 609.27525,1425.1715 608.06698,1426.5392 C 606.85871,1427.9069 606.25517,1429.9762 606.25517,1432.74 L 606.25517,1432.74 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path101" />
-
-   <path
-   d="M 627.032,1443.54 L 627.032,1421.9365 L 630.32373,1421.9365 L 630.32373,1425.0062 C 631.91467,1422.631 634.20601,1421.4428 637.19893,1421.4428 C 638.50405,1421.4428 639.69814,1421.679 640.78948,1422.1444 C 641.88672,1422.6168 642.69814,1423.2274 643.24027,1423.9916 C 643.78948,1424.7487 644.16389,1425.6511 644.38594,1426.6928 C 644.51822,1427.3743 644.58791,1428.5613 644.58791,1430.2562 L 644.58791,1443.5401 L 640.92059,1443.5401 L 640.92059,1430.3944 C 640.92059,1428.9086 640.7824,1427.7901 640.49775,1427.0471 C 640.21311,1426.3113 639.70523,1425.7208 638.98358,1425.2838 C 638.25484,1424.8397 637.40681,1424.6164 636.42767,1424.6164 C 634.86507,1424.6164 633.5257,1425.1172 632.38594,1426.1034 C 631.25444,1427.0956 630.69224,1428.9712 630.69224,1431.742 L 630.69224,1443.54 L 627.032,1443.54 L 627.032,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path103" />
-
-   <path
-   d="M 988.517,1440.88 C 987.15519,1442.0328 985.85007,1442.8454 984.60046,1443.3249 C 983.34259,1443.7973 981.99613,1444.0335 980.55873,1444.0335 C 978.18353,1444.0335 976.36464,1443.4572 975.08668,1442.2973 C 973.81581,1441.1375 973.17684,1439.6517 973.17684,1437.8528 C 973.17684,1436.7898 973.41306,1435.8249 973.89849,1434.9497 C 974.37802,1434.0745 975.00991,1433.3741 975.78825,1432.8461 C 976.57251,1432.3182 977.4477,1431.9154 978.42683,1431.645 C 979.1414,1431.4572 980.22565,1431.2694 981.67604,1431.0957 C 984.6347,1430.7414 986.81502,1430.3245 988.21108,1429.832 C 988.22526,1429.3324 988.23234,1429.0123 988.23234,1428.88 C 988.23234,1427.3871 987.8851,1426.3324 987.19061,1425.7276 C 986.2599,1424.895 984.86384,1424.4851 983.02368,1424.4851 C 981.30163,1424.4851 980.03077,1424.7839 979.20399,1425.3875 C 978.38431,1425.9922 977.78076,1427.0611 977.38509,1428.5954 L 973.80871,1428.1028 C 974.1347,1426.5757 974.66974,1425.332 975.41265,1424.3942 C 976.15557,1423.4505 977.23863,1422.7206 978.64887,1422.2139 C 980.05793,1421.7072 981.69021,1421.4497 983.55163,1421.4497 C 985.39887,1421.4497 986.89179,1421.6729 988.04454,1422.1028 C 989.1973,1422.541 990.04415,1423.082 990.59336,1423.7422 C 991.13431,1424.4013 991.5099,1425.228 991.73194,1426.2343 C 991.85005,1426.8603 991.91265,1427.9847 991.91265,1429.6099 L 991.91265,1434.4914 C 991.91265,1437.9013 991.98824,1440.0544 992.14887,1440.9497 C 992.30123,1441.8521 992.61423,1442.7202 993.07249,1443.5469 L 989.24572,1443.5469 C 988.87132,1442.7899 988.62092,1441.9017 988.51698,1440.88 L 988.517,1440.88 z M 988.21109,1432.6997 C 986.87763,1433.2489 984.88511,1433.7072 982.23235,1434.0887 C 980.72526,1434.3036 979.65518,1434.5469 979.03747,1434.8174 C 978.41267,1435.0891 977.92605,1435.4847 977.59298,1436.0127 C 977.25283,1436.5336 977.0792,1437.1099 977.0792,1437.7489 C 977.0792,1438.728 977.45479,1439.5406 978.19062,1440.1926 C 978.92645,1440.8387 980.00952,1441.1647 981.43393,1441.1647 C 982.84299,1441.1647 984.09968,1440.8599 985.19692,1440.241 C 986.29416,1439.6233 987.10676,1438.7765 987.62054,1437.7064 C 988.01621,1436.8808 988.21109,1435.6584 988.21109,1434.0473 L 988.21109,1432.6997 L 988.21109,1432.6997 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path105" />
-
-   <path
-   d="M 1011.61,1443.54 L 1011.61,1440.8105 C 1010.2423,1442.9565 1008.2285,1444.0266 1005.5687,1444.0266 C 1003.8466,1444.0266 1002.2628,1443.5542 1000.8183,1442.6022 C 999.37378,1441.6585 998.25646,1440.3321 997.45803,1438.6231 C 996.66551,1436.9223 996.26984,1434.9711 996.26984,1432.7553 C 996.26984,1430.6022 996.63126,1428.6439 997.34701,1426.8876 C 998.06866,1425.1302 999.14465,1423.7837 1000.5821,1422.853 C 1002.0206,1421.9152 1003.6317,1421.4427 1005.4092,1421.4427 C 1006.7073,1421.4427 1007.8671,1421.7215 1008.8805,1422.2695 C 1009.9021,1422.8187 1010.7277,1423.5333 1011.3667,1424.4156 L 1011.3667,1413.7148 L 1015.0057,1413.7148 L 1015.0057,1443.54 L 1011.61,1443.54 L 1011.61,1443.54 z M 1000.034,1432.7554 C 1000.034,1435.5263 1000.6175,1437.5956 1001.7844,1438.9633 C 1002.9501,1440.3322 1004.3261,1441.0196 1005.9159,1441.0196 C 1007.5127,1441.0196 1008.8746,1440.3593 1009.9919,1439.0542 C 1011.1104,1437.7479 1011.6726,1435.7483 1011.6726,1433.0613 C 1011.6726,1430.1027 1011.1033,1427.9365 1009.9647,1426.5546 C 1008.8249,1425.1656 1007.423,1424.4782 1005.7494,1424.4782 C 1004.1242,1424.4782 1002.7635,1425.1444 1001.6734,1426.4708 C 1000.582,1427.7971 1000.034,1429.8948 1000.034,1432.7554 L 1000.034,1432.7554 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path107" />
-
-   <path
-   d="M 1020.78,1417.93 L 1020.78,1413.7158 L 1024.4461,1413.7158 L 1024.4461,1417.93 L 1020.78,1417.93 z M 1020.78,1443.541 L 1020.78,1421.9375 L 1024.4461,1421.9375 L 1024.4461,1443.541 L 1020.78,1443.541 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path109" />
-
-   <path
-   d="M 1044.81,1436.58 L 1048.5942,1437.0454 C 1047.9966,1439.2599 1046.8935,1440.9749 1045.2824,1442.1973 C 1043.6643,1443.4127 1041.6009,1444.0245 1039.0946,1444.0245 C 1035.9352,1444.0245 1033.4277,1443.0513 1031.5805,1441.1072 C 1029.7261,1439.1631 1028.8025,1436.4336 1028.8025,1432.9198 C 1028.8025,1429.2808 1029.7403,1426.4615 1031.6088,1424.4548 C 1033.4832,1422.4481 1035.9069,1421.4406 1038.8927,1421.4406 C 1041.7817,1421.4406 1044.1427,1422.4269 1045.9699,1424.3922 C 1047.8029,1426.3576 1048.7195,1429.1284 1048.7195,1432.6906 C 1048.7195,1432.9127 1048.7124,1433.2399 1048.6982,1433.6698 L 1032.588,1433.6698 C 1032.7203,1436.045 1033.3935,1437.8639 1034.6018,1439.1217 C 1035.8101,1440.3855 1037.3101,1441.0174 1039.116,1441.0174 C 1040.4553,1441.0174 1041.601,1440.6631 1042.553,1439.9544 C 1043.5037,1439.2529 1044.2538,1438.1284 1044.8101,1436.58 L 1044.81,1436.58 z M 1032.7887,1430.6568 L 1044.8513,1430.6568 C 1044.6919,1428.8438 1044.2265,1427.4761 1043.4694,1426.5725 C 1042.3025,1425.1635 1040.7895,1424.4548 1038.9352,1424.4548 C 1037.2544,1424.4548 1035.8371,1425.017 1034.6915,1426.1426 C 1033.5458,1427.267 1032.9139,1428.7741 1032.7887,1430.6568 L 1032.7887,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path111" />
-
-   <path
-   d="M 1053.19,1443.54 L 1053.19,1421.9365 L 1056.4817,1421.9365 L 1056.4817,1425.0062 C 1058.0727,1422.631 1060.364,1421.4428 1063.3569,1421.4428 C 1064.662,1421.4428 1065.8561,1421.679 1066.9475,1422.1444 C 1068.0447,1422.6168 1068.8561,1423.2274 1069.3983,1423.9916 C 1069.9475,1424.7487 1070.3219,1425.6511 1070.5439,1426.6928 C 1070.6762,1427.3743 1070.7459,1428.5613 1070.7459,1430.2562 L 1070.7459,1443.5401 L 1067.0786,1443.5401 L 1067.0786,1430.3944 C 1067.0786,1428.9086 1066.9404,1427.7901 1066.6558,1427.0471 C 1066.3711,1426.3113 1065.8632,1425.7208 1065.1416,1425.2838 C 1064.4128,1424.8397 1063.5648,1424.6164 1062.5857,1424.6164 C 1061.0231,1424.6164 1059.6837,1425.1172 1058.5439,1426.1034 C 1057.4124,1427.0956 1056.8502,1428.9712 1056.8502,1431.742 L 1056.8502,1443.54 L 1053.19,1443.54 L 1053.19,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path113" />
-
-   <path
-   d="M 1084.36,1440.26 L 1084.8868,1443.4962 C 1083.8592,1443.7112 1082.9356,1443.8222 1082.123,1443.8222 C 1080.7907,1443.8222 1079.762,1443.6143 1079.0261,1443.1903 C 1078.2974,1442.7734 1077.7836,1442.2183 1077.4848,1441.5309 C 1077.186,1440.8505 1077.0336,1439.4061 1077.0336,1437.2116 L 1077.0336,1424.7805 L 1074.3454,1424.7805 L 1074.3454,1421.934 L 1077.0336,1421.934 L 1077.0336,1416.5801 L 1080.6785,1414.3856 L 1080.6785,1421.934 L 1084.36,1421.934 L 1084.36,1424.7805 L 1080.6785,1424.7805 L 1080.6785,1437.4124 C 1080.6785,1438.4612 1080.7411,1439.1285 1080.8663,1439.4262 C 1080.9986,1439.725 1081.2065,1439.9612 1081.4982,1440.1419 C 1081.7899,1440.3155 1082.2068,1440.4053 1082.749,1440.4053 C 1083.1576,1440.4053 1083.6927,1440.3569 1084.36,1440.26 L 1084.36,1440.26 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path115" />
-
-   <polygon
-   points="1098.09,1434.59 1098.09,1430.91 1109.35,1430.91 1109.35,1434.59 1098.09,1434.59 "
-   style="fill:#000000;fill-rule:nonzero"
-   id="polygon117" />
-
-   <path
-   d="M 1138.98,1443.54 L 1138.98,1440.8105 C 1137.6123,1442.9565 1135.5985,1444.0266 1132.9387,1444.0266 C 1131.2166,1444.0266 1129.6328,1443.5542 1128.1883,1442.6022 C 1126.7438,1441.6585 1125.6265,1440.3321 1124.828,1438.6231 C 1124.0355,1436.9223 1123.6398,1434.9711 1123.6398,1432.7553 C 1123.6398,1430.6022 1124.0013,1428.6439 1124.717,1426.8876 C 1125.4387,1425.1302 1126.5147,1423.7837 1127.9521,1422.853 C 1129.3906,1421.9152 1131.0017,1421.4427 1132.7792,1421.4427 C 1134.0773,1421.4427 1135.2371,1421.7215 1136.2505,1422.2695 C 1137.2721,1422.8187 1138.0977,1423.5333 1138.7367,1424.4156 L 1138.7367,1413.7148 L 1142.3757,1413.7148 L 1142.3757,1443.54 L 1138.98,1443.54 L 1138.98,1443.54 z M 1127.404,1432.7554 C 1127.404,1435.5263 1127.9875,1437.5956 1129.1544,1438.9633 C 1130.3201,1440.3322 1131.6961,1441.0196 1133.2859,1441.0196 C 1134.8827,1441.0196 1136.2445,1440.3593 1137.3619,1439.0542 C 1138.4804,1437.7479 1139.0426,1435.7483 1139.0426,1433.0613 C 1139.0426,1430.1027 1138.4733,1427.9365 1137.3347,1426.5546 C 1136.195,1425.1656 1134.793,1424.4782 1133.1194,1424.4782 C 1131.4942,1424.4782 1130.1335,1425.1444 1129.0434,1426.4708 C 1127.952,1427.7971 1127.404,1429.8948 1127.404,1432.7554 L 1127.404,1432.7554 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path119" />
-
-   <path
-   d="M 1148.16,1417.93 L 1148.16,1413.7158 L 1151.8261,1413.7158 L 1151.8261,1417.93 L 1148.16,1417.93 z M 1148.16,1443.541 L 1148.16,1421.9375 L 1151.8261,1421.9375 L 1151.8261,1443.541 L 1148.16,1443.541 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path121" />
-
-   <path
-   d="M 1158.27,1443.54 L 1158.27,1424.7829 L 1155.0409,1424.7829 L 1155.0409,1421.9364 L 1158.27,1421.9364 L 1158.27,1419.638 C 1158.27,1418.1864 1158.4023,1417.1034 1158.6586,1416.4018 C 1159.0129,1415.4498 1159.6318,1414.6797 1160.52,1414.0892 C 1161.4094,1413.4986 1162.6519,1413.2069 1164.2558,1413.2069 C 1165.2846,1413.2069 1166.4232,1413.325 1167.6728,1413.5754 L 1167.1247,1416.7703 C 1166.3676,1416.6309 1165.6448,1416.5612 1164.9645,1416.5612 C 1163.8531,1416.5612 1163.0688,1416.7975 1162.6106,1417.277 C 1162.1452,1417.7494 1161.9161,1418.6376 1161.9161,1419.9427 L 1161.9161,1421.9364 L 1166.1243,1421.9364 L 1166.1243,1424.7829 L 1161.9161,1424.7829 L 1161.9161,1443.54 L 1158.27,1443.54 L 1158.27,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path123" />
-
-   <path
-   d="M 1169.09,1443.54 L 1169.09,1424.7829 L 1165.8609,1424.7829 L 1165.8609,1421.9364 L 1169.09,1421.9364 L 1169.09,1419.638 C 1169.09,1418.1864 1169.2223,1417.1034 1169.4786,1416.4018 C 1169.8329,1415.4498 1170.4518,1414.6797 1171.34,1414.0892 C 1172.2294,1413.4986 1173.4719,1413.2069 1175.0758,1413.2069 C 1176.1046,1413.2069 1177.2432,1413.325 1178.4928,1413.5754 L 1177.9447,1416.7703 C 1177.1876,1416.6309 1176.4648,1416.5612 1175.7845,1416.5612 C 1174.6731,1416.5612 1173.8888,1416.7975 1173.4306,1417.277 C 1172.9652,1417.7494 1172.7361,1418.6376 1172.7361,1419.9427 L 1172.7361,1421.9364 L 1176.9443,1421.9364 L 1176.9443,1424.7829 L 1172.7361,1424.7829 L 1172.7361,1443.54 L 1169.09,1443.54 L 1169.09,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path125" />
-
-   <path
-   d="M 1194.59,1436.58 L 1198.3742,1437.0454 C 1197.7766,1439.2599 1196.6735,1440.9749 1195.0624,1442.1973 C 1193.4443,1443.4127 1191.3809,1444.0245 1188.8746,1444.0245 C 1185.7152,1444.0245 1183.2077,1443.0513 1181.3605,1441.1072 C 1179.5061,1439.1631 1178.5825,1436.4336 1178.5825,1432.9198 C 1178.5825,1429.2808 1179.5203,1426.4615 1181.3888,1424.4548 C 1183.2632,1422.4481 1185.6869,1421.4406 1188.6727,1421.4406 C 1191.5617,1421.4406 1193.9227,1422.4269 1195.7499,1424.3922 C 1197.5829,1426.3576 1198.4995,1429.1284 1198.4995,1432.6906 C 1198.4995,1432.9127 1198.4924,1433.2399 1198.4782,1433.6698 L 1182.368,1433.6698 C 1182.5003,1436.045 1183.1735,1437.8639 1184.3818,1439.1217 C 1185.5901,1440.3855 1187.0901,1441.0174 1188.896,1441.0174 C 1190.2353,1441.0174 1191.381,1440.6631 1192.333,1439.9544 C 1193.2837,1439.2529 1194.0338,1438.1284 1194.5901,1436.58 L 1194.59,1436.58 z M 1182.5687,1430.6568 L 1194.6313,1430.6568 C 1194.4719,1428.8438 1194.0065,1427.4761 1193.2494,1426.5725 C 1192.0825,1425.1635 1190.5695,1424.4548 1188.7152,1424.4548 C 1187.0344,1424.4548 1185.6171,1425.017 1184.4715,1426.1426 C 1183.3258,1427.267 1182.6939,1428.7741 1182.5687,1430.6568 L 1182.5687,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path127" />
-
-   <path
-   d="M 1202.93,1443.54 L 1202.93,1421.9365 L 1206.2217,1421.9365 L 1206.2217,1425.207 C 1207.0615,1423.6798 1207.8398,1422.6652 1208.5544,1422.1798 C 1209.2631,1421.6932 1210.0473,1421.4428 1210.9024,1421.4428 C 1212.1379,1421.4428 1213.3887,1421.8396 1214.6654,1422.6239 L 1213.4017,1426.0267 C 1212.5135,1425.4916 1211.617,1425.2282 1210.7217,1425.2282 C 1209.9162,1425.2282 1209.2005,1425.4715 1208.5615,1425.9499 C 1207.9225,1426.4365 1207.4713,1427.1026 1207.2009,1427.9566 C 1206.791,1429.2558 1206.5902,1430.679 1206.5902,1432.2274 L 1206.5902,1443.54 L 1202.93,1443.54 L 1202.93,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path129" />
-
-   <path
-   d="M 1231.63,1436.58 L 1235.4143,1437.0454 C 1234.8166,1439.2599 1233.7135,1440.9749 1232.1024,1442.1973 C 1230.4843,1443.4127 1228.4209,1444.0245 1225.9146,1444.0245 C 1222.7552,1444.0245 1220.2477,1443.0513 1218.4005,1441.1072 C 1216.5461,1439.1631 1215.6225,1436.4336 1215.6225,1432.9198 C 1215.6225,1429.2808 1216.5603,1426.4615 1218.4288,1424.4548 C 1220.3032,1422.4481 1222.7269,1421.4406 1225.7127,1421.4406 C 1228.6017,1421.4406 1230.9627,1422.4269 1232.7899,1424.3922 C 1234.6229,1426.3576 1235.5395,1429.1284 1235.5395,1432.6906 C 1235.5395,1432.9127 1235.5324,1433.2399 1235.5182,1433.6698 L 1219.408,1433.6698 C 1219.5403,1436.045 1220.2135,1437.8639 1221.4218,1439.1217 C 1222.6301,1440.3855 1224.1301,1441.0174 1225.936,1441.0174 C 1227.2753,1441.0174 1228.421,1440.6631 1229.373,1439.9544 C 1230.3237,1439.2529 1231.0738,1438.1284 1231.6301,1436.58 L 1231.63,1436.58 z M 1219.6087,1430.6568 L 1231.6713,1430.6568 C 1231.5119,1428.8438 1231.0465,1427.4761 1230.2894,1426.5725 C 1229.1225,1425.1635 1227.6095,1424.4548 1225.7552,1424.4548 C 1224.0744,1424.4548 1222.6571,1425.017 1221.5115,1426.1426 C 1220.3658,1427.267 1219.7339,1428.7741 1219.6087,1430.6568 L 1219.6087,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path131" />
-
-   <path
-   d="M 1240.02,1443.54 L 1240.02,1421.9365 L 1243.3117,1421.9365 L 1243.3117,1425.0062 C 1244.9027,1422.631 1247.194,1421.4428 1250.1869,1421.4428 C 1251.492,1421.4428 1252.6861,1421.679 1253.7775,1422.1444 C 1254.8747,1422.6168 1255.6861,1423.2274 1256.2283,1423.9916 C 1256.7775,1424.7487 1257.1519,1425.6511 1257.3739,1426.6928 C 1257.5062,1427.3743 1257.5759,1428.5613 1257.5759,1430.2562 L 1257.5759,1443.5401 L 1253.9086,1443.5401 L 1253.9086,1430.3944 C 1253.9086,1428.9086 1253.7704,1427.7901 1253.4858,1427.0471 C 1253.2011,1426.3113 1252.6932,1425.7208 1251.9716,1425.2838 C 1251.2428,1424.8397 1250.3948,1424.6164 1249.4157,1424.6164 C 1247.8531,1424.6164 1246.5137,1425.1172 1245.3739,1426.1034 C 1244.2424,1427.0956 1243.6802,1428.9712 1243.6802,1431.742 L 1243.6802,1443.54 L 1240.02,1443.54 L 1240.02,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path133" />
-
-   <path
-   d="M 1271.19,1440.26 L 1271.7168,1443.4962 C 1270.6892,1443.7112 1269.7656,1443.8222 1268.953,1443.8222 C 1267.6207,1443.8222 1266.592,1443.6143 1265.8561,1443.1903 C 1265.1274,1442.7734 1264.6136,1442.2183 1264.3148,1441.5309 C 1264.016,1440.8505 1263.8636,1439.4061 1263.8636,1437.2116 L 1263.8636,1424.7805 L 1261.1754,1424.7805 L 1261.1754,1421.934 L 1263.8636,1421.934 L 1263.8636,1416.5801 L 1267.5085,1414.3856 L 1267.5085,1421.934 L 1271.19,1421.934 L 1271.19,1424.7805 L 1267.5085,1424.7805 L 1267.5085,1437.4124 C 1267.5085,1438.4612 1267.5711,1439.1285 1267.6963,1439.4262 C 1267.8286,1439.725 1268.0365,1439.9612 1268.3282,1440.1419 C 1268.6199,1440.3155 1269.0368,1440.4053 1269.579,1440.4053 C 1269.9876,1440.4053 1270.5227,1440.3569 1271.19,1440.26 L 1271.19,1440.26 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path135" />
-
-   <path
-   d="M 1300.45,1435.63 L 1304.0465,1436.1024 C 1303.6579,1438.5816 1302.6504,1440.5257 1301.0264,1441.9288 C 1299.4083,1443.332 1297.4146,1444.0335 1295.0536,1444.0335 C 1292.1032,1444.0335 1289.7209,1443.0674 1287.9291,1441.1375 C 1286.1303,1439.2064 1285.228,1436.4355 1285.228,1432.8249 C 1285.228,1430.4922 1285.6165,1428.4501 1286.3878,1426.6997 C 1287.165,1424.9505 1288.339,1423.6371 1289.9217,1422.7631 C 1291.4984,1421.8879 1293.2205,1421.4497 1295.0748,1421.4497 C 1297.4217,1421.4497 1299.3457,1422.0473 1300.8315,1423.2343 C 1302.3244,1424.4225 1303.2835,1426.1032 1303.7063,1428.2906 L 1300.1441,1428.8387 C 1299.8039,1427.3871 1299.2063,1426.2969 1298.3453,1425.5611 C 1297.4843,1424.8324 1296.4425,1424.4639 1295.2201,1424.4639 C 1293.3728,1424.4639 1291.8728,1425.1241 1290.7201,1426.4505 C 1289.5673,1427.7698 1288.991,1429.8603 1288.991,1432.7209 C 1288.991,1435.6229 1289.5472,1437.7347 1290.6646,1439.054 C 1291.776,1440.3662 1293.2276,1441.0265 1295.0193,1441.0265 C 1296.4567,1441.0265 1297.6508,1440.5812 1298.6158,1439.7001 C 1299.5819,1438.8178 1300.1925,1437.4642 1300.45,1435.63 L 1300.45,1435.63 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path137" />
-
-   <path
-   d="M 1321.34,1443.54 L 1321.34,1440.3664 C 1319.6522,1442.8113 1317.3679,1444.0266 1314.479,1444.0266 C 1313.2081,1444.0266 1312.0128,1443.7833 1310.9097,1443.2967 C 1309.8054,1442.8113 1308.9857,1442.1924 1308.4506,1441.4565 C 1307.9097,1440.7136 1307.5341,1439.8113 1307.3191,1438.7412 C 1307.1727,1438.0195 1307.0971,1436.8809 1307.0971,1435.3184 L 1307.0971,1421.9365 L 1310.7561,1421.9365 L 1310.7561,1433.9152 C 1310.7561,1435.8321 1310.8329,1437.1159 1310.9782,1437.7833 C 1311.2144,1438.7482 1311.701,1439.4982 1312.4439,1440.0533 C 1313.1939,1440.6026 1314.1176,1440.873 1315.2148,1440.873 C 1316.3121,1440.873 1317.3396,1440.5955 1318.3046,1440.0333 C 1319.2695,1439.4711 1319.951,1438.6998 1320.3467,1437.7348 C 1320.7495,1436.7628 1320.9502,1435.3526 1320.9502,1433.5124 L 1320.9502,1421.9364 L 1324.6105,1421.9364 L 1324.6105,1443.5399 L 1321.34,1443.5399 L 1321.34,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path139" />
-
-   <path
-   d="M 1330.31,1443.54 L 1330.31,1421.9365 L 1333.6017,1421.9365 L 1333.6017,1425.207 C 1334.4415,1423.6798 1335.2198,1422.6652 1335.9344,1422.1798 C 1336.6431,1421.6932 1337.4273,1421.4428 1338.2824,1421.4428 C 1339.5179,1421.4428 1340.7687,1421.8396 1342.0454,1422.6239 L 1340.7816,1426.0267 C 1339.8935,1425.4916 1338.997,1425.2282 1338.1017,1425.2282 C 1337.2962,1425.2282 1336.5805,1425.4715 1335.9415,1425.9499 C 1335.3025,1426.4365 1334.8513,1427.1026 1334.5809,1427.9566 C 1334.171,1429.2558 1333.9702,1430.679 1333.9702,1432.2274 L 1333.9702,1443.54 L 1330.31,1443.54 L 1330.31,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path141" />
-
-   <path
-   d="M 1350.23,1443.54 L 1342.0084,1421.9365 L 1345.8765,1421.9365 L 1350.5146,1434.8731 C 1351.0154,1436.2692 1351.4737,1437.7207 1351.8965,1439.2278 C 1352.2237,1438.0892 1352.6749,1436.7203 1353.2584,1435.1164 L 1358.0631,1421.9365 L 1361.8272,1421.9365 L 1353.6469,1443.54 L 1350.23,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path143" />
-
-   <path
-   d="M 1379.85,1436.58 L 1383.6342,1437.0454 C 1383.0366,1439.2599 1381.9335,1440.9749 1380.3224,1442.1973 C 1378.7043,1443.4127 1376.6409,1444.0245 1374.1346,1444.0245 C 1370.9752,1444.0245 1368.4677,1443.0513 1366.6205,1441.1072 C 1364.7661,1439.1631 1363.8425,1436.4336 1363.8425,1432.9198 C 1363.8425,1429.2808 1364.7803,1426.4615 1366.6488,1424.4548 C 1368.5232,1422.4481 1370.9469,1421.4406 1373.9327,1421.4406 C 1376.8217,1421.4406 1379.1827,1422.4269 1381.0099,1424.3922 C 1382.8429,1426.3576 1383.7595,1429.1284 1383.7595,1432.6906 C 1383.7595,1432.9127 1383.7524,1433.2399 1383.7382,1433.6698 L 1367.628,1433.6698 C 1367.7603,1436.045 1368.4335,1437.8639 1369.6418,1439.1217 C 1370.8501,1440.3855 1372.3501,1441.0174 1374.156,1441.0174 C 1375.4953,1441.0174 1376.641,1440.6631 1377.593,1439.9544 C 1378.5437,1439.2529 1379.2938,1438.1284 1379.8501,1436.58 L 1379.85,1436.58 z M 1367.8287,1430.6568 L 1379.8913,1430.6568 C 1379.7319,1428.8438 1379.2665,1427.4761 1378.5094,1426.5725 C 1377.3425,1425.1635 1375.8295,1424.4548 1373.9752,1424.4548 C 1372.2944,1424.4548 1370.8771,1425.017 1369.7315,1426.1426 C 1368.5858,1427.267 1367.9539,1428.7741 1367.8287,1430.6568 L 1367.8287,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path145" />
-
-   <path
-   d="M 1386.77,1437.09 L 1390.3877,1436.5207 C 1390.5885,1437.9723 1391.159,1439.0825 1392.0885,1439.8609 C 1393.0121,1440.6309 1394.3113,1441.0207 1395.985,1441.0207 C 1397.6657,1441.0207 1398.9153,1440.6735 1399.7279,1439.9931 C 1400.5405,1439.3057 1400.9503,1438.4991 1400.9503,1437.5825 C 1400.9503,1436.7498 1400.5889,1436.1038 1399.8661,1435.6242 C 1399.3665,1435.2983 1398.1169,1434.8884 1396.1232,1434.3888 C 1393.4432,1433.7085 1391.5747,1433.125 1390.5401,1432.6242 C 1389.5054,1432.1317 1388.7141,1431.4443 1388.1791,1430.5691 C 1387.6452,1429.6939 1387.3736,1428.729 1387.3736,1427.6731 C 1387.3736,1426.7081 1387.5956,1425.8199 1388.0409,1425.0002 C 1388.4779,1424.1735 1389.0826,1423.4931 1389.8385,1422.951 C 1390.409,1422.5353 1391.1862,1422.1739 1392.1653,1421.8821 C 1393.1515,1421.5904 1394.2074,1421.4439 1395.3318,1421.4439 C 1397.0267,1421.4439 1398.5125,1421.6943 1399.7976,1422.1809 C 1401.0814,1422.6664 1402.0263,1423.3266 1402.637,1424.1593 C 1403.2488,1425.0002 1403.6657,1426.1105 1403.8948,1427.5065 L 1400.3184,1428.0002 C 1400.1519,1426.8888 1399.6795,1426.0207 1398.9011,1425.3959 C 1398.124,1424.7711 1397.0196,1424.4581 1395.5964,1424.4581 C 1393.9157,1424.4581 1392.7145,1424.7357 1391.9988,1425.292 C 1391.2771,1425.8471 1390.9157,1426.5002 1390.9157,1427.2432 C 1390.9157,1427.7215 1391.0681,1428.1455 1391.3669,1428.5282 C 1391.6657,1428.9239 1392.131,1429.2428 1392.77,1429.5073 C 1393.1373,1429.6384 1394.2145,1429.9514 1396.0051,1430.4369 C 1398.5952,1431.1313 1400.4011,1431.6947 1401.4216,1432.1388 C 1402.4503,1432.5758 1403.2559,1433.2219 1403.8393,1434.0617 C 1404.4216,1434.9026 1404.7133,1435.9443 1404.7133,1437.1939 C 1404.7133,1438.4164 1404.3531,1439.562 1403.6444,1440.6451 C 1402.9287,1441.7223 1401.9011,1442.555 1400.5606,1443.1455 C 1399.2212,1443.7361 1397.6999,1444.0278 1396.0051,1444.0278 C 1393.1929,1444.0278 1391.0539,1443.4443 1389.5822,1442.2774 C 1388.1094,1441.1105 1387.1728,1439.3813 1386.77,1437.09 L 1386.77,1437.09 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path147" />
-
-   <path
-   d="M 1410.02,1443.54 L 1410.02,1439.366 L 1414.1928,1439.366 L 1414.1928,1443.54 C 1414.1928,1445.0742 1413.9224,1446.3109 1413.3802,1447.2558 C 1412.8322,1448.1924 1411.9712,1448.9223 1410.7972,1449.4432 L 1409.7767,1447.8735 C 1410.548,1447.5333 1411.1172,1447.0325 1411.4846,1446.3806 C 1411.8531,1445.7203 1412.0539,1444.7766 1412.0964,1443.54 L 1410.02,1443.54 L 1410.02,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path149" />
-
-   <path
-   d="M 1430.75,1437.09 L 1434.3677,1436.5207 C 1434.5685,1437.9723 1435.139,1439.0825 1436.0685,1439.8609 C 1436.9921,1440.6309 1438.2913,1441.0207 1439.965,1441.0207 C 1441.6457,1441.0207 1442.8953,1440.6735 1443.7079,1439.9931 C 1444.5205,1439.3057 1444.9303,1438.4991 1444.9303,1437.5825 C 1444.9303,1436.7498 1444.5689,1436.1038 1443.8461,1435.6242 C 1443.3465,1435.2983 1442.0969,1434.8884 1440.1032,1434.3888 C 1437.4232,1433.7085 1435.5547,1433.125 1434.5201,1432.6242 C 1433.4854,1432.1317 1432.6941,1431.4443 1432.1591,1430.5691 C 1431.6252,1429.6939 1431.3536,1428.729 1431.3536,1427.6731 C 1431.3536,1426.7081 1431.5756,1425.8199 1432.0209,1425.0002 C 1432.4579,1424.1735 1433.0626,1423.4931 1433.8185,1422.951 C 1434.389,1422.5353 1435.1662,1422.1739 1436.1453,1421.8821 C 1437.1315,1421.5904 1438.1874,1421.4439 1439.3118,1421.4439 C 1441.0067,1421.4439 1442.4925,1421.6943 1443.7776,1422.1809 C 1445.0614,1422.6664 1446.0063,1423.3266 1446.617,1424.1593 C 1447.2288,1425.0002 1447.6457,1426.1105 1447.8748,1427.5065 L 1444.2984,1428.0002 C 1444.1319,1426.8888 1443.6595,1426.0207 1442.8811,1425.3959 C 1442.104,1424.7711 1440.9996,1424.4581 1439.5764,1424.4581 C 1437.8957,1424.4581 1436.6945,1424.7357 1435.9788,1425.292 C 1435.2571,1425.8471 1434.8957,1426.5002 1434.8957,1427.2432 C 1434.8957,1427.7215 1435.0481,1428.1455 1435.3469,1428.5282 C 1435.6457,1428.9239 1436.111,1429.2428 1436.75,1429.5073 C 1437.1173,1429.6384 1438.1945,1429.9514 1439.9851,1430.4369 C 1442.5752,1431.1313 1444.3811,1431.6947 1445.4016,1432.1388 C 1446.4303,1432.5758 1447.2359,1433.2219 1447.8193,1434.0617 C 1448.4016,1434.9026 1448.6933,1435.9443 1448.6933,1437.1939 C 1448.6933,1438.4164 1448.3331,1439.562 1447.6244,1440.6451 C 1446.9087,1441.7223 1445.8811,1442.555 1444.5406,1443.1455 C 1443.2012,1443.7361 1441.6799,1444.0278 1439.9851,1444.0278 C 1437.1729,1444.0278 1435.0339,1443.4443 1433.5622,1442.2774 C 1432.0894,1441.1105 1431.1528,1439.3813 1430.75,1437.09 L 1430.75,1437.09 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path151" />
-
-   <path
-   d="M 1453.05,1451.82 L 1453.05,1421.9393 L 1456.3831,1421.9393 L 1456.3831,1424.7444 C 1457.1685,1423.6472 1458.0567,1422.8216 1459.05,1422.2724 C 1460.0362,1421.7243 1461.2374,1421.4456 1462.6476,1421.4456 C 1464.4949,1421.4456 1466.1201,1421.9251 1467.5291,1422.87 C 1468.9453,1423.8208 1470.0083,1425.1613 1470.724,1426.8905 C 1471.4457,1428.6196 1471.8071,1430.5153 1471.8071,1432.5775 C 1471.8071,1434.7861 1471.4114,1436.7787 1470.613,1438.5503 C 1469.8205,1440.3208 1468.6677,1441.6743 1467.1547,1442.6192 C 1465.6406,1443.557 1464.0496,1444.0295 1462.3831,1444.0295 C 1461.1618,1444.0295 1460.0705,1443.772 1459.0984,1443.2582 C 1458.1264,1442.7444 1457.335,1442.0913 1456.7102,1441.307 L 1456.7102,1451.82 L 1453.05,1451.82 L 1453.05,1451.82 z M 1456.363,1432.8621 C 1456.363,1435.64 1456.9252,1437.6952 1458.0508,1439.0286 C 1459.1752,1440.355 1460.5429,1441.0223 1462.1409,1441.0223 C 1463.765,1441.0223 1465.161,1440.3349 1466.3209,1438.953 C 1467.4807,1437.5782 1468.0642,1435.4464 1468.0642,1432.5574 C 1468.0642,1429.7995 1467.4949,1427.7444 1466.3622,1426.3696 C 1465.2307,1425.0019 1463.876,1424.3145 1462.3075,1424.3145 C 1460.7449,1424.3145 1459.363,1425.0432 1458.1618,1426.5019 C 1456.9595,1427.9593 1456.363,1430.0853 1456.363,1432.8621 L 1456.363,1432.8621 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path153" />
-
-   <path
-   d="M 1490.32,1440.88 C 1488.9582,1442.0328 1487.6531,1442.8454 1486.4035,1443.3249 C 1485.1456,1443.7973 1483.7991,1444.0335 1482.3617,1444.0335 C 1479.9865,1444.0335 1478.1676,1443.4572 1476.8897,1442.2973 C 1475.6188,1441.1375 1474.9798,1439.6517 1474.9798,1437.8528 C 1474.9798,1436.7898 1475.2161,1435.8249 1475.7015,1434.9497 C 1476.181,1434.0745 1476.8129,1433.3741 1477.5913,1432.8461 C 1478.3755,1432.3182 1479.2507,1431.9154 1480.2298,1431.645 C 1480.9444,1431.4572 1482.0287,1431.2694 1483.479,1431.0957 C 1486.4377,1430.7414 1488.618,1430.3245 1490.0141,1429.832 C 1490.0283,1429.3324 1490.0353,1429.0123 1490.0353,1428.88 C 1490.0353,1427.3871 1489.6881,1426.3324 1488.9936,1425.7276 C 1488.0629,1424.895 1486.6668,1424.4851 1484.8267,1424.4851 C 1483.1046,1424.4851 1481.8338,1424.7839 1481.007,1425.3875 C 1480.1873,1425.9922 1479.5838,1427.0611 1479.1881,1428.5954 L 1475.6117,1428.1028 C 1475.9377,1426.5757 1476.4727,1425.332 1477.2157,1424.3942 C 1477.9586,1423.4505 1479.0416,1422.7206 1480.4519,1422.2139 C 1481.8609,1421.7072 1483.4932,1421.4497 1485.3546,1421.4497 C 1487.2019,1421.4497 1488.6948,1421.6729 1489.8475,1422.1028 C 1491.0003,1422.541 1491.8472,1423.082 1492.3964,1423.7422 C 1492.9373,1424.4013 1493.3129,1425.228 1493.5349,1426.2343 C 1493.6531,1426.8603 1493.7157,1427.9847 1493.7157,1429.6099 L 1493.7157,1434.4914 C 1493.7157,1437.9013 1493.7912,1440.0544 1493.9519,1440.9497 C 1494.1042,1441.8521 1494.4172,1442.7202 1494.8755,1443.5469 L 1491.0487,1443.5469 C 1490.6743,1442.7899 1490.4239,1441.9017 1490.32,1440.88 L 1490.32,1440.88 z M 1490.0141,1432.6997 C 1488.6806,1433.2489 1486.6881,1433.7072 1484.0354,1434.0887 C 1482.5283,1434.3036 1481.4582,1434.5469 1480.8405,1434.8174 C 1480.2157,1435.0891 1479.7291,1435.4847 1479.396,1436.0127 C 1479.0558,1436.5336 1478.8822,1437.1099 1478.8822,1437.7489 C 1478.8822,1438.728 1479.2578,1439.5406 1479.9936,1440.1926 C 1480.7295,1440.8387 1481.8125,1441.1647 1483.2369,1441.1647 C 1484.646,1441.1647 1485.9027,1440.8599 1486.9999,1440.241 C 1488.0972,1439.6233 1488.9098,1438.7765 1489.4235,1437.7064 C 1489.8192,1436.8808 1490.0141,1435.6584 1490.0141,1434.0473 L 1490.0141,1432.6997 L 1490.0141,1432.6997 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path155" />
-
-   <path
-   d="M 1513.49,1435.63 L 1517.0865,1436.1024 C 1516.6979,1438.5816 1515.6904,1440.5257 1514.0664,1441.9288 C 1512.4483,1443.332 1510.4546,1444.0335 1508.0936,1444.0335 C 1505.1432,1444.0335 1502.7609,1443.0674 1500.9691,1441.1375 C 1499.1703,1439.2064 1498.268,1436.4355 1498.268,1432.8249 C 1498.268,1430.4922 1498.6565,1428.4501 1499.4278,1426.6997 C 1500.205,1424.9505 1501.379,1423.6371 1502.9617,1422.7631 C 1504.5384,1421.8879 1506.2605,1421.4497 1508.1148,1421.4497 C 1510.4617,1421.4497 1512.3857,1422.0473 1513.8715,1423.2343 C 1515.3644,1424.4225 1516.3235,1426.1032 1516.7463,1428.2906 L 1513.1841,1428.8387 C 1512.8439,1427.3871 1512.2463,1426.2969 1511.3853,1425.5611 C 1510.5243,1424.8324 1509.4825,1424.4639 1508.2601,1424.4639 C 1506.4128,1424.4639 1504.9128,1425.1241 1503.7601,1426.4505 C 1502.6073,1427.7698 1502.031,1429.8603 1502.031,1432.7209 C 1502.031,1435.6229 1502.5872,1437.7347 1503.7046,1439.054 C 1504.816,1440.3662 1506.2676,1441.0265 1508.0593,1441.0265 C 1509.4967,1441.0265 1510.6908,1440.5812 1511.6558,1439.7001 C 1512.6219,1438.8178 1513.2325,1437.4642 1513.49,1435.63 L 1513.49,1435.63 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path157" />
-
-   <path
-   d="M 1520.24,1417.93 L 1520.24,1413.7158 L 1523.9061,1413.7158 L 1523.9061,1417.93 L 1520.24,1417.93 z M 1520.24,1443.541 L 1520.24,1421.9375 L 1523.9061,1421.9375 L 1523.9061,1443.541 L 1520.24,1443.541 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path159" />
-
-   <path
-   d="M 1529.49,1443.54 L 1529.49,1421.9365 L 1532.7817,1421.9365 L 1532.7817,1425.0062 C 1534.3727,1422.631 1536.664,1421.4428 1539.6569,1421.4428 C 1540.962,1421.4428 1542.1561,1421.679 1543.2475,1422.1444 C 1544.3447,1422.6168 1545.1561,1423.2274 1545.6983,1423.9916 C 1546.2475,1424.7487 1546.6219,1425.6511 1546.8439,1426.6928 C 1546.9762,1427.3743 1547.0459,1428.5613 1547.0459,1430.2562 L 1547.0459,1443.5401 L 1543.3786,1443.5401 L 1543.3786,1430.3944 C 1543.3786,1428.9086 1543.2404,1427.7901 1542.9558,1427.0471 C 1542.6711,1426.3113 1542.1632,1425.7208 1541.4416,1425.2838 C 1540.7128,1424.8397 1539.8648,1424.6164 1538.8857,1424.6164 C 1537.3231,1424.6164 1535.9837,1425.1172 1534.8439,1426.1034 C 1533.7124,1427.0956 1533.1502,1428.9712 1533.1502,1431.742 L 1533.1502,1443.54 L 1529.49,1443.54 L 1529.49,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path161" />
-
-   <path
-   d="M 1551.99,1445.33 L 1555.5522,1445.858 C 1555.6987,1446.9552 1556.1144,1447.7536 1556.7888,1448.2603 C 1557.6983,1448.9335 1558.9408,1449.2737 1560.5105,1449.2737 C 1562.2124,1449.2737 1563.5176,1448.9335 1564.4412,1448.2603 C 1565.3648,1447.58 1565.9825,1446.628 1566.3085,1445.4127 C 1566.5034,1444.6627 1566.5872,1443.1013 1566.5731,1440.7119 C 1564.9762,1442.5934 1562.9825,1443.5383 1560.5943,1443.5383 C 1557.6215,1443.5383 1555.3231,1442.4694 1553.6979,1440.3233 C 1552.0738,1438.1843 1551.2542,1435.6083 1551.2542,1432.6154 C 1551.2542,1430.552 1551.6286,1428.6493 1552.3715,1426.9072 C 1553.1215,1425.1639 1554.2057,1423.8162 1555.6219,1422.8654 C 1557.038,1421.9206 1558.7045,1421.441 1560.6144,1421.441 C 1563.1632,1421.441 1565.2679,1422.4757 1566.9203,1424.5391 L 1566.9203,1421.9347 L 1570.3018,1421.9347 L 1570.3018,1440.6079 C 1570.3018,1443.9693 1569.9546,1446.3575 1569.2742,1447.7607 C 1568.5868,1449.1627 1567.5038,1450.2741 1566.0179,1451.0867 C 1564.5309,1451.8993 1562.7049,1452.3091 1560.5317,1452.3091 C 1557.9545,1452.3091 1555.8723,1451.7256 1554.2884,1450.5658 C 1552.6986,1449.406 1551.9345,1447.6626 1551.99,1445.33 L 1551.99,1445.33 z M 1555.0172,1432.3509 C 1555.0172,1435.1844 1555.5806,1437.2537 1556.7121,1438.5529 C 1557.8376,1439.858 1559.2467,1440.5041 1560.9416,1440.5041 C 1562.6211,1440.5041 1564.0313,1439.858 1565.1699,1438.5659 C 1566.3085,1437.2678 1566.879,1435.2399 1566.879,1432.469 C 1566.879,1429.8233 1566.2955,1427.8308 1565.1215,1426.4903 C 1563.9475,1425.1497 1562.5314,1424.4765 1560.879,1424.4765 C 1559.2538,1424.4765 1557.8719,1425.1355 1556.7262,1426.4619 C 1555.5877,1427.7812 1555.0172,1429.7466 1555.0172,1432.3509 L 1555.0172,1432.3509 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path163" />
-
-   <path
-   d="M 1576.78,1443.54 L 1576.78,1439.366 L 1580.9528,1439.366 L 1580.9528,1443.54 C 1580.9528,1445.0742 1580.6824,1446.3109 1580.1402,1447.2558 C 1579.5922,1448.1924 1578.7312,1448.9223 1577.5572,1449.4432 L 1576.5367,1447.8735 C 1577.308,1447.5333 1577.8772,1447.0325 1578.2446,1446.3806 C 1578.6131,1445.7203 1578.8139,1444.7766 1578.8564,1443.54 L 1576.78,1443.54 L 1576.78,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path165" />
-
-   <path
-   d="M 669.775,1440.26 L 670.30177,1443.4962 C 669.27421,1443.7112 668.35059,1443.8222 667.53799,1443.8222 C 666.20571,1443.8222 665.17697,1443.6143 664.44114,1443.1903 C 663.7124,1442.7734 663.19862,1442.2183 662.8998,1441.5309 C 662.60098,1440.8505 662.44862,1439.4061 662.44862,1437.2116 L 662.44862,1424.7805 L 659.76043,1424.7805 L 659.76043,1421.934 L 662.44862,1421.934 L 662.44862,1416.5801 L 666.0935,1414.3856 L 666.0935,1421.934 L 669.775,1421.934 L 669.775,1424.7805 L 666.0935,1424.7805 L 666.0935,1437.4124 C 666.0935,1438.4612 666.1561,1439.1285 666.2813,1439.4262 C 666.41358,1439.725 666.62145,1439.9612 666.91319,1440.1419 C 667.20492,1440.3155 667.62185,1440.4053 668.16398,1440.4053 C 668.57264,1440.4053 669.10768,1440.3569 669.775,1440.26 L 669.775,1440.26 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path167" />
-
-   <path
-   d="M 673.357,1443.54 L 673.357,1413.7148 L 677.01724,1413.7148 L 677.01724,1424.4156 C 678.72511,1422.4361 680.88535,1421.4428 683.4885,1421.4428 C 685.08653,1421.4428 686.47551,1421.7628 687.65543,1422.3947 C 688.83653,1423.0195 689.68338,1423.8947 690.19008,1425.0062 C 690.69677,1426.1164 690.95425,1427.7345 690.95425,1429.8463 L 690.95425,1443.54 L 687.28811,1443.54 L 687.28811,1429.8463 C 687.28811,1428.0191 686.89126,1426.6857 686.09992,1425.853 C 685.30858,1425.0192 684.18299,1424.5963 682.7326,1424.5963 C 681.64835,1424.5963 680.62788,1424.881 679.67,1425.4432 C 678.71095,1426.0054 678.03063,1426.7695 677.62787,1427.7345 C 677.21803,1428.6936 677.01724,1430.0258 677.01724,1431.7207 L 677.01724,1443.54 L 673.357,1443.54 L 673.357,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path169" />
-
-   <path
-   d="M 711.315,1436.58 L 715.09925,1437.0454 C 714.50161,1439.2599 713.39846,1440.9749 711.78744,1442.1973 C 710.16933,1443.4127 708.10594,1444.0245 705.59964,1444.0245 C 702.44019,1444.0245 699.93271,1443.0513 698.08547,1441.1072 C 696.23114,1439.1631 695.30752,1436.4336 695.30752,1432.9198 C 695.30752,1429.2808 696.24532,1426.4615 698.11382,1424.4548 C 699.98823,1422.4481 702.41185,1421.4406 705.39768,1421.4406 C 708.28666,1421.4406 710.64768,1422.4269 712.47485,1424.3922 C 714.30792,1426.3576 715.22446,1429.1284 715.22446,1432.6906 C 715.22446,1432.9127 715.21737,1433.2399 715.2032,1433.6698 L 699.093,1433.6698 C 699.22528,1436.045 699.89851,1437.8639 701.10678,1439.1217 C 702.31505,1440.3855 703.81505,1441.0174 705.62095,1441.0174 C 706.96032,1441.0174 708.10599,1440.6631 709.05796,1439.9544 C 710.00875,1439.2529 710.75875,1438.1284 711.31505,1436.58 L 711.315,1436.58 z M 699.2937,1430.6568 L 711.3563,1430.6568 C 711.19685,1428.8438 710.7315,1427.4761 709.97441,1426.5725 C 708.80748,1425.1635 707.29449,1424.4548 705.44016,1424.4548 C 703.75945,1424.4548 702.34213,1425.017 701.19646,1426.1426 C 700.05079,1427.267 699.4189,1428.7741 699.2937,1430.6568 L 699.2937,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path171" />
-
-   <path
-   d="M 735.266,1443.54 L 728.65537,1421.9365 L 732.43962,1421.9365 L 735.87781,1434.4078 L 737.15458,1439.0472 C 737.21009,1438.811 737.58568,1437.3251 738.27308,1434.5885 L 741.71009,1421.9365 L 745.47426,1421.9365 L 748.71048,1434.4633 L 749.79355,1438.596 L 751.03016,1434.422 L 754.73055,1421.9366 L 758.29394,1421.9366 L 751.53685,1443.5401 L 747.73842,1443.5401 L 744.30023,1430.6023 L 743.46047,1426.9149 L 739.09275,1443.5401 L 735.26598,1443.5401 L 735.266,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path173" />
-
-   <path
-   d="M 776.154,1436.58 L 779.93825,1437.0454 C 779.34061,1439.2599 778.23746,1440.9749 776.62644,1442.1973 C 775.00833,1443.4127 772.94494,1444.0245 770.43864,1444.0245 C 767.27919,1444.0245 764.77171,1443.0513 762.92447,1441.1072 C 761.07014,1439.1631 760.14652,1436.4336 760.14652,1432.9198 C 760.14652,1429.2808 761.08431,1426.4615 762.95282,1424.4548 C 764.82723,1422.4481 767.25085,1421.4406 770.23668,1421.4406 C 773.12566,1421.4406 775.48668,1422.4269 777.31385,1424.3922 C 779.14692,1426.3576 780.06346,1429.1284 780.06346,1432.6906 C 780.06346,1432.9127 780.05637,1433.2399 780.0422,1433.6698 L 763.932,1433.6698 C 764.06428,1436.045 764.73751,1437.8639 765.94578,1439.1217 C 767.15405,1440.3855 768.65405,1441.0174 770.45995,1441.0174 C 771.79932,1441.0174 772.94499,1440.6631 773.89696,1439.9544 C 774.84775,1439.2529 775.59775,1438.1284 776.15405,1436.58 L 776.154,1436.58 z M 764.1327,1430.6568 L 776.1953,1430.6568 C 776.03585,1428.8438 775.5705,1427.4761 774.81341,1426.5725 C 773.64648,1425.1635 772.13349,1424.4548 770.27916,1424.4548 C 768.59845,1424.4548 767.18113,1425.017 766.03546,1426.1426 C 764.88979,1427.267 764.2579,1428.7741 764.1327,1430.6568 L 764.1327,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path175" />
-
-   <path
-   d="M 787.918,1443.54 L 784.52233,1443.54 L 784.52233,1413.7148 L 788.18139,1413.7148 L 788.18139,1424.353 C 789.72982,1422.416 791.70226,1421.4428 794.09753,1421.4428 C 795.43099,1421.4428 796.68887,1421.7144 797.87588,1422.2483 C 799.06289,1422.7833 800.03494,1423.5404 800.80619,1424.5054 C 801.57036,1425.4774 802.17391,1426.6443 802.60501,1428.0191 C 803.04202,1429.388 803.25816,1430.8526 803.25816,1432.4081 C 803.25816,1436.1168 802.34044,1438.9774 800.50737,1440.9983 C 798.68139,1443.0192 796.47981,1444.0266 793.918,1444.0266 C 791.36918,1444.0266 789.36957,1442.9636 787.918,1440.8318 L 787.918,1443.54 L 787.918,1443.54 z M 787.87548,1432.5746 C 787.87548,1435.1648 788.22981,1437.0333 788.93139,1438.186 C 790.08415,1440.0746 791.64674,1441.0195 793.6121,1441.0195 C 795.21604,1441.0195 796.59793,1440.325 797.76486,1438.9289 C 798.93179,1437.54 799.51407,1435.4707 799.51407,1432.714 C 799.51407,1429.8947 798.95187,1427.8112 797.83454,1426.4707 C 796.71604,1425.1301 795.36249,1424.4569 793.77863,1424.4569 C 792.17469,1424.4569 790.7928,1425.1514 789.62587,1426.5403 C 788.45894,1427.9293 787.87548,1429.9431 787.87548,1432.5746 L 787.87548,1432.5746 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path177" />
-
-   <path
-   d="M 817.827,1437.09 L 821.44472,1436.5207 C 821.64551,1437.9723 822.21598,1439.0825 823.14551,1439.8609 C 824.06913,1440.6309 825.36834,1441.0207 827.04197,1441.0207 C 828.72268,1441.0207 829.97228,1440.6735 830.78488,1439.9931 C 831.59748,1439.3057 832.00732,1438.4991 832.00732,1437.5825 C 832.00732,1436.7498 831.6459,1436.1038 830.92307,1435.6242 C 830.42346,1435.2983 829.17386,1434.8884 827.18016,1434.3888 C 824.50024,1433.7085 822.63173,1433.125 821.59709,1432.6242 C 820.56244,1432.1317 819.77111,1431.4443 819.23607,1430.5691 C 818.70221,1429.6939 818.43056,1428.729 818.43056,1427.6731 C 818.43056,1426.7081 818.6526,1425.8199 819.09788,1425.0002 C 819.53489,1424.1735 820.13961,1423.4931 820.89552,1422.951 C 821.46599,1422.5353 822.24316,1422.1739 823.22229,1421.8821 C 824.20851,1421.5904 825.26442,1421.4439 826.38883,1421.4439 C 828.08371,1421.4439 829.56954,1421.6943 830.85458,1422.1809 C 832.13844,1422.6664 833.08332,1423.3266 833.69395,1424.1593 C 834.30576,1425.0002 834.72269,1426.1105 834.95182,1427.5065 L 831.37544,1428.0002 C 831.20891,1426.8888 830.73647,1426.0207 829.95812,1425.3959 C 829.18096,1424.7711 828.07662,1424.4581 826.6534,1424.4581 C 824.97269,1424.4581 823.77151,1424.7357 823.05576,1425.292 C 822.33411,1425.8471 821.97269,1426.5002 821.97269,1427.2432 C 821.97269,1427.7215 822.12505,1428.1455 822.42387,1428.5282 C 822.72269,1428.9239 823.18805,1429.2428 823.82702,1429.5073 C 824.19435,1429.6384 825.27151,1429.9514 827.06206,1430.4369 C 829.65222,1431.1313 831.45812,1431.6947 832.4786,1432.1388 C 833.50734,1432.5758 834.31285,1433.2219 834.89632,1434.0617 C 835.47861,1434.9026 835.77034,1435.9443 835.77034,1437.1939 C 835.77034,1438.4164 835.4101,1439.562 834.70144,1440.6451 C 833.98569,1441.7223 832.95813,1442.555 831.61758,1443.1455 C 830.27821,1443.7361 828.75695,1444.0278 827.06207,1444.0278 C 824.24987,1444.0278 822.11089,1443.4443 820.63924,1442.2774 C 819.16641,1441.1105 818.22979,1439.3813 817.82704,1437.09 L 817.827,1437.09 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path179" />
-
-   <path
-   d="M 840.138,1417.93 L 840.138,1413.7158 L 843.80414,1413.7158 L 843.80414,1417.93 L 840.138,1417.93 z M 840.138,1443.541 L 840.138,1421.9375 L 843.80414,1421.9375 L 843.80414,1443.541 L 840.138,1443.541 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path181" />
-
-   <path
-   d="M 857.374,1440.26 L 857.90077,1443.4962 C 856.87321,1443.7112 855.94959,1443.8222 855.13699,1443.8222 C 853.80471,1443.8222 852.77597,1443.6143 852.04014,1443.1903 C 851.3114,1442.7734 850.79762,1442.2183 850.4988,1441.5309 C 850.19998,1440.8505 850.04762,1439.4061 850.04762,1437.2116 L 850.04762,1424.7805 L 847.35943,1424.7805 L 847.35943,1421.934 L 850.04762,1421.934 L 850.04762,1416.5801 L 853.6925,1414.3856 L 853.6925,1421.934 L 857.374,1421.934 L 857.374,1424.7805 L 853.6925,1424.7805 L 853.6925,1437.4124 C 853.6925,1438.4612 853.7551,1439.1285 853.8803,1439.4262 C 854.01258,1439.725 854.22045,1439.9612 854.51219,1440.1419 C 854.80392,1440.3155 855.22085,1440.4053 855.76298,1440.4053 C 856.17164,1440.4053 856.70668,1440.3569 857.374,1440.26 L 857.374,1440.26 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path183" />
-
-   <path
-   d="M 875.741,1436.58 L 879.52525,1437.0454 C 878.92761,1439.2599 877.82446,1440.9749 876.21344,1442.1973 C 874.59533,1443.4127 872.53194,1444.0245 870.02564,1444.0245 C 866.86619,1444.0245 864.35871,1443.0513 862.51147,1441.1072 C 860.65714,1439.1631 859.73352,1436.4336 859.73352,1432.9198 C 859.73352,1429.2808 860.67131,1426.4615 862.53982,1424.4548 C 864.41423,1422.4481 866.83785,1421.4406 869.82368,1421.4406 C 872.71266,1421.4406 875.07368,1422.4269 876.90085,1424.3922 C 878.73392,1426.3576 879.65046,1429.1284 879.65046,1432.6906 C 879.65046,1432.9127 879.64337,1433.2399 879.6292,1433.6698 L 863.519,1433.6698 C 863.65128,1436.045 864.32451,1437.8639 865.53278,1439.1217 C 866.74105,1440.3855 868.24105,1441.0174 870.04695,1441.0174 C 871.38632,1441.0174 872.53199,1440.6631 873.48396,1439.9544 C 874.43475,1439.2529 875.18475,1438.1284 875.74105,1436.58 L 875.741,1436.58 z M 863.7197,1430.6568 L 875.7823,1430.6568 C 875.62285,1428.8438 875.1575,1427.4761 874.40041,1426.5725 C 873.23348,1425.1635 871.72049,1424.4548 869.86616,1424.4548 C 868.18545,1424.4548 866.76813,1425.017 865.62246,1426.1426 C 864.47679,1427.267 863.8449,1428.7741 863.7197,1430.6568 L 863.7197,1430.6568 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path185" />
-
-   <path
-   d="M 899.692,1443.54 L 893.08137,1421.9365 L 896.86562,1421.9365 L 900.30381,1434.4078 L 901.58058,1439.0472 C 901.63609,1438.811 902.01168,1437.3251 902.69908,1434.5885 L 906.13609,1421.9365 L 909.90026,1421.9365 L 913.13648,1434.4633 L 914.21955,1438.596 L 915.45616,1434.422 L 919.15655,1421.9366 L 922.71994,1421.9366 L 915.96285,1443.5401 L 912.16442,1443.5401 L 908.72623,1430.6023 L 907.88647,1426.9149 L 903.51875,1443.5401 L 899.69198,1443.5401 L 899.692,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path187" />
-
-   <polygon
-   points="923.046,1444.05 931.691,1413.21 934.622,1413.21 925.997,1444.05 923.046,1444.05 "
-   style="fill:#000000;fill-rule:nonzero"
-   id="polygon189" />
-
-   <path
-   d="M 936.698,1445.33 L 940.2602,1445.858 C 940.40666,1446.9552 940.8224,1447.7536 941.49681,1448.2603 C 942.40626,1448.9335 943.64878,1449.2737 945.21846,1449.2737 C 946.92043,1449.2737 948.22555,1448.9335 949.14917,1448.2603 C 950.07279,1447.58 950.69051,1446.628 951.01649,1445.4127 C 951.21137,1444.6627 951.29523,1443.1013 951.28106,1440.7119 C 949.68421,1442.5934 947.69051,1443.5383 945.30232,1443.5383 C 942.32949,1443.5383 940.03106,1442.4694 938.40586,1440.3233 C 936.78184,1438.1843 935.96216,1435.6083 935.96216,1432.6154 C 935.96216,1430.552 936.33657,1428.6493 937.07948,1426.9072 C 937.82948,1425.1639 938.91373,1423.8162 940.32987,1422.8654 C 941.74601,1421.9206 943.41255,1421.441 945.32239,1421.441 C 947.87121,1421.441 949.97593,1422.4757 951.6283,1424.5391 L 951.6283,1421.9347 L 955.0098,1421.9347 L 955.0098,1440.6079 C 955.0098,1443.9693 954.66255,1446.3575 953.98224,1447.7607 C 953.29483,1449.1627 952.21177,1450.2741 950.72594,1451.0867 C 949.23893,1451.8993 947.41295,1452.3091 945.23972,1452.3091 C 942.66255,1452.3091 940.58027,1451.7256 938.99641,1450.5658 C 937.40665,1449.406 936.64247,1447.6626 936.69798,1445.33 L 936.698,1445.33 z M 939.72517,1432.3509 C 939.72517,1435.1844 940.28856,1437.2537 941.42005,1438.5529 C 942.54564,1439.858 943.9547,1440.5041 945.64958,1440.5041 C 947.32911,1440.5041 948.73934,1439.858 949.87793,1438.5659 C 951.01651,1437.2678 951.58699,1435.2399 951.58699,1432.469 C 951.58699,1429.8233 951.00352,1427.8308 949.82951,1426.4903 C 948.65549,1425.1497 947.23935,1424.4765 945.58699,1424.4765 C 943.96179,1424.4765 942.5799,1425.1355 941.43423,1426.4619 C 940.29565,1427.7812 939.72517,1429.7466 939.72517,1432.3509 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path191" />
-
-   <path
-   d="M 960.503,1443.54 L 960.503,1421.9365 L 963.79473,1421.9365 L 963.79473,1425.207 C 964.63449,1423.6798 965.41284,1422.6652 966.12741,1422.1798 C 966.83607,1421.6932 967.62032,1421.4428 968.47544,1421.4428 C 969.71087,1421.4428 970.96166,1421.8396 972.23843,1422.6239 L 970.97465,1426.0267 C 970.08646,1425.4916 969.19,1425.2282 968.29473,1425.2282 C 967.48922,1425.2282 966.77347,1425.4715 966.13449,1425.9499 C 965.49551,1426.4365 965.04433,1427.1026 964.77386,1427.9566 C 964.36402,1429.2558 964.16323,1430.679 964.16323,1432.2274 L 964.16323,1443.54 L 960.50299,1443.54 L 960.503,1443.54 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path193" />
-
-  </g>
-    <g
-       transform="matrix(0.317715,0,0,0.317715,415.2513,-451.5858)"
-       style="fill-rule:evenodd"
-       id="_19509096">
-   <path
-   d="M 75.3272,2384.22 L 75.853972,2387.4562 C 74.826412,2387.6712 73.902792,2387.7822 73.090192,2387.7822 C 71.757912,2387.7822 70.729172,2387.5743 69.993342,2387.1503 C 69.264602,2386.7334 68.750822,2386.1783 68.452002,2385.4909 C 68.153183,2384.8105 68.000821,2383.3661 68.000821,2381.1716 L 68.000821,2368.7405 L 65.312631,2368.7405 L 65.312631,2365.894 L 68.000821,2365.894 L 68.000821,2360.5401 L 71.645701,2358.3456 L 71.645701,2365.894 L 75.327201,2365.894 L 75.327201,2368.7405 L 71.645701,2368.7405 L 71.645701,2381.3724 C 71.645701,2382.4212 71.708299,2383.0885 71.833496,2383.3862 C 71.965779,2383.685 72.173653,2383.9212 72.465386,2384.1019 C 72.757118,2384.2755 73.174047,2384.3653 73.716176,2384.3653 C 74.124837,2384.3653 74.659877,2384.3169 75.327196,2384.22 L 75.3272,2384.22 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="_19509000" />
-
-   <path
-   d="M 93.6945,2380.54 L 97.47875,2381.0054 C 96.881112,2383.2199 95.77796,2384.9349 94.16694,2386.1573 C 92.54883,2387.3727 90.48544,2387.9845 87.97914,2387.9845 C 84.81969,2387.9845 82.31221,2387.0113 80.46497,2385.0672 C 78.61064,2383.1231 77.68702,2380.3936 77.68702,2376.8798 C 77.68702,2373.2408 78.624815,2370.4215 80.49332,2368.4148 C 82.36773,2366.4081 84.79135,2365.4006 87.77718,2365.4006 C 90.66616,2365.4006 93.02718,2366.3869 94.85435,2368.3522 C 96.68742,2370.3176 97.60396,2373.0884 97.60396,2376.6506 C 97.60396,2376.8727 97.596873,2377.1999 97.5827,2377.6298 L 81.4725,2377.6298 C 81.604783,2380.005 82.278012,2381.8239 83.48628,2383.0817 C 84.69455,2384.3455 86.19455,2384.9774 88.00045,2384.9774 C 89.33982,2384.9774 90.48549,2384.6231 91.43746,2383.9144 C 92.388247,2383.2129 93.13825,2382.0884 93.69455,2380.54 L 93.6945,2380.54 z M 81.6732,2374.6168 L 93.7358,2374.6168 C 93.576351,2372.8038 93.110997,2371.4361 92.35391,2370.5325 C 91.18698,2369.1235 89.67399,2368.4148 87.81966,2368.4148 C 86.13895,2368.4148 84.72163,2368.977 83.57596,2370.1026 C 82.43029,2371.227 81.7984,2372.7341 81.6732,2374.6168 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path197" />
-
-   <path
-   d="M 99.639,2387.5 L 107.53467,2376.2713 L 100.22837,2365.8965 L 104.80514,2365.8965 L 108.12404,2370.9587 C 108.74294,2371.9237 109.24963,2372.7292 109.62404,2373.3823 C 110.22168,2372.487 110.77089,2371.6945 111.27758,2371 L 114.91656,2365.8965 L 119.29136,2365.8965 L 111.82561,2376.0693 L 119.86065,2387.5 L 115.36774,2387.5 L 110.93034,2380.7854 L 109.74924,2378.9724 L 104.07641,2387.5 L 99.63901,2387.5 L 99.639,2387.5 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path199" />
-
-   <path
-   d="M 130.909,2384.22 L 131.43577,2387.4562 C 130.40821,2387.6712 129.48459,2387.7822 128.67199,2387.7822 C 127.33971,2387.7822 126.31097,2387.5743 125.57514,2387.1503 C 124.8464,2386.7334 124.33262,2386.1783 124.0338,2385.4909 C 123.73498,2384.8105 123.58262,2383.3661 123.58262,2381.1716 L 123.58262,2368.7405 L 120.89443,2368.7405 L 120.89443,2365.894 L 123.58262,2365.894 L 123.58262,2360.5401 L 127.2275,2358.3456 L 127.2275,2365.894 L 130.909,2365.894 L 130.909,2368.7405 L 127.2275,2368.7405 L 127.2275,2381.3724 C 127.2275,2382.4212 127.2901,2383.0885 127.4153,2383.3862 C 127.54758,2383.685 127.75545,2383.9212 128.04719,2384.1019 C 128.33892,2384.2755 128.75585,2384.3653 129.29798,2384.3653 C 129.70664,2384.3653 130.24168,2384.3169 130.909,2384.22 L 130.909,2384.22 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path201" />
-
-   <path
-   d="M 146.067,2395.78 L 146.067,2365.8993 L 149.40007,2365.8993 L 149.40007,2368.7044 C 150.1855,2367.6072 151.07369,2366.7816 152.067,2366.2324 C 153.05322,2365.6843 154.2544,2365.4056 155.66464,2365.4056 C 157.51188,2365.4056 159.13708,2365.8851 160.54614,2366.83 C 161.96228,2367.7808 163.02527,2369.1213 163.74102,2370.8505 C 164.46267,2372.5796 164.82409,2374.4753 164.82409,2376.5375 C 164.82409,2378.7461 164.42842,2380.7387 163.63,2382.5103 C 162.83748,2384.2808 161.68472,2385.6343 160.17173,2386.5792 C 158.65756,2387.517 157.06661,2387.9895 155.40008,2387.9895 C 154.17882,2387.9895 153.08748,2387.732 152.11543,2387.2182 C 151.14338,2386.7044 150.35204,2386.0513 149.72724,2385.267 L 149.72724,2395.78 L 146.067,2395.78 L 146.067,2395.78 z M 149.37999,2376.8221 C 149.37999,2379.6001 149.9422,2381.6552 151.06779,2382.9886 C 152.1922,2384.315 153.55992,2384.9823 155.15795,2384.9823 C 156.78197,2384.9823 158.17803,2384.2949 159.33787,2382.9131 C 160.49771,2381.5383 161.08118,2379.4064 161.08118,2376.5174 C 161.08118,2373.7595 160.51189,2371.7044 159.37921,2370.3296 C 158.24771,2368.9619 156.89299,2368.2745 155.32449,2368.2745 C 153.76189,2368.2745 152.38,2369.0032 151.17882,2370.4619 C 149.97646,2371.9193 149.38,2374.0453 149.38,2376.8221 L 149.37999,2376.8221 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path203" />
-
-   <path
-   d="M 169.199,2387.5 L 169.199,2365.8965 L 172.49073,2365.8965 L 172.49073,2369.167 C 173.33049,2367.6398 174.10884,2366.6252 174.82341,2366.1398 C 175.53207,2365.6532 176.31632,2365.4028 177.17144,2365.4028 C 178.40687,2365.4028 179.65766,2365.7996 180.93443,2366.5839 L 179.67065,2369.9867 C 178.78246,2369.4516 177.886,2369.1882 176.99073,2369.1882 C 176.18522,2369.1882 175.46947,2369.4315 174.83049,2369.9099 C 174.19151,2370.3965 173.74033,2371.0626 173.46986,2371.9166 C 173.06002,2373.2158 172.85923,2374.639 172.85923,2376.1874 L 172.85923,2387.5 L 169.19899,2387.5 L 169.199,2387.5 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path205" />
-
-   <path
-   d="M 181.747,2376.69 C 181.747,2372.6908 182.85842,2369.725 185.08716,2367.8022 C 186.94149,2366.2042 189.20566,2365.3987 191.8785,2365.3987 C 194.85133,2365.3987 197.28086,2366.3719 199.16354,2368.3231 C 201.05212,2370.2672 201.98992,2372.9542 201.98992,2376.3853 C 201.98992,2379.1691 201.57299,2381.3577 200.73913,2382.9475 C 199.90645,2384.5443 198.6911,2385.7809 197.10133,2386.662 C 195.5033,2387.5443 193.76708,2387.9825 191.8785,2387.9825 C 188.85842,2387.9825 186.41354,2387.0164 184.54504,2385.0723 C 182.67772,2383.1353 181.74701,2380.3431 181.74701,2376.69 L 181.747,2376.69 z M 185.51117,2376.69 C 185.51117,2379.4609 186.11471,2381.5313 187.32298,2382.9061 C 188.53125,2384.288 190.05251,2384.9754 191.87849,2384.9754 C 193.69857,2384.9754 195.21156,2384.2809 196.41983,2382.8991 C 197.62219,2381.5172 198.22574,2379.4054 198.22574,2376.5731 C 198.22574,2373.8991 197.6222,2371.8711 196.40684,2370.4963 C 195.19149,2369.1215 193.6844,2368.4341 191.87849,2368.4341 C 190.05251,2368.4341 188.53125,2369.1215 187.32298,2370.4892 C 186.11471,2371.8569 185.51117,2373.9262 185.51117,2376.69 L 185.51117,2376.69 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path207" />
-
-   <path
-   d="M 206.288,2395.78 L 206.288,2365.8993 L 209.62107,2365.8993 L 209.62107,2368.7044 C 210.4065,2367.6072 211.29469,2366.7816 212.288,2366.2324 C 213.27422,2365.6843 214.4754,2365.4056 215.88564,2365.4056 C 217.73288,2365.4056 219.35808,2365.8851 220.76714,2366.83 C 222.18328,2367.7808 223.24627,2369.1213 223.96202,2370.8505 C 224.68367,2372.5796 225.04509,2374.4753 225.04509,2376.5375 C 225.04509,2378.7461 224.64942,2380.7387 223.851,2382.5103 C 223.05848,2384.2808 221.90572,2385.6343 220.39273,2386.5792 C 218.87856,2387.517 217.28761,2387.9895 215.62108,2387.9895 C 214.39982,2387.9895 213.30848,2387.732 212.33643,2387.2182 C 211.36438,2386.7044 210.57304,2386.0513 209.94824,2385.267 L 209.94824,2395.78 L 206.288,2395.78 L 206.288,2395.78 z M 209.60099,2376.8221 C 209.60099,2379.6001 210.1632,2381.6552 211.28879,2382.9886 C 212.4132,2384.315 213.78092,2384.9823 215.37895,2384.9823 C 217.00297,2384.9823 218.39903,2384.2949 219.55887,2382.9131 C 220.71871,2381.5383 221.30218,2379.4064 221.30218,2376.5174 C 221.30218,2373.7595 220.73289,2371.7044 219.60021,2370.3296 C 218.46871,2368.9619 217.11399,2368.2745 215.54549,2368.2745 C 213.98289,2368.2745 212.601,2369.0032 211.39982,2370.4619 C 210.19746,2371.9193 209.601,2374.0453 209.601,2376.8221 L 209.60099,2376.8221 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path209" />
-
-   <path
-   d="M 228.093,2376.69 C 228.093,2372.6908 229.20442,2369.725 231.43316,2367.8022 C 233.28749,2366.2042 235.55166,2365.3987 238.2245,2365.3987 C 241.19733,2365.3987 243.62686,2366.3719 245.50954,2368.3231 C 247.39812,2370.2672 248.33592,2372.9542 248.33592,2376.3853 C 248.33592,2379.1691 247.91899,2381.3577 247.08513,2382.9475 C 246.25245,2384.5443 245.0371,2385.7809 243.44733,2386.662 C 241.8493,2387.5443 240.11308,2387.9825 238.2245,2387.9825 C 235.20442,2387.9825 232.75954,2387.0164 230.89104,2385.0723 C 229.02372,2383.1353 228.09301,2380.3431 228.09301,2376.69 L 228.093,2376.69 z M 231.85717,2376.69 C 231.85717,2379.4609 232.46071,2381.5313 233.66898,2382.9061 C 234.87725,2384.288 236.39851,2384.9754 238.22449,2384.9754 C 240.04457,2384.9754 241.55756,2384.2809 242.76583,2382.8991 C 243.96819,2381.5172 244.57174,2379.4054 244.57174,2376.5731 C 244.57174,2373.8991 243.9682,2371.8711 242.75284,2370.4963 C 241.53749,2369.1215 240.0304,2368.4341 238.22449,2368.4341 C 236.39851,2368.4341 234.87725,2369.1215 233.66898,2370.4892 C 232.46071,2371.8569 231.85717,2373.9262 231.85717,2376.69 L 231.85717,2376.69 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path211" />
-
-   <path
-   d="M 252.593,2387.5 L 252.593,2365.8965 L 255.88473,2365.8965 L 255.88473,2369.167 C 256.72449,2367.6398 257.50284,2366.6252 258.21741,2366.1398 C 258.92607,2365.6532 259.71032,2365.4028 260.56544,2365.4028 C 261.80087,2365.4028 263.05166,2365.7996 264.32843,2366.5839 L 263.06465,2369.9867 C 262.17646,2369.4516 261.28,2369.1882 260.38473,2369.1882 C 259.57922,2369.1882 258.86347,2369.4315 258.22449,2369.9099 C 257.58551,2370.3965 257.13433,2371.0626 256.86386,2371.9166 C 256.45402,2373.2158 256.25323,2374.639 256.25323,2376.1874 L 256.25323,2387.5 L 252.59299,2387.5 L 252.593,2387.5 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path213" />
-
-   <path
-   d="M 274.502,2384.22 L 275.02877,2387.4562 C 274.00121,2387.6712 273.07759,2387.7822 272.26499,2387.7822 C 270.93271,2387.7822 269.90397,2387.5743 269.16814,2387.1503 C 268.4394,2386.7334 267.92562,2386.1783 267.6268,2385.4909 C 267.32798,2384.8105 267.17562,2383.3661 267.17562,2381.1716 L 267.17562,2368.7405 L 264.48743,2368.7405 L 264.48743,2365.894 L 267.17562,2365.894 L 267.17562,2360.5401 L 270.8205,2358.3456 L 270.8205,2365.894 L 274.502,2365.894 L 274.502,2368.7405 L 270.8205,2368.7405 L 270.8205,2381.3724 C 270.8205,2382.4212 270.8831,2383.0885 271.0083,2383.3862 C 271.14058,2383.685 271.34845,2383.9212 271.64019,2384.1019 C 271.93192,2384.2755 272.34885,2384.3653 272.89098,2384.3653 C 273.29964,2384.3653 273.83468,2384.3169 274.502,2384.22 L 274.502,2384.22 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path215" />
-
-   <path
-   d="M 278.099,2361.89 L 278.099,2357.6758 L 281.76514,2357.6758 L 281.76514,2361.89 L 278.099,2361.89 z M 278.099,2387.501 L 278.099,2365.8975 L 281.76514,2365.8975 L 281.76514,2387.501 L 278.099,2387.501 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path217" />
-
-   <path
-   d="M 285.973,2376.69 C 285.973,2372.6908 287.08442,2369.725 289.31316,2367.8022 C 291.16749,2366.2042 293.43166,2365.3987 296.1045,2365.3987 C 299.07733,2365.3987 301.50686,2366.3719 303.38954,2368.3231 C 305.27812,2370.2672 306.21592,2372.9542 306.21592,2376.3853 C 306.21592,2379.1691 305.79899,2381.3577 304.96513,2382.9475 C 304.13245,2384.5443 302.9171,2385.7809 301.32733,2386.662 C 299.7293,2387.5443 297.99308,2387.9825 296.1045,2387.9825 C 293.08442,2387.9825 290.63954,2387.0164 288.77104,2385.0723 C 286.90372,2383.1353 285.97301,2380.3431 285.97301,2376.69 L 285.973,2376.69 z M 289.73717,2376.69 C 289.73717,2379.4609 290.34071,2381.5313 291.54898,2382.9061 C 292.75725,2384.288 294.27851,2384.9754 296.10449,2384.9754 C 297.92457,2384.9754 299.43756,2384.2809 300.64583,2382.8991 C 301.84819,2381.5172 302.45174,2379.4054 302.45174,2376.5731 C 302.45174,2373.8991 301.8482,2371.8711 300.63284,2370.4963 C 299.41749,2369.1215 297.9104,2368.4341 296.10449,2368.4341 C 294.27851,2368.4341 292.75725,2369.1215 291.54898,2370.4892 C 290.34071,2371.8569 289.73717,2373.9262 289.73717,2376.69 L 289.73717,2376.69 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path219" />
-
-   <path
-   d="M 310.514,2387.5 L 310.514,2365.8965 L 313.80573,2365.8965 L 313.80573,2368.9662 C 315.39667,2366.591 317.68801,2365.4028 320.68093,2365.4028 C 321.98605,2365.4028 323.18014,2365.639 324.27148,2366.1044 C 325.36872,2366.5768 326.18014,2367.1874 326.72227,2367.9516 C 327.27148,2368.7087 327.64589,2369.6111 327.86794,2370.6528 C 328.00022,2371.3343 328.06991,2372.5213 328.06991,2374.2162 L 328.06991,2387.5001 L 324.40259,2387.5001 L 324.40259,2374.3544 C 324.40259,2372.8686 324.2644,2371.7501 323.97975,2371.0071 C 323.69511,2370.2713 323.18723,2369.6808 322.46558,2369.2438 C 321.73684,2368.7997 320.88881,2368.5764 319.90967,2368.5764 C 318.34707,2368.5764 317.0077,2369.0772 315.86794,2370.0634 C 314.73644,2371.0556 314.17424,2372.9312 314.17424,2375.702 L 314.17424,2387.5 L 310.514,2387.5 L 310.514,2387.5 z "
-   style="fill:#000000;fill-rule:nonzero"
-   id="path221" />
-
-  </g>
-    <path
-       d="M 88.126188,369.03622 C 88.126188,356.61906 103.01889,346.69059 127.84056,346.69059 C 152.66211,346.69059 167.55494,356.61906 167.55494,369.02307 L 167.55494,406.26181 C 167.55494,417.22297 158.65917,426.11874 147.698,426.11874 L 107.98331,426.11874 C 94.282043,426.11874 83.162145,437.23902 83.162145,450.94029 L 83.162145,468.32206 L 68.269064,468.30894 C 55.851904,468.30894 45.923056,453.41586 45.923056,428.59425 C 45.923056,403.7727 55.851904,388.87987 68.269064,388.87987 L 127.84063,388.893 L 127.84063,383.92876 L 88.126252,383.92876 L 88.126252,369.03606 L 88.126188,369.03622 z M 105.49443,359.10775 C 109.61173,359.10775 112.94774,362.44376 112.94774,366.54753 C 112.94774,370.66483 109.61173,374.00045 105.49443,374.00045 C 101.39066,374.00045 98.041501,370.66483 98.041501,366.54753 C 98.041501,362.44376 101.39063,359.10775 105.49443,359.10775 z "
-       style="fill:url(#pyBlue);fill-opacity:1;fill-rule:evenodd"
-       id="path223" />
-    <g
-       transform="matrix(0.317715,0,0,0.317715,-71.39343,-151.2348)"
-       style="fill-rule:evenodd"
-       id="_19487936">
-   <g
-   id="g226">
-    <path
-   d="M 1200.75,1694 C 1269.1252,1692.8331 1300.1244,1757.1665 1300.7079,1830.124 C 1300.7079,1894.4575 1268.5418,1954.749 1199.6259,1957.041 C 1171.459,1957.041 1147.3338,1948.4166 1123.792,1934.0827 L 1123.792,2082.8327 L 1082.418,2067.874 L 1083.0003,1737.625 C 1082.418,1737.625 1115.1676,1694.5833 1200.1683,1693.4163 L 1200.7506,1693.9998 L 1200.75,1694 z M 1190.4177,1927.166 C 1245.5421,1923.7491 1252.4586,1869.7503 1252.4586,1827.2495 C 1252.4586,1785.8743 1245.5421,1723.8745 1193.2925,1721.5835 C 1157.6669,1719.2496 1128.959,1735.9162 1123.2094,1741.667 L 1123.2094,1905.375 C 1137,1913.9581 1164.5834,1928.9167 1190.4177,1927.1663 L 1190.4177,1927.166 z "
-   style="fill:#6a6a6a"
-   id="_19487984" />
-
-    <path
-   d="M 1387.87,1869.75 L 1387.87,1693.416 L 1345.3704,1707.7912 L 1345.3704,1882.3742 C 1345.3704,1928.9155 1388.4535,1955.9155 1426.3704,1955.9155 C 1475.7452,1955.9155 1503.9121,1942.1238 1516.5369,1936.3742 C 1517.1204,1942.6659 1516.5369,1940.9569 1516.5369,1947.2899 C 1516.5369,1965.6655 1515.9534,1997.2493 1507.3704,2013.3324 C 1490.1204,2046.082 1444.1613,2050.6659 1411.9952,2055.2485 L 1418.9117,2081.665 C 1461.4113,2080.5406 1521.1197,2064.4575 1542.3697,2024.2481 C 1554.4536,2001.2485 1556.1614,1957.0398 1556.1614,1927.7485 L 1556.1614,1699.7485 L 1514.2453,1699.7485 L 1514.2453,1904.7905 C 1500.4536,1913.957 1475.2028,1926.6244 1452.7866,1927.1653 C 1415.4531,1927.7488 1387.8697,1907.6653 1387.8697,1869.1661 L 1387.8697,1869.7496 L 1387.87,1869.75 z "
-   style="fill:#6a6a6a"
-   id="_19488200" />
-
-    <path
-   d="M 1626.62,1726.75 L 1626.62,1891.583 C 1626.62,1934.6661 1659.9117,1959.9169 1715.6196,1954.7495 L 1715.6196,1932.9168 C 1686.3283,1931.7912 1668.5361,1923.7491 1668.5361,1890.416 L 1668.5361,1726.749 L 1715.6196,1726.749 L 1715.6196,1699.749 L 1668.5361,1699.749 L 1668.5361,1614.7498 L 1626.62,1629.6671 L 1626.62,1699.749 L 1597.8696,1699.749 L 1597.8696,1726.749 L 1626.62,1726.749 L 1626.62,1726.75 z "
-   style="fill:#6a6a6a"
-   id="_19488488" />
-
-    <path
-   d="M 1970.21,1951.29 L 1970.21,1776.123 C 1970.21,1732.4565 1940.3352,1697.999 1895.5431,1697.999 C 1861.6266,1697.999 1832.9187,1708.9147 1807.6691,1727.2903 L 1807.6691,1550.9993 L 1765.7104,1564.2087 L 1765.7104,1951.2897 L 1807.6691,1951.2897 L 1807.6691,1757.1647 C 1828.9183,1742.2474 1853.0435,1726.7478 1879.46,1726.7478 C 1913.3352,1726.7478 1927.7104,1760.0395 1927.7104,1789.3309 L 1927.7104,1951.2899 L 1970.21,1951.2899 L 1970.21,1951.29 z "
-   style="fill:#6a6a6a"
-   id="_126749024" />
-
-    <path
-   d="M 2007.75,1820.92 C 2007.75,1890.4196 2044.5,1955.92 2122.041,1956.462 C 2200.1662,1955.9199 2238.042,1890.4195 2238.042,1820.92 C 2237.4999,1753.1696 2195.0003,1694.003 2122.625,1693.42 C 2050.8341,1694.0035 2007.751,1753.1696 2007.751,1820.92 L 2007.75,1820.92 z M 2053.1244,1820.92 C 2053.1244,1775.5444 2064.5823,1725.5861 2122.0405,1722.1279 C 2176.0405,1725.0039 2192.1248,1775.5444 2192.1248,1820.92 C 2192.1248,1869.1704 2181.75,1928.92 2123.1661,1930.628 C 2069.2074,1930.0445 2053.7078,1869.1705 2053.7078,1820.92 L 2053.1243,1820.92 L 2053.1244,1820.92 z "
-   style="fill:#6a6a6a"
-   id="_126677456" />
-
-    <path
-   d="M 2477.04,1951.29 L 2477.04,1758.873 C 2477.04,1724.999 2450.0813,1703.1651 2419.6231,1696.2899 C 2389.7483,1689.4147 2361.6239,1695.1655 2340.957,1700.8738 C 2314.4991,1707.7903 2295.5814,1719.8317 2274.3322,1735.3313 L 2274.3322,1951.2903 L 2316.2483,1951.2903 L 2316.2483,1740.4993 C 2329.4566,1731.3327 2350.707,1721.5828 2373.0818,1720.9993 C 2409.8731,1720.4158 2435.1239,1741.6662 2435.1239,1780.1654 L 2435.1239,1951.2904 L 2477.04,1951.2904 L 2477.04,1951.29 z "
-   style="fill:#6a6a6a"
-   id="_126678176" />
-
-   </g>
-
-  </g>
-    <path
-       d="M 167.55462,488.16664 C 167.55462,500.58418 152.66192,510.51265 127.84025,510.51265 C 103.0187,510.51265 88.12587,500.58418 88.12587,488.17979 L 88.12587,450.94105 C 88.12587,439.97988 97.021636,431.08374 107.9828,431.08374 L 147.6975,431.08374 C 161.39877,431.08374 172.51904,419.96384 172.51904,406.26257 L 172.51904,388.8808 L 187.41174,388.89392 C 199.81575,388.89392 209.7446,403.787 209.7446,428.60829 C 209.7446,453.42984 199.81575,468.32298 187.41174,468.32298 L 127.84018,468.30986 L 127.84018,473.2741 L 167.55456,473.2741 L 167.55456,488.1668 L 167.55462,488.16664 z M 150.17323,498.0951 C 146.06946,498.0951 142.73345,494.75948 142.73345,490.65533 C 142.73345,486.53841 146.06946,483.2024 150.17323,483.2024 C 154.29015,483.2024 157.62615,486.53841 157.62615,490.65533 C 157.62615,494.75948 154.29015,498.0951 150.17323,498.0951 z "
-       style="fill:url(#pyYellow);fill-opacity:1;fill-rule:evenodd"
-       id="path234" />
-  </g>
-</svg>
diff --git a/PC/icons/source.xar b/PC/icons/source.xar
deleted file mode 100644 (file)
index 84cbbc4..0000000
Binary files a/PC/icons/source.xar and /dev/null differ
index fada4c9..db5226e 100644 (file)
@@ -114,7 +114,7 @@ static wchar_t * get_env(wchar_t * key)
     if (result >= BUFSIZE) {
         /* Large environment variable. Accept some leakage */
         wchar_t *buf2 = (wchar_t*)malloc(sizeof(wchar_t) * (result+1));
-        if (buf2 = NULL) {
+        if (buf2 == NULL) {
             error(RC_NO_MEMORY, L"Could not allocate environment buffer");
         }
         GetEnvironmentVariableW(key, buf2, result);
@@ -171,6 +171,9 @@ static wchar_t * location_checks[] = {
     L"\\",
     L"\\PCBuild\\win32\\",
     L"\\PCBuild\\amd64\\",
+    // To support early 32bit versions of Python that stuck the build binaries
+    // directly in PCBuild...
+    L"\\PCBuild\\",
     NULL
 };
 
@@ -965,10 +968,12 @@ typedef struct {
  */
 static BOM BOMs[] = {
     { 3, { 0xEF, 0xBB, 0xBF }, CP_UTF8 },           /* UTF-8 - keep first */
-    { 2, { 0xFF, 0xFE }, CP_UTF16LE },              /* UTF-16LE */
-    { 2, { 0xFE, 0xFF }, CP_UTF16BE },              /* UTF-16BE */
+    /* Test UTF-32LE before UTF-16LE since UTF-16LE BOM is a prefix
+     * of UTF-32LE BOM. */
     { 4, { 0xFF, 0xFE, 0x00, 0x00 }, CP_UTF32LE },  /* UTF-32LE */
     { 4, { 0x00, 0x00, 0xFE, 0xFF }, CP_UTF32BE },  /* UTF-32BE */
+    { 2, { 0xFF, 0xFE }, CP_UTF16LE },              /* UTF-16LE */
+    { 2, { 0xFE, 0xFF }, CP_UTF16BE },              /* UTF-16BE */
     { 0 }                                           /* sentinel */
 };
 
@@ -1063,18 +1068,21 @@ typedef struct {
 } PYC_MAGIC;
 
 static PYC_MAGIC magic_values[] = {
-    { 0xc687, 0xc687, L"2.0" },
-    { 0xeb2a, 0xeb2a, L"2.1" },
-    { 0xed2d, 0xed2d, L"2.2" },
-    { 0xf23b, 0xf245, L"2.3" },
-    { 0xf259, 0xf26d, L"2.4" },
-    { 0xf277, 0xf2b3, L"2.5" },
-    { 0xf2c7, 0xf2d1, L"2.6" },
-    { 0xf2db, 0xf303, L"2.7" },
-    { 0x0bb8, 0x0c3b, L"3.0" },
-    { 0x0c45, 0x0c4f, L"3.1" },
-    { 0x0c58, 0x0c6c, L"3.2" },
-    { 0x0c76, 0x0c76, L"3.3" },
+    { 50823, 50823, L"2.0" },
+    { 60202, 60202, L"2.1" },
+    { 60717, 60717, L"2.2" },
+    { 62011, 62021, L"2.3" },
+    { 62041, 62061, L"2.4" },
+    { 62071, 62131, L"2.5" },
+    { 62151, 62161, L"2.6" },
+    { 62171, 62211, L"2.7" },
+    { 3000, 3131, L"3.0" },
+    { 3141, 3151, L"3.1" },
+    { 3160, 3180, L"3.2" },
+    { 3190, 3230, L"3.3" },
+    { 3250, 3310, L"3.4" },
+    { 3320, 3350, L"3.5" },
+    { 3360, 3361, L"3.6" },
     { 0 }
 };
 
@@ -1252,7 +1260,7 @@ path '%ls'", command);
                              * is no version specification.
                              */
                             debug(L"searching PATH for python executable\n");
-                            cmd = find_on_path(L"python");
+                            cmd = find_on_path(PYTHON_EXECUTABLE);
                             debug(L"Python on path: %ls\n", cmd ? cmd->value : L"<not found>");
                             if (cmd) {
                                 debug(L"located python on PATH: %ls\n", cmd->value);
index d44173a..ac4f8f2 100644 (file)
@@ -347,7 +347,7 @@ Py_NO_ENABLE_SHARED to find out.  Also support MS_NO_COREDLL for b/w compat */
 #      define SIZEOF_FPOS_T 8
 #      define SIZEOF_HKEY 4
 #      define SIZEOF_SIZE_T 4
-       /* MS VS2005 changes time_t to an 64-bit type on all platforms */
+       /* MS VS2005 changes time_t to a 64-bit type on all platforms */
 #      if defined(_MSC_VER) && _MSC_VER >= 1400
 #      define SIZEOF_TIME_T 8
 #      else
index 827e9be..f95e755 100644 (file)
@@ -4,16 +4,15 @@
 #include "winver.h"
 
 #define PYTHON_COMPANY   "Python Software Foundation"
-#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2015 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC."
+#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2016 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC."
 
 #define MS_WINDOWS
 #include "modsupport.h"
 #include "patchlevel.h"
+#include <pythonnt_rc.h>
 #ifdef _DEBUG
-#   include "pythonnt_rc_d.h"
 #   define PYTHON_DEBUG_EXT "_d"
 #else
-#   include "pythonnt_rc.h"
 #   define PYTHON_DEBUG_EXT
 #endif
 
diff --git a/PC/sqlite3.rc b/PC/sqlite3.rc
new file mode 100644 (file)
index 0000000..84bd87d
--- /dev/null
@@ -0,0 +1,49 @@
+// Resource script for Sqlite DLL.
+
+#include <winver.h>
+
+// Include the manifest file that indicates we support all
+// current versions of Windows.
+#include <winuser.h>
+2 RT_MANIFEST "python.manifest"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+#define _S(x) #x
+#define S(x) _S(x)
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION SQLITE_MAJOR_VERSION, SQLITE_MINOR_VERSION, SQLITE_MICRO_VERSION, SQLITE_PATCH_VERSION
+ PRODUCTVERSION SQLITE_MAJOR_VERSION, SQLITE_MINOR_VERSION, SQLITE_MICRO_VERSION, SQLITE_PATCH_VERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "000004b0"
+        BEGIN
+            VALUE "CompanyName", "SQLite3\0"
+            VALUE "FileDescription", "SQLite3\0"
+            VALUE "FileVersion", S(SQLITE_VERSION) "\0"
+            VALUE "InternalName", "SQLite3 DLL\0"
+            VALUE "LegalCopyright", "Unspecified\0"
+            VALUE "OriginalFilename", "sqlite3.dll\0"
+            VALUE "ProductName", "SQLite3\0"
+            VALUE "ProductVersion", S(SQLITE_VERSION) "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x0, 1200
+    END
+END
diff --git a/PC/validate_ucrtbase.py b/PC/validate_ucrtbase.py
new file mode 100644 (file)
index 0000000..6145d59
--- /dev/null
@@ -0,0 +1,88 @@
+'''
+This script gets the version number from ucrtbased.dll and checks
+whether it is a version with a known issue.
+'''
+
+import sys
+
+from ctypes import (c_buffer, POINTER, byref, create_unicode_buffer,
+                    Structure, WinDLL)
+from ctypes.wintypes import DWORD, HANDLE
+
+class VS_FIXEDFILEINFO(Structure):
+    _fields_ = [
+        ("dwSignature", DWORD),
+        ("dwStrucVersion", DWORD),
+        ("dwFileVersionMS", DWORD),
+        ("dwFileVersionLS", DWORD),
+        ("dwProductVersionMS", DWORD),
+        ("dwProductVersionLS", DWORD),
+        ("dwFileFlagsMask", DWORD),
+        ("dwFileFlags", DWORD),
+        ("dwFileOS", DWORD),
+        ("dwFileType", DWORD),
+        ("dwFileSubtype", DWORD),
+        ("dwFileDateMS", DWORD),
+        ("dwFileDateLS", DWORD),
+    ]
+
+kernel32 = WinDLL('kernel32')
+version = WinDLL('version')
+
+if len(sys.argv) < 2:
+    print('Usage: validate_ucrtbase.py <ucrtbase|ucrtbased>')
+    sys.exit(2)
+
+try:
+    ucrtbased = WinDLL(sys.argv[1])
+except OSError:
+    print('Cannot find ucrtbased.dll')
+    # This likely means that VS is not installed, but that is an
+    # obvious enough problem if you're trying to produce a debug
+    # build that we don't need to fail here.
+    sys.exit(0)
+
+# We will immediately double the length up to MAX_PATH, but the
+# path may be longer, so we retry until the returned string is
+# shorter than our buffer.
+name_len = actual_len = 130
+while actual_len == name_len:
+    name_len *= 2
+    name = create_unicode_buffer(name_len)
+    actual_len = kernel32.GetModuleFileNameW(HANDLE(ucrtbased._handle),
+                                             name, len(name))
+    if not actual_len:
+        print('Failed to get full module name.')
+        sys.exit(2)
+
+size = version.GetFileVersionInfoSizeW(name, None)
+if not size:
+    print('Failed to get size of version info.')
+    sys.exit(2)
+
+ver_block = c_buffer(size)
+if (not version.GetFileVersionInfoW(name, None, size, ver_block) or
+    not ver_block):
+    print('Failed to get version info.')
+    sys.exit(2)
+
+pvi = POINTER(VS_FIXEDFILEINFO)()
+if not version.VerQueryValueW(ver_block, "", byref(pvi), byref(DWORD())):
+    print('Failed to get version value from info.')
+    sys.exit(2)
+
+ver = (
+    pvi.contents.dwProductVersionMS >> 16,
+    pvi.contents.dwProductVersionMS & 0xFFFF,
+    pvi.contents.dwProductVersionLS >> 16,
+    pvi.contents.dwProductVersionLS & 0xFFFF,
+)
+
+print('{} is version {}.{}.{}.{}'.format(name.value, *ver))
+
+if ver < (10, 0, 10586):
+    print('WARN: ucrtbased contains known issues. '
+          'Please update Visual Studio or the Windows SDK.')
+    print('See:')
+    print('  http://bugs.python.org/issue26624')
+    sys.exit(1)
index 3313202..d1c3f39 100644 (file)
@@ -792,7 +792,7 @@ winreg.ConnectRegistry -> HKEY
         The predefined key to connect to.
     /
 
-Establishes a connection to the registry on on another computer.
+Establishes a connection to the registry on another computer.
 
 The return value is the handle of the opened key.
 If the function fails, an OSError exception is raised.
@@ -801,7 +801,7 @@ If the function fails, an OSError exception is raised.
 static HKEY
 winreg_ConnectRegistry_impl(PyModuleDef *module, Py_UNICODE *computer_name,
                             HKEY key)
-/*[clinic end generated code: output=5c52f6f7ba6e7b46 input=9a056558ce318433]*/
+/*[clinic end generated code: output=5c52f6f7ba6e7b46 input=5f98a891a347e68e]*/
 {
     HKEY retKey;
     long rc;
@@ -1605,7 +1605,7 @@ winreg.SetValueEx
                          references to environment variables (for example,
                          %PATH%).
         REG_LINK -- A Unicode symbolic link.
-        REG_MULTI_SZ -- An sequence of null-terminated strings, terminated
+        REG_MULTI_SZ -- A sequence of null-terminated strings, terminated
                         by two null characters.  Note that Python handles
                         this termination automatically.
         REG_NONE -- No defined value type.
@@ -1631,7 +1631,7 @@ the configuration registry to help the registry perform efficiently.
 static PyObject *
 winreg_SetValueEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *value_name,
                        PyObject *reserved, DWORD type, PyObject *value)
-/*[clinic end generated code: output=ea092a935c361582 input=e73dec535ebeea7d]*/
+/*[clinic end generated code: output=ea092a935c361582 input=f1b16cbcc3ed4101]*/
 {
     BYTE *data;
     DWORD len;
index 64c3dcd..9efb0d9 100644 (file)
@@ -84,6 +84,9 @@
     <ClInclude Include="$(bz2Dir)\bzlib_private.h" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 68b8e29..70bea45 100644 (file)
@@ -97,6 +97,9 @@
     </CustomBuild>
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
     </ProjectReference>
index c1260b5..b62407f 100644 (file)
@@ -67,6 +67,9 @@
     <ClCompile Include="..\Modules\_ctypes\_ctypes_test.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
     </ProjectReference>
index 943bfb0..9c9c19a 100644 (file)
     </CustomBuild>
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
     </ProjectReference>
index 414bd8b..725b5a9 100644 (file)
@@ -92,6 +92,9 @@
     <ClCompile Include="..\Modules\expat\xmltok.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index d82b266..b1300cb 100644 (file)
@@ -61,7 +61,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup>
     <ClCompile>
-      <AdditionalIncludeDirectories>$(opensslDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(opensslIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
       <AdditionalDependencies>ws2_32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -71,6 +71,9 @@
     <ClCompile Include="..\Modules\_hashopenssl.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
@@ -87,4 +90,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index af50494..1f0696d 100644 (file)
@@ -74,6 +74,9 @@
     <ClCompile Include="..\Modules\_lzmamodule.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index f5ba7bf..3895d45 100644 (file)
@@ -69,6 +69,9 @@
     <ClCompile Include="..\PC\_msi.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 1eb92b6..bb2bb41 100644 (file)
@@ -73,6 +73,9 @@
     <ClCompile Include="..\Modules\_multiprocessing\semaphore.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 55301ea..8cf8a86 100644 (file)
@@ -69,6 +69,9 @@
     <ClCompile Include="..\Modules\overlapped.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 03b6f75..d5c4d1b 100644 (file)
@@ -72,6 +72,9 @@
     <ClCompile Include="..\Modules\socketmodule.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 5e889d0..5456bb5 100644 (file)
@@ -91,6 +91,9 @@
     <ClCompile Include="..\Modules\_sqlite\util.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 8594a06..d75ebd6 100644 (file)
@@ -61,7 +61,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup>
     <ClCompile>
-      <AdditionalIncludeDirectories>$(opensslDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(opensslIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
       <AdditionalDependencies>ws2_32.lib;crypt32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -71,6 +71,9 @@
     <ClCompile Include="..\Modules\_ssl.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
@@ -91,4 +94,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index 8cbf125..1f45b29 100644 (file)
@@ -69,6 +69,9 @@
     <ClCompile Include="..\Modules\_testbuffer.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
     </ProjectReference>
index dbf44e6..365b07c 100644 (file)
@@ -69,6 +69,9 @@
     <ClCompile Include="..\Modules\_testcapimodule.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index f0e4d9f..14a926e 100644 (file)
@@ -66,6 +66,9 @@
     <ClCompile Include="..\Programs\_testembed.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index cec042c..37c1a64 100644 (file)
@@ -69,6 +69,9 @@
     <ClCompile Include="..\Modules\_testimportmultiple.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 647b380..106927c 100644 (file)
@@ -69,6 +69,9 @@
     <ClCompile Include="..\Modules\_testmultiphase.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index f3185eb..6793106 100644 (file)
@@ -74,6 +74,9 @@
     <ClCompile Include="..\Modules\tkappinit.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index cfbc4a2..88b1f06 100644 (file)
@@ -25,6 +25,9 @@ echo.  -M  Disable parallel build
 echo.  -v  Increased output messages\r
 echo.  -k  Attempt to kill any running Pythons before building (usually done\r
 echo.      automatically by the pythoncore project)\r
+echo.  --pgo          Build with Profile-Guided Optimization.  This flag\r
+echo.                 overrides -c and -d\r
+echo.  --test-marker  Enable the test marker within the build.\r
 echo.\r
 echo.Available flags to avoid building certain modules.\r
 echo.These flags have no effect if '-e' is not given:\r
@@ -38,7 +41,8 @@ echo.  -p x64 ^| Win32
 echo.     Set the platform (default: Win32)\r
 echo.  -t Build ^| Rebuild ^| Clean ^| CleanAll\r
 echo.     Set the target manually\r
-echo.  --test-marker  Enable the test marker within the build.\r
+echo.  --pgo-job  The job to use for PGO training; implies --pgo\r
+echo.             (default: "-m test --pgo")\r
 exit /b 127\r
 \r
 :Run\r
@@ -51,6 +55,12 @@ set dir=%~dp0
 set parallel=/m\r
 set verbose=/nologo /v:m\r
 set kill=\r
+set do_pgo=\r
+set pgo_job=-m test --pgo\r
+set on_64_bit=true\r
+\r
+rem This may not be 100% accurate, but close enough.\r
+if "%ProgramFiles(x86)%"=="" (set on_64_bit=false)\r
 \r
 :CheckOpts\r
 if "%~1"=="-h" goto Usage\r
@@ -63,6 +73,8 @@ if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts
 if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts\r
 if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts\r
 if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts\r
+if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts\r
+if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts\r
 if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts\r
 if "%~1"=="-V" shift & goto Version\r
 rem These use the actual property names used by MSBuild.  We could just let\r
@@ -78,15 +90,49 @@ if "%IncludeTkinter%"=="" set IncludeTkinter=true
 \r
 if "%IncludeExternals%"=="true" call "%dir%get_externals.bat"\r
 \r
-if "%platf%"=="x64" (set vs_platf=x86_amd64)\r
+if "%platf%"=="x64" (\r
+    if "%on_64_bit%"=="true" (\r
+        rem This ought to always be correct these days...\r
+        set vs_platf=amd64\r
+    ) else (\r
+        if "%do_pgo%"=="true" (\r
+            echo.ERROR: Cannot cross-compile with PGO\r
+            echo.    32bit operating system detected, if this is incorrect,\r
+            echo.    make sure the ProgramFiles(x86^) environment variable is set\r
+            exit /b 1\r
+        )\r
+        set vs_platf=x86_amd64\r
+    )\r
+)\r
 \r
 rem Setup the environment\r
 call "%dir%env.bat" %vs_platf% >nul\r
 \r
-if "%kill%"=="true" (\r
-    msbuild /v:m /nologo /target:KillPython "%dir%\pythoncore.vcxproj" /p:Configuration=%conf% /p:Platform=%platf% /p:KillPython=true\r
+if "%kill%"=="true" call :Kill\r
+\r
+if "%do_pgo%"=="true" (\r
+    set conf=PGInstrument\r
+    call :Build\r
+    del /s "%dir%\*.pgc"\r
+    del /s "%dir%\..\Lib\*.pyc"\r
+    echo on\r
+    call "%dir%\..\python.bat" %pgo_job%\r
+    @echo off\r
+    call :Kill\r
+    set conf=PGUpdate\r
 )\r
+goto Build\r
 \r
+:Kill\r
+echo on\r
+msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^\r
+ /p:Configuration=%conf% /p:Platform=%platf%^\r
+ /p:KillPython=true\r
+\r
+@echo off\r
+goto :eof\r
+\r
+:Build\r
 rem Call on MSBuild to do the work, echo the command.\r
 rem Passing %1-9 is not the preferred option, but argument parsing in\r
 rem batch is, shall we say, "lackluster"\r
@@ -98,7 +144,8 @@ msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^
  /p:UseTestMarker=%UseTestMarker%^\r
  %1 %2 %3 %4 %5 %6 %7 %8 %9\r
 \r
-@goto :eof\r
+@echo off\r
+goto :eof\r
 \r
 :Version\r
 rem Display the current build version information\r
index 79ec267..872c382 100644 (file)
@@ -1,48 +1,6 @@
 @echo off\r
-rem A batch program to build PGO (Profile guided optimization) by first\r
-rem building instrumented binaries, then running the testsuite, and\r
-rem finally building the optimized code.\r
-rem Note, after the first instrumented run, one can just keep on\r
-rem building the PGUpdate configuration while developing.\r
+echo.DeprecationWarning:\r
+echo.    This script is deprecated, use `build.bat --pgo` instead.\r
+echo.\r
 \r
-setlocal\r
-set platf=Win32\r
-set parallel=/m\r
-set dir=%~dp0\r
-\r
-rem use the performance testsuite.  This is quick and simple\r
-set job1="%dir%..\tools\pybench\pybench.py" -n 1 -C 1 --with-gc\r
-set path1="%dir%..\tools\pybench"\r
-\r
-rem or the whole testsuite for more thorough testing\r
-set job2="%dir%..\lib\test\regrtest.py"\r
-set path2="%dir%..\lib"\r
-\r
-set job=%job1%\r
-set clrpath=%path1%\r
-\r
-:CheckOpts\r
-if "%1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts\r
-if "%1"=="-2" (set job=%job2%) & (set clrpath=%path2%) & shift & goto CheckOpts\r
-if "%1"=="-M" (set parallel=) & shift & goto CheckOpts\r
-\r
-\r
-rem We cannot cross compile PGO builds, as the optimization needs to be run natively\r
-set vs_platf=x86\r
-set PGO=%dir%win32-pgo\r
-\r
-if "%platf%"=="x64" (set vs_platf=amd64) & (set PGO=%dir%amd64-pgo)\r
-rem Setup the environment\r
-call "%dir%env.bat" %vs_platf%\r
-\r
-\r
-rem build the instrumented version\r
-msbuild "%dir%pcbuild.proj" %parallel% /t:Build /p:Configuration=PGInstrument /p:Platform=%platf% %1 %2 %3 %4 %5 %6 %7 %8 %9\r
-\r
-rem remove .pyc files, .pgc files and execute the job\r
-"%PGO%\python.exe" "%dir%rmpyc.py" %clrpath%\r
-del "%PGO%\*.pgc"\r
-"%PGO%\python.exe" %job%\r
-\r
-rem build optimized version\r
-msbuild "%dir%pcbuild.proj" %parallel% /t:Build /p:Configuration=PGUpdate /p:Platform=%platf% %1 %2 %3 %4 %5 %6 %7 %8 %9\r
+call "%~dp0build.bat" --pgo %*\r
index 0b3c08b..9b2a084 100644 (file)
@@ -54,7 +54,7 @@ echo.Fetching external libraries...
 set libraries=\r
 set libraries=%libraries%                                    bzip2-1.0.6\r
 if NOT "%IncludeSSL%"=="false" set libraries=%libraries%     nasm-2.11.06\r
-if NOT "%IncludeSSL%"=="false" set libraries=%libraries%     openssl-1.0.2d\r
+if NOT "%IncludeSSL%"=="false" set libraries=%libraries%     openssl-1.0.2h\r
 set libraries=%libraries%                                    sqlite-3.8.11.0\r
 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tcl-core-8.6.4.2\r
 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tk-8.6.4.2\r
index d094e59..e35c0d9 100644 (file)
@@ -17,9 +17,8 @@
     <PreprocessorDefinitions Include="_CRT_SECURE_NO_WARNINGS" />
     <PreprocessorDefinitions Include="_CRT_SECURE_NO_DEPRECATE" />
     <PreprocessorDefinitions Include="OPENSSL_THREADS" />
-    <PreprocessorDefinitions Include="OPENSSL_SYSNAME_WIN32" />
+    <!-- <PreprocessorDefinitions Include="OPENSSL_SYSNAME_WIN32" /> -->
     <PreprocessorDefinitions Include="OPENSSL_IA32_SSE2" />
-    <PreprocessorDefinitions Include="OPENSSL_CPUID_OBJ" />
     <PreprocessorDefinitions Include="SHA1_ASM" />
     <PreprocessorDefinitions Include="SHA256_ASM" />
     <PreprocessorDefinitions Include="SHA512_ASM" />
@@ -53,7 +52,7 @@
     <ClCompile>
       <!-- Suppress 64-bit truncation warnings - they aren't ours to worry about -->
       <DisableSpecificWarnings>4244;4267</DisableSpecificWarnings>
-      <AdditionalIncludeDirectories>$(opensslDir);$(opensslDir)include;$(opensslDir)crypto;$(opensslDir)crypto\asn1;$(opensslDir)crypto\evp;$(opensslDir)crypto\modes</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(opensslDir);$(opensslIncludeDir);$(opensslDir)crypto;$(opensslDir)crypto\asn1;$(opensslDir)crypto\evp;$(opensslDir)crypto\modes</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>$(_PreprocessorDefinitionList);%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
   </ItemDefinitionGroup>
@@ -74,4 +73,4 @@ $(nasm) -o "$(IntDir)%(NasmCompile.Filename).obj" "%(NasmCompile.FullPath)"' />
       <Lib Include="$(IntDir)%(NasmCompile.Filename).obj" />
     </ItemGroup>
   </Target>
-</Project>
\ No newline at end of file
+</Project>
index c08a9f3..1be73e6 100644 (file)
@@ -1,6 +1,6 @@
 @echo off\r
 if not defined HOST_PYTHON (\r
-  if %1 EQU Debug (\r
+  if "%1" EQU "Debug" (\r
     shift\r
     set HOST_PYTHON=python_d.exe\r
     if not exist python35_d.dll exit 1\r
@@ -9,4 +9,4 @@ if not defined HOST_PYTHON (
     if not exist python35.dll exit 1\r
   )\r
 )\r
-%HOST_PYTHON% prepare_ssl.py %1\r
+%HOST_PYTHON% "%~dp0prepare_ssl.py" %1\r
index 4203dab..f6170f5 100644 (file)
 import os
 import re
 import sys
-import shutil
 import subprocess
+from shutil import copy
 
 # Find all "foo.exe" files on the PATH.
-def find_all_on_path(filename, extras = None):
+def find_all_on_path(filename, extras=None):
     entries = os.environ["PATH"].split(os.pathsep)
     ret = []
     for p in entries:
@@ -39,6 +39,7 @@ def find_all_on_path(filename, extras = None):
                 ret.append(fname)
     return ret
 
+
 # Find a suitable Perl installation for OpenSSL.
 # cygwin perl does *not* work.  ActivePerl does.
 # Being a Perl dummy, the simplest way I can check is if the "Win32" package
@@ -61,82 +62,47 @@ def find_working_perl(perls):
         print("NO perl interpreters were found on this machine at all!")
     print(" Please install ActivePerl and ensure it appears on your path")
 
-def create_makefile64(makefile, m32):
-    """Create and fix makefile for 64bit
-
-    Replace 32 with 64bit directories
-    """
-    if not os.path.isfile(m32):
-        return
-    with open(m32) as fin:
-        with open(makefile, 'w') as fout:
-            for line in fin:
-                line = line.replace("=tmp32", "=tmp64")
-                line = line.replace("=out32", "=out64")
-                line = line.replace("=inc32", "=inc64")
-                # force 64 bit machine
-                line = line.replace("MKLIB=lib", "MKLIB=lib /MACHINE:X64")
-                line = line.replace("LFLAGS=", "LFLAGS=/MACHINE:X64 ")
-                # don't link against the lib on 64bit systems
-                line = line.replace("bufferoverflowu.lib", "")
-                fout.write(line)
-    os.unlink(m32)
-
-def create_asms(makefile):
+
+def create_asms(makefile, tmp_d):
     #create a custom makefile out of the provided one
     asm_makefile = os.path.splitext(makefile)[0] + '.asm.mak'
-    with open(makefile) as fin:
-        with open(asm_makefile, 'w') as fout:
-            for line in fin:
-                # Keep everything up to the install target (it's convenient)
-                if line.startswith('install: all'):
-                    break
-                else:
+    with open(makefile) as fin, open(asm_makefile, 'w') as fout:
+        for line in fin:
+            # Keep everything up to the install target (it's convenient)
+            if line.startswith('install: all'):
+                break
+            fout.write(line)
+        asms = []
+        for line in fin:
+            if '.asm' in line and line.strip().endswith('.pl'):
+                asms.append(line.split(':')[0])
+                while line.strip():
                     fout.write(line)
-            asms = []
-            for line in fin:
-                if '.asm' in line and line.strip().endswith('.pl'):
-                    asms.append(line.split(':')[0])
-                    while line.strip():
-                        fout.write(line)
-                        line = next(fin)
-                    fout.write('\n')
+                    line = next(fin)
+                fout.write('\n')
 
-            fout.write('asms: $(TMP_D) ')
-            fout.write(' '.join(asms))
-            fout.write('\n')
+        fout.write('asms: $(TMP_D) ')
+        fout.write(' '.join(asms))
+        fout.write('\n')
+    os.system('nmake /f {} PERL=perl TMP_D={} asms'.format(asm_makefile, tmp_d))
 
-    os.system('nmake /f {} PERL=perl asms'.format(asm_makefile))
-    os.unlink(asm_makefile)
 
-
-
-def fix_makefile(makefile):
-    """Fix some stuff in all makefiles
-    """
-    if not os.path.isfile(makefile):
-        return
+def copy_includes(makefile, suffix):
+    dir = 'include'+suffix+'\\openssl'
+    os.makedirs(dir, exist_ok=True)
     copy_if_different = r'$(PERL) $(SRC_D)\util\copy-if-different.pl'
     with open(makefile) as fin:
-        lines = fin.readlines()
-    with open(makefile, 'w') as fout:
-        for line in lines:
-            if line.startswith("PERL="):
-                continue
-            if line.startswith("CP="):
-                line = "CP=copy\n"
-            if line.startswith("MKDIR="):
-                line = "MKDIR=mkdir\n"
-            if line.startswith("CFLAG="):
-                line = line.strip()
-                for algo in ("RC5", "MDC2", "IDEA"):
-                    noalgo = " -DOPENSSL_NO_%s" % algo
-                    if noalgo not in line:
-                        line = line + noalgo
-                line = line + '\n'
+        for line in fin:
             if copy_if_different in line:
-                line = line.replace(copy_if_different, 'copy /Y')
-            fout.write(line)
+                perl, script, src, dest = line.split()
+                if not '$(INCO_D)' in dest:
+                    continue
+                # We're in the root of the source tree
+                src = src.replace('$(SRC_D)', '.').strip('"')
+                dest = dest.strip('"').replace('$(INCO_D)', dir)
+                print('copying', src, 'to', dest)
+                copy(src, dest)
+
 
 def run_configure(configure, do_script):
     print("perl Configure "+configure+" no-idea no-mdc2")
@@ -144,61 +110,37 @@ def run_configure(configure, do_script):
     print(do_script)
     os.system(do_script)
 
-def cmp(f1, f2):
-    bufsize = 1024 * 8
-    with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2:
-        while True:
-            b1 = fp1.read(bufsize)
-            b2 = fp2.read(bufsize)
-            if b1 != b2:
-                return False
-            if not b1:
-                return True
-
-def copy(src, dst):
-    if os.path.isfile(dst) and cmp(src, dst):
-        return
-    shutil.copy(src, dst)
 
 def prep(arch):
+    makefile_template = "ms\\nt{}.mak"
+    generated_makefile = makefile_template.format('')
     if arch == "x86":
         configure = "VC-WIN32"
         do_script = "ms\\do_nasm"
-        makefile="ms\\nt.mak"
-        m32 = makefile
-        dirsuffix = "32"
+        suffix = "32"
     elif arch == "amd64":
         configure = "VC-WIN64A"
         do_script = "ms\\do_win64a"
-        makefile = "ms\\nt64.mak"
-        m32 = makefile.replace('64', '')
-        dirsuffix = "64"
+        suffix = "64"
         #os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON"
     else:
         raise ValueError('Unrecognized platform: %s' % arch)
 
-    # rebuild makefile when we do the role over from 32 to 64 build
-    if arch == "amd64" and os.path.isfile(m32) and not os.path.isfile(makefile):
-        os.unlink(m32)
-
-    # If the ssl makefiles do not exist, we invoke Perl to generate them.
-    # Due to a bug in this script, the makefile sometimes ended up empty
-    # Force a regeneration if it is.
-    if not os.path.isfile(makefile) or os.path.getsize(makefile)==0:
-        print("Creating the makefiles...")
-        sys.stdout.flush()
-        run_configure(configure, do_script)
-
-        if arch == "amd64":
-            create_makefile64(makefile, m32)
-        fix_makefile(makefile)
-        copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch)
-        copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch)
-    else:
-        print(makefile, 'already exists!')
+    print("Creating the makefiles...")
+    sys.stdout.flush()
+    # run configure, copy includes, create asms
+    run_configure(configure, do_script)
+    makefile = makefile_template.format(suffix)
+    try:
+        os.unlink(makefile)
+    except FileNotFoundError:
+        pass
+    os.rename(generated_makefile, makefile)
+    copy_includes(makefile, suffix)
 
     print('creating asms...')
-    create_asms(makefile)
+    create_asms(makefile, 'tmp'+suffix)
+
 
 def main():
     if len(sys.argv) == 1:
@@ -229,6 +171,12 @@ def main():
         print("Found a working perl at '%s'" % (perl,))
     else:
         sys.exit(1)
+    if not find_all_on_path('nmake.exe'):
+        print('Could not find nmake.exe, try running env.bat')
+        sys.exit(1)
+    if not find_all_on_path('nasm.exe'):
+        print('Could not find nasm.exe, please add to PATH')
+        sys.exit(1)
     sys.stdout.flush()
 
     # Put our working Perl at the front of our path
index 4e7621e..99c7286 100644 (file)
@@ -73,6 +73,9 @@
     <ClCompile Include="..\Modules\expat\xmltok.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 6a21785..2d4b5f6 100644 (file)
@@ -38,7 +38,6 @@
     <ProjectGuid>{7B2727B5-5A3F-40EE-A866-43A13CD31446}</ProjectGuid>
     <RootNamespace>pylauncher</RootNamespace>
     <TargetName>py</TargetName>
-    <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
     <SupportPGO>false</SupportPGO>
   </PropertyGroup>
   <Import Project="python.props" />
index 25cdfcc..c56292a 100644 (file)
@@ -50,6 +50,9 @@
       <WholeProgramOptimization>false</WholeProgramOptimization>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
     </ClCompile>
+    <ClCompile Condition="$(ICCBuild) == 'true'">
+      <FloatingPointModel>Strict</FloatingPointModel>
+    </ClCompile>
     <Link>
       <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
@@ -72,7 +75,7 @@
       <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGUpdate'">true</LinkTimeCodeGeneration>
     </Lib>
     <ResourceCompile>
-      <AdditionalIncludeDirectories>$(PySourcePath)PC;$(PySourcePath)Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(PySourcePath)PC;$(PySourcePath)Include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>$(_DebugPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <Culture>0x0409</Culture>
     </ResourceCompile>
   </ItemDefinitionGroup>
 
   <Target Name="GeneratePythonNtRcH"
-          BeforeTargets="$(MakeVersionInfoBeforeTarget)"
+          BeforeTargets="ClCompile"
           Inputs="$(PySourcePath)Include\patchlevel.h"
-          Outputs="$(PySourcePath)PC\pythonnt_rc$(PyDebugExt).h">
-    <WriteLinesToFile File="$(PySourcePath)PC\pythonnt_rc$(PyDebugExt).h" Overwrite="true" Encoding="ascii"
-                      Lines='/* This file created by python.props /t:GeneratePythonNtRcH */
+          Outputs="$(IntDir)pythonnt_rc.h">
+    <WriteLinesToFile File="$(IntDir)pythonnt_rc.h" Overwrite="true" Encoding="ascii"
+                      Lines='/* This file created by pyproject.props /t:GeneratePythonNtRcH */
 #define FIELD3 $(Field3Value)
 #define MS_DLL_ID "$(SysWinVer)"
-#define PYTHON_DLL_NAME "$(PyDllName).dll"
+#define PYTHON_DLL_NAME "$(TargetName)$(TargetExt)"
 ' />
     <ItemGroup>
-        <FileWrites Include="$(PySourcePath)PC\pythonnt_rc$(PyDebugExt).h" />
+        <FileWrites Include="$(IntDir)pythonnt_rc.h" />
     </ItemGroup>
   </Target>
 
@@ -151,7 +154,7 @@ foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses
     <SignToolPath Condition="'$(SignToolPath)' == '' or !Exists($(SignToolPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot81)\bin\x86\signtool.exe</SignToolPath>
     <SignToolPath Condition="!Exists($(SignToolPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot)\bin\x86\signtool.exe</SignToolPath>
     <SignToolPath Condition="!Exists($(SignToolPath))">$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)\Bin\signtool.exe</SignToolPath>
-    <_SignCommand Condition="Exists($(SignToolPath))">"$(SignToolPath)" sign /q /n "$(SigningCertificate)" /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)"</_SignCommand>
+    <_SignCommand Condition="Exists($(SignToolPath))">"$(SignToolPath)" sign /q /n "$(SigningCertificate)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)"</_SignCommand>
   </PropertyGroup>
   
   <Target Name="_SignBuild" AfterTargets="AfterBuild" Condition="'$(SigningCertificate)' != '' and $(SupportSigning)">
index 862f041..843771d 100644 (file)
@@ -7,12 +7,18 @@
     Use the latest available version of Visual Studio to build. To override
     this and build with an earlier version, pass "/p:PlatformToolset=v100"
     (for example) when building.
+
+    We set BasePlatformToolset for ICC's benefit, it's otherwise ignored.
     -->
-    <PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VCTargetsPath14)' != ''">v140</PlatformToolset>
-    <PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VCTargetsPath12)' != ''">v120</PlatformToolset>
-    <PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VCTargetsPath11)' != ''">v110</PlatformToolset>
-    <PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VCTargetsPath10)' != ''">v100</PlatformToolset>
-    
+    <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath14)' != ''">v140</BasePlatformToolset>
+    <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath12)' != ''">v120</BasePlatformToolset>
+    <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath11)' != ''">v110</BasePlatformToolset>
+    <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath10)' != ''">v100</BasePlatformToolset>
+
+    <PlatformToolset Condition="'$(PlatformToolset)' == ''">$(BasePlatformToolset)</PlatformToolset>
+    <ICCBuild>false</ICCBuild>
+    <ICCBuild Condition="$(PlatformToolset.StartsWith(`Intel C++ Compiler`))">true</ICCBuild>
+
     <!--
     Convincing MSVC/MSBuild to prefer our platform names is too difficult,
     so we define our own constant ArchName and use wherever we need it.
@@ -35,7 +41,9 @@
     <sqlite3Dir>$(ExternalsDir)sqlite-3.8.11.0\</sqlite3Dir>
     <bz2Dir>$(ExternalsDir)bzip2-1.0.6\</bz2Dir>
     <lzmaDir>$(ExternalsDir)xz-5.0.5\</lzmaDir>
-    <opensslDir>$(ExternalsDir)openssl-1.0.2d\</opensslDir>
+    <opensslDir>$(ExternalsDir)openssl-1.0.2h\</opensslDir>
+    <opensslIncludeDir>$(opensslDir)include32</opensslIncludeDir>
+    <opensslIncludeDir Condition="'$(ArchName)' == 'amd64'">$(opensslDir)include64</opensslIncludeDir>
     <nasmDir>$(ExternalsDir)\nasm-2.11.06\</nasmDir>
     
     <!-- Suffix for all binaries when building for debug -->
index 0ae4882..60116df 100644 (file)
@@ -36,7 +36,6 @@
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}</ProjectGuid>
-    <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
   </PropertyGroup>
   <Import Project="python.props" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
+  <Target Name="ValidateUcrtbase" AfterTargets="AfterBuild">
+    <PropertyGroup>
+      <UcrtName>ucrtbase</UcrtName>
+      <UcrtName Condition="'$(Configuration)' == 'Debug'">ucrtbased</UcrtName>
+    </PropertyGroup>
+    <Exec Command='"$(OutDir)python$(PyDebugExt).exe" "$(PySourcePath)PC\validate_ucrtbase.py" $(UcrtName)' ContinueOnError="true" />
+  </Target>
   <Target Name="GeneratePythonBat" AfterTargets="AfterBuild">
     <PropertyGroup>
       <_Content>@rem This script invokes the most recently built Python with all arguments
index 18ff4a8..cbb618f 100644 (file)
@@ -39,7 +39,6 @@
     <RootNamespace>python3dll</RootNamespace>
     <Keyword>Win32Proj</Keyword>
     <TargetName>python3</TargetName>
-    <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
     <SupportPGO>false</SupportPGO>
   </PropertyGroup>
   <Import Project="python.props" />
index 9cbe8b9..3a1b5ba 100644 (file)
@@ -48,7 +48,6 @@
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <PropertyGroup>
-    <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
     <KillPython>true</KillPython>
   </PropertyGroup>
   <ImportGroup Label="PropertySheets">
index b0a209a..caed1e8 100644 (file)
@@ -36,7 +36,6 @@
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{F4229CC3-873C-49AE-9729-DD308ED4CD4A}</ProjectGuid>
-    <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
     <SupportPGO>false</SupportPGO>
   </PropertyGroup>
   <Import Project="python.props" />
index 882f1c4..eabf883 100644 (file)
@@ -38,7 +38,6 @@
     <ProjectGuid>{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}</ProjectGuid>
     <RootNamespace>pywlauncher</RootNamespace>
     <TargetName>pyw</TargetName>
-    <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
     <SupportPGO>false</SupportPGO>
   </PropertyGroup>
   <Import Project="python.props" />
index 09a996f..d45eb27 100644 (file)
@@ -169,7 +169,7 @@ _lzma
     Homepage:\r
         http://tukaani.org/xz/\r
 _ssl\r
-    Python wrapper for version 1.0.2d of the OpenSSL secure sockets\r
+    Python wrapper for version 1.0.2h of the OpenSSL secure sockets\r
     library, which is built by ssl.vcxproj\r
     Homepage:\r
         http://www.openssl.org/\r
index 3cd0694..d6112ab 100644 (file)
@@ -68,6 +68,9 @@
     <ClCompile Include="..\Modules\selectmodule.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index b6246fa..c841c5a 100644 (file)
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <_SqliteVersion>$([System.Text.RegularExpressions.Regex]::Match(`$(sqlite3Dir)`, `((\d+)\.(\d+)\.(\d+)\.(\d+))\\?$`).Groups)</_SqliteVersion>
+    <SqliteVersion>$(_SqliteVersion.Split(`;`)[1])</SqliteVersion>
+    <SqliteMajorVersion>$(_SqliteVersion.Split(`;`)[2])</SqliteMajorVersion>
+    <SqliteMinorVersion>$(_SqliteVersion.Split(`;`)[3])</SqliteMinorVersion>
+    <SqliteMicroVersion>$(_SqliteVersion.Split(`;`)[4])</SqliteMicroVersion>
+    <SqlitePatchVersion>$(_SqliteVersion.Split(`;`)[5])</SqlitePatchVersion>
   </PropertyGroup>
   <ItemDefinitionGroup>
     <ClCompile>
@@ -63,6 +69,9 @@
       <PreprocessorDefinitions>SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <WarningLevel>Level1</WarningLevel>
     </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>SQLITE_VERSION=$(SqliteVersion);SQLITE_MAJOR_VERSION=$(SqliteMajorVersion);SQLITE_MINOR_VERSION=$(SqliteMinorVersion);SQLITE_MICRO_VERSION=$(SqliteMicroVersion);SQLITE_PATCH_VERSION=$(SqlitePatchVersion);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="$(sqlite3Dir)\sqlite3.h" />
@@ -71,6 +80,9 @@
   <ItemGroup>
     <ClCompile Include="$(sqlite3Dir)\sqlite3.c" />
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\PC\sqlite3.rc" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
index 5e794e5..11dbffb 100644 (file)
@@ -37,9 +37,9 @@
     <BuildDirTop>Release</BuildDirTop>
     <BuildDirTop Condition="$(Configuration) == 'Debug'">Debug</BuildDirTop>
     <BuildDirTop Condition="$(TclMachine) != 'IX86'">$(BuildDirTop)_$(TclMachine)</BuildDirTop>
-    <BuildDirTop Condition="$(VisualStudioVersion) == '14.0'">$(BuildDirTop)_VC13</BuildDirTop>
-    <BuildDirTop Condition="$(VisualStudioVersion) == '12.0'">$(BuildDirTop)_VC12</BuildDirTop>
-    <BuildDirTop Condition="$(VisualStudioVersion) == '11.0'">$(BuildDirTop)_VC11</BuildDirTop>
-    <BuildDirTop Condition="$(VisualStudioVersion) == '10.0'">$(BuildDirTop)_VC10</BuildDirTop>
+    <BuildDirTop Condition="$(PlatformToolset) == 'v140'">$(BuildDirTop)_VC13</BuildDirTop>
+    <BuildDirTop Condition="$(PlatformToolset) == 'v120'">$(BuildDirTop)_VC12</BuildDirTop>
+    <BuildDirTop Condition="$(PlatformToolset) == 'v110'">$(BuildDirTop)_VC11</BuildDirTop>
+    <BuildDirTop Condition="$(PlatformToolset) == 'v100'">$(BuildDirTop)_VC10</BuildDirTop>
   </PropertyGroup>
 </Project>
\ No newline at end of file
index a3071fb..317c1a8 100644 (file)
@@ -72,6 +72,9 @@
     <ClCompile Include="..\Modules\unicodedata.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 540235a..12913ef 100644 (file)
@@ -68,6 +68,9 @@
     <ClCompile Include="..\PC\winsound.c" />
   </ItemGroup>
   <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
index 6a528db..184ffe7 100644 (file)
@@ -275,6 +275,7 @@ get_coding_spec(const char *s, char **spec, Py_ssize_t size, struct tok_state *t
                         return 0;
                 }
                 *spec = r;
+                break;
             }
         }
     }
@@ -524,9 +525,8 @@ fp_setreadl(struct tok_state *tok, const char* enc)
     if (stream == NULL)
         goto cleanup;
 
-    Py_XDECREF(tok->decoding_readline);
     readline = _PyObject_GetAttrId(stream, &PyId_readline);
-    tok->decoding_readline = readline;
+    Py_XSETREF(tok->decoding_readline, readline);
     if (pos > 0) {
         if (PyObject_CallObject(readline, NULL) == NULL) {
             readline = NULL;
index 39ff097..ab6a8c7 100644 (file)
@@ -17,7 +17,7 @@ static void _testembed_Py_Initialize(void)
 
 
 /*****************************************************
- * Test repeated initalisation and subinterpreters
+ * Test repeated initialisation and subinterpreters
  *****************************************************/
 
 static void print_subinterp(void)
index 2e5e4e3..37b10b8 100644 (file)
@@ -4,7 +4,7 @@
 #include <locale.h>
 
 #ifdef __FreeBSD__
-#include <floatingpoint.h>
+#include <fenv.h>
 #endif
 
 #ifdef MS_WINDOWS
@@ -23,9 +23,6 @@ main(int argc, char **argv)
     wchar_t **argv_copy2;
     int i, res;
     char *oldloc;
-#ifdef __FreeBSD__
-    fp_except_t m;
-#endif
 
     argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
     argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
@@ -40,8 +37,7 @@ main(int argc, char **argv)
      * exceptions by default.  Here we disable them.
      */
 #ifdef __FreeBSD__
-    m = fpgetmask();
-    fpsetmask(m & ~FP_X_OFL);
+    fedisableexcept(FE_OVERFLOW);
 #endif
 
     oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
index 9ca8314..978bad1 100644 (file)
@@ -680,8 +680,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
                     goto handle_error;
                 }
                 else if (!is_true) {
-                    Py_DECREF(*filename);
-                    *filename = PyUnicode_FromString("__main__");
+                    Py_SETREF(*filename, PyUnicode_FromString("__main__"));
                     if (*filename == NULL)
                         goto handle_error;
                 }
index a06ef61..f3d0c9a 100644 (file)
@@ -796,12 +796,12 @@ divmod as builtin_divmod
     y: object
     /
 
-Return the tuple ((x-x%y)/y, x%y).  Invariant: div*y + mod == x.
+Return the tuple (x//y, x%y).  Invariant: div*y + mod == x.
 [clinic start generated code]*/
 
 static PyObject *
 builtin_divmod_impl(PyModuleDef *module, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=9ad0076120ebf9ac input=7fdb15f8a97a5fe7]*/
+/*[clinic end generated code: output=9ad0076120ebf9ac input=175ad9c84ff41a85]*/
 {
     return PyNumber_Divmod(x, y);
 }
index beabfeb..3d69038 100644 (file)
@@ -1933,8 +1933,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
             PyObject *obj = TOP();
             PyTypeObject *type = Py_TYPE(obj);
 
-            if (type->tp_as_async != NULL)
+            if (type->tp_as_async != NULL) {
                 getter = type->tp_as_async->am_aiter;
+            }
 
             if (getter != NULL) {
                 iter = (*getter)(obj);
@@ -1955,6 +1956,27 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
                 goto error;
             }
 
+            if (Py_TYPE(iter)->tp_as_async != NULL &&
+                    Py_TYPE(iter)->tp_as_async->am_anext != NULL) {
+
+                /* Starting with CPython 3.5.2 __aiter__ should return
+                   asynchronous iterators directly (not awaitables that
+                   resolve to asynchronous iterators.)
+
+                   Therefore, we check if the object that was returned
+                   from __aiter__ has an __anext__ method.  If it does,
+                   we wrap it in an awaitable that resolves to `iter`.
+
+                   See http://bugs.python.org/issue27243 for more
+                   details.
+                */
+
+                PyObject *wrapper = _PyAIterWrapper_New(iter);
+                Py_DECREF(iter);
+                SET_TOP(wrapper);
+                DISPATCH();
+            }
+
             awaitable = _PyCoro_GetAwaitableIter(iter);
             if (awaitable == NULL) {
                 SET_TOP(NULL);
@@ -1966,9 +1988,23 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
 
                 Py_DECREF(iter);
                 goto error;
-            } else
+            } else {
                 Py_DECREF(iter);
 
+                if (PyErr_WarnFormat(
+                        PyExc_PendingDeprecationWarning, 1,
+                        "'%.100s' implements legacy __aiter__ protocol; "
+                        "__aiter__ should return an asynchronous "
+                        "iterator, not awaitable",
+                        type->tp_name))
+                {
+                    /* Warning was converted to an error. */
+                    Py_DECREF(awaitable);
+                    SET_TOP(NULL);
+                    goto error;
+                }
+            }
+
             SET_TOP(awaitable);
             DISPATCH();
         }
@@ -2021,6 +2057,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
 
             Py_DECREF(iterable);
 
+            if (iter != NULL && PyCoro_CheckExact(iter)) {
+                PyObject *yf = _PyGen_yf((PyGenObject*)iter);
+                if (yf != NULL) {
+                    /* `iter` is a coroutine object that is being
+                       awaited, `yf` is a pointer to the current awaitable
+                       being awaited on. */
+                    Py_DECREF(yf);
+                    Py_CLEAR(iter);
+                    PyErr_SetString(
+                        PyExc_RuntimeError,
+                        "coroutine is being awaited already");
+                    /* The code below jumps to `error` if `iter` is NULL. */
+                }
+            }
+
             SET_TOP(iter); /* Even if it's NULL */
 
             if (iter == NULL) {
@@ -3214,8 +3265,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
                 Py_INCREF(self);
                 func = PyMethod_GET_FUNCTION(func);
                 Py_INCREF(func);
-                Py_DECREF(*pfunc);
-                *pfunc = self;
+                Py_SETREF(*pfunc, self);
                 na++;
                 /* n++; */
             } else
@@ -3270,6 +3320,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
                 PyObject *anns = PyDict_New();
                 if (anns == NULL) {
                     Py_DECREF(func);
+                    Py_DECREF(names);
                     goto error;
                 }
                 name_ix = PyTuple_Size(names);
@@ -3285,9 +3336,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
                     if (err != 0) {
                         Py_DECREF(anns);
                         Py_DECREF(func);
+                        Py_DECREF(names);
                         goto error;
                     }
                 }
+                Py_DECREF(names);
 
                 if (PyFunction_SetAnnotations(func, anns) != 0) {
                     /* Can't happen unless
@@ -3297,7 +3350,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
                     goto error;
                 }
                 Py_DECREF(anns);
-                Py_DECREF(names);
             }
 
             /* XXX Maybe this should be a separate opcode? */
@@ -4411,10 +4463,8 @@ _PyEval_SetCoroutineWrapper(PyObject *wrapper)
 {
     PyThreadState *tstate = PyThreadState_GET();
 
-    Py_CLEAR(tstate->coroutine_wrapper);
-
     Py_XINCREF(wrapper);
-    tstate->coroutine_wrapper = wrapper;
+    Py_XSETREF(tstate->coroutine_wrapper, wrapper);
 }
 
 PyObject *
@@ -4670,8 +4720,7 @@ call_function(PyObject ***pp_stack, int oparg
             Py_INCREF(self);
             func = PyMethod_GET_FUNCTION(func);
             Py_INCREF(func);
-            Py_DECREF(*pfunc);
-            *pfunc = self;
+            Py_SETREF(*pfunc, self);
             na++;
             n++;
         } else
@@ -4939,16 +4988,18 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
         stararg = EXT_POP(*pp_stack);
         if (!PyTuple_Check(stararg)) {
             PyObject *t = NULL;
+            if (Py_TYPE(stararg)->tp_iter == NULL &&
+                    !PySequence_Check(stararg)) {
+                PyErr_Format(PyExc_TypeError,
+                             "%.200s%.200s argument after * "
+                             "must be an iterable, not %.200s",
+                             PyEval_GetFuncName(func),
+                             PyEval_GetFuncDesc(func),
+                             stararg->ob_type->tp_name);
+                goto ext_call_fail;
+            }
             t = PySequence_Tuple(stararg);
             if (t == NULL) {
-                if (PyErr_ExceptionMatches(PyExc_TypeError)) {
-                    PyErr_Format(PyExc_TypeError,
-                                 "%.200s%.200s argument after * "
-                                 "must be a sequence, not %.200s",
-                                 PyEval_GetFuncName(func),
-                                 PyEval_GetFuncDesc(func),
-                                 stararg->ob_type->tp_name);
-                }
                 goto ext_call_fail;
             }
             Py_DECREF(stararg);
index aafcbc2..8d38ee9 100644 (file)
@@ -111,7 +111,7 @@ static _Py_atomic_int gil_locked = {-1};
 static unsigned long gil_switch_number = 0;
 /* Last PyThreadState holding / having held the GIL. This helps us know
    whether anyone else was scheduled after we dropped the GIL. */
-static _Py_atomic_address gil_last_holder = {NULL};
+static _Py_atomic_address gil_last_holder = {0};
 
 /* This condition variable allows one or several threads to wait until
    the GIL is released. In addition, the mutex also protects the above
@@ -142,7 +142,7 @@ static void create_gil(void)
 #ifdef FORCE_SWITCHING
     COND_INIT(switch_cond);
 #endif
-    _Py_atomic_store_relaxed(&gil_last_holder, NULL);
+    _Py_atomic_store_relaxed(&gil_last_holder, 0);
     _Py_ANNOTATE_RWLOCK_CREATE(&gil_locked);
     _Py_atomic_store_explicit(&gil_locked, 0, _Py_memory_order_release);
 }
@@ -178,7 +178,7 @@ static void drop_gil(PyThreadState *tstate)
         /* Sub-interpreter support: threads might have been switched
            under our feet using PyThreadState_Swap(). Fix the GIL last
            holder variable so that our heuristics work. */
-        _Py_atomic_store_relaxed(&gil_last_holder, tstate);
+        _Py_atomic_store_relaxed(&gil_last_holder, (Py_uintptr_t)tstate);
     }
 
     MUTEX_LOCK(gil_mutex);
@@ -240,7 +240,7 @@ _ready:
     _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil_locked, /*is_write=*/1);
 
     if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil_last_holder)) {
-        _Py_atomic_store_relaxed(&gil_last_holder, tstate);
+        _Py_atomic_store_relaxed(&gil_last_holder, (Py_uintptr_t)tstate);
         ++gil_switch_number;
     }
 
index 7369148..90995e5 100644 (file)
@@ -179,7 +179,7 @@ PyDoc_STRVAR(builtin_divmod__doc__,
 "divmod($module, x, y, /)\n"
 "--\n"
 "\n"
-"Return the tuple ((x-x%y)/y, x%y).  Invariant: div*y + mod == x.");
+"Return the tuple (x//y, x%y).  Invariant: div*y + mod == x.");
 
 #define BUILTIN_DIVMOD_METHODDEF    \
     {"divmod", (PyCFunction)builtin_divmod, METH_VARARGS, builtin_divmod__doc__},
@@ -660,4 +660,4 @@ builtin_issubclass(PyModuleDef *module, PyObject *args)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=bec3399c0aee98d7 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=4bef16b6aa432879 input=a9049054013a1b77]*/
index d90bf73..fe57d0d 100644 (file)
@@ -403,7 +403,7 @@ wrap_codec_error(const char *operation,
                            operation, encoding);
 }
 
-/* Encode an object (e.g. an Unicode object) using the given encoding
+/* Encode an object (e.g. a Unicode object) using the given encoding
    and return the resulting encoded object (usually a Python string).
 
    errors is passed to the encoder factory as argument if non-NULL. */
@@ -450,7 +450,7 @@ _PyCodec_EncodeInternal(PyObject *object,
 }
 
 /* Decode an object (usually a Python string) using the given encoding
-   and return an equivalent object (e.g. an Unicode object).
+   and return an equivalent object (e.g. a Unicode object).
 
    errors is passed to the decoder factory as argument if non-NULL. */
 
index 4befaa7..1e720ea 100644 (file)
@@ -393,7 +393,7 @@ list2dict(PyObject *list)
             return NULL;
         }
         k = PyList_GET_ITEM(list, i);
-        k = PyTuple_Pack(2, k, k->ob_type);
+        k = _PyCode_ConstantKey(k);
         if (k == NULL || PyDict_SetItem(dict, k, v) < 0) {
             Py_XDECREF(k);
             Py_DECREF(v);
@@ -456,7 +456,7 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
                 return NULL;
             }
             i++;
-            tuple = PyTuple_Pack(2, k, k->ob_type);
+            tuple = _PyCode_ConstantKey(k);
             if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
                 Py_DECREF(sorted_keys);
                 Py_DECREF(item);
@@ -559,7 +559,7 @@ compiler_enter_scope(struct compiler *c, identifier name,
             compiler_unit_free(u);
             return 0;
         }
-        tuple = PyTuple_Pack(2, name, Py_TYPE(name));
+        tuple = _PyCode_ConstantKey(name);
         if (!tuple) {
             compiler_unit_free(u);
             return 0;
@@ -1100,47 +1100,8 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
 {
     PyObject *t, *v;
     Py_ssize_t arg;
-    double d;
-
-    /* necessary to make sure types aren't coerced (e.g., float and complex) */
-    /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
-    if (PyFloat_Check(o)) {
-        d = PyFloat_AS_DOUBLE(o);
-        /* all we need is to make the tuple different in either the 0.0
-         * or -0.0 case from all others, just to avoid the "coercion".
-         */
-        if (d == 0.0 && copysign(1.0, d) < 0.0)
-            t = PyTuple_Pack(3, o, o->ob_type, Py_None);
-        else
-            t = PyTuple_Pack(2, o, o->ob_type);
-    }
-    else if (PyComplex_Check(o)) {
-        Py_complex z;
-        int real_negzero, imag_negzero;
-        /* For the complex case we must make complex(x, 0.)
-           different from complex(x, -0.) and complex(0., y)
-           different from complex(-0., y), for any x and y.
-           All four complex zeros must be distinguished.*/
-        z = PyComplex_AsCComplex(o);
-        real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
-        imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
-        if (real_negzero && imag_negzero) {
-            t = PyTuple_Pack(5, o, o->ob_type,
-                             Py_None, Py_None, Py_None);
-        }
-        else if (imag_negzero) {
-            t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None);
-        }
-        else if (real_negzero) {
-            t = PyTuple_Pack(3, o, o->ob_type, Py_None);
-        }
-        else {
-            t = PyTuple_Pack(2, o, o->ob_type);
-        }
-    }
-    else {
-        t = PyTuple_Pack(2, o, o->ob_type);
-    }
+
+    t = _PyCode_ConstantKey(o);
     if (t == NULL)
         return -1;
 
@@ -1454,7 +1415,7 @@ static int
 compiler_lookup_arg(PyObject *dict, PyObject *name)
 {
     PyObject *k, *v;
-    k = PyTuple_Pack(2, name, name->ob_type);
+    k = _PyCode_ConstantKey(name);
     if (k == NULL)
         return -1;
     v = PyDict_GetItem(dict, k);
@@ -1795,8 +1756,7 @@ compiler_class(struct compiler *c, stmt_ty s)
     {
         /* use the class name for name mangling */
         Py_INCREF(s->v.ClassDef.name);
-        Py_XDECREF(c->u->u_private);
-        c->u->u_private = s->v.ClassDef.name;
+        Py_XSETREF(c->u->u_private, s->v.ClassDef.name);
         /* load (global) __name__ ... */
         str = PyUnicode_InternFromString("__name__");
         if (!str || !compiler_nameop(c, str, Load)) {
@@ -4563,9 +4523,10 @@ dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
         return NULL;
     while (PyDict_Next(dict, &pos, &k, &v)) {
         i = PyLong_AS_LONG(v);
-        /* The keys of the dictionary are tuples. (see compiler_add_o)
-           The object we want is always first, though. */
-        k = PyTuple_GET_ITEM(k, 0);
+        /* The keys of the dictionary are tuples. (see compiler_add_o
+         * and _PyCode_ConstantKey). The object we want is always second,
+         * though. */
+        k = PyTuple_GET_ITEM(k, 1);
         Py_INCREF(k);
         assert((i - offset) < size);
         assert((i - offset) >= 0);
index aed2bdc..e151cab 100644 (file)
@@ -152,13 +152,7 @@ PyErr_SetString(PyObject *exception, const char *string)
 PyObject *
 PyErr_Occurred(void)
 {
-    /* If there is no thread state, PyThreadState_GET calls
-       Py_FatalError, which calls PyErr_Occurred.  To avoid the
-       resulting infinite loop, we inline PyThreadState_GET here and
-       treat no thread as no error. */
-    PyThreadState *tstate =
-        ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current));
-
+    PyThreadState *tstate = _PyThreadState_UncheckedGet();
     return tstate == NULL ? NULL : tstate->curexc_type;
 }
 
@@ -315,14 +309,11 @@ finally:
     tstate = PyThreadState_GET();
     if (++tstate->recursion_depth > Py_GetRecursionLimit()) {
         --tstate->recursion_depth;
-        /* throw away the old exception... */
-        Py_DECREF(*exc);
-        Py_DECREF(*val);
-        /* ... and use the recursion error instead */
-        *exc = PyExc_RecursionError;
-        *val = PyExc_RecursionErrorInst;
-        Py_INCREF(*exc);
-        Py_INCREF(*val);
+        /* throw away the old exception and use the recursion error instead */
+        Py_INCREF(PyExc_RecursionError);
+        Py_SETREF(*exc, PyExc_RecursionError);
+        Py_INCREF(PyExc_RecursionErrorInst);
+        Py_SETREF(*val, PyExc_RecursionErrorInst);
         /* just keeping the old traceback */
         return;
     }
@@ -736,9 +727,9 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
     PyTuple_SET_ITEM(args, 0, msg);
 
     if (PyDict_SetItemString(kwargs, "name", name) < 0)
-        return NULL;
+        goto done;
     if (PyDict_SetItemString(kwargs, "path", path) < 0)
-        return NULL;
+        goto done;
 
     error = PyObject_Call(PyExc_ImportError, args, kwargs);
     if (error != NULL) {
@@ -746,9 +737,9 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
         Py_DECREF(error);
     }
 
+done:
     Py_DECREF(args);
     Py_DECREF(kwargs);
-
     return NULL;
 }
 
@@ -909,8 +900,12 @@ PyErr_WriteUnraisable(PyObject *obj)
     if (obj) {
         if (PyFile_WriteString("Exception ignored in: ", f) < 0)
             goto done;
-        if (PyFile_WriteObject(obj, f, 0) < 0)
-            goto done;
+        if (PyFile_WriteObject(obj, f, 0) < 0) {
+            PyErr_Clear();
+            if (PyFile_WriteString("<object repr() failed>", f) < 0) {
+                goto done;
+            }
+        }
         if (PyFile_WriteString("\n", f) < 0)
             goto done;
     }
@@ -955,8 +950,12 @@ PyErr_WriteUnraisable(PyObject *obj)
     if (v && v != Py_None) {
         if (PyFile_WriteString(": ", f) < 0)
             goto done;
-        if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
-            goto done;
+        if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) {
+            PyErr_Clear();
+            if (PyFile_WriteString("<exception str() failed>", f) < 0) {
+                goto done;
+            }
+        }
     }
     if (PyFile_WriteString("\n", f) < 0)
         goto done;
index 079918c..23eed71 100644 (file)
@@ -176,7 +176,7 @@ check_force_ascii(void)
 #endif
 
 error:
-    /* if an error occured, force the ASCII encoding */
+    /* if an error occurred, force the ASCII encoding */
     return 1;
 }
 
@@ -599,7 +599,7 @@ _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
 
    On Windows, use GetFileType() and GetFileInformationByHandle() which support
    files larger than 2 GB.  fstat() may fail with EOVERFLOW on files larger
-   than 2 GB because the file size type is an signed 32-bit integer: see issue
+   than 2 GB because the file size type is a signed 32-bit integer: see issue
    #23152.
 
    On Windows, set the last Windows error and return nonzero on error. On
@@ -669,7 +669,7 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status)
 
    On Windows, use GetFileType() and GetFileInformationByHandle() which support
    files larger than 2 GB.  fstat() may fail with EOVERFLOW on files larger
-   than 2 GB because the file size type is an signed 32-bit integer: see issue
+   than 2 GB because the file size type is a signed 32-bit integer: see issue
    #23152.
 
    Raise an exception and return -1 on error. On Windows, set the last Windows
@@ -856,7 +856,7 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
             return 0;
         }
 
-        if (errno != ENOTTY) {
+        if (errno != ENOTTY && errno != EACCES) {
             if (raise)
                 PyErr_SetFromErrno(PyExc_OSError);
             return -1;
@@ -865,7 +865,12 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
             /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for
                device". The ioctl is declared but not supported by the kernel.
                Remember that ioctl() doesn't work. It is the case on
-               Illumos-based OS for example. */
+               Illumos-based OS for example.
+
+               Issue #27057: When SELinux policy disallows ioctl it will fail
+               with EACCES. While FIOCLEX is safe operation it may be
+               unavailable because ioctl was denied altogether.
+               This can be the case on Android. */
             ioctl_works = 0;
         }
         /* fallback to fcntl() if ioctl() does not work */
index 056bb76..8e9c502 100644 (file)
@@ -1042,7 +1042,7 @@ format_float_internal(PyObject *value,
     else if (type == 'r')
         type = 'g';
 
-    /* Cast "type", because if we're in unicode we need to pass a
+    /* Cast "type", because if we're in unicode we need to pass an
        8-bit char. This is safe, because we've restricted what "type"
        can be. */
     buf = PyOS_double_to_string(val, (char)type, precision, flags,
@@ -1221,7 +1221,7 @@ format_complex_internal(PyObject *value,
     else if (type == 'r')
         type = 'g';
 
-    /* Cast "type", because if we're in unicode we need to pass a
+    /* Cast "type", because if we're in unicode we need to pass an
        8-bit char. This is safe, because we've restricted what "type"
        can be. */
     re_buf = PyOS_double_to_string(re, (char)type, precision, flags,
index c365fc2..8aab067 100644 (file)
@@ -342,7 +342,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
                           flags, levels, msgbuf,
                           sizeof(msgbuf), &freelist);
         if (msg) {
-            seterror(i+1, msg, levels, fname, msg);
+            seterror(i+1, msg, levels, fname, message);
             return cleanreturn(0, &freelist);
         }
     }
@@ -535,9 +535,15 @@ converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
 {
     assert(expected != NULL);
     assert(arg != NULL);
-    PyOS_snprintf(msgbuf, bufsize,
-                  "must be %.50s, not %.50s", expected,
-                  arg == Py_None ? "None" : arg->ob_type->tp_name);
+    if (expected[0] == '(') {
+        PyOS_snprintf(msgbuf, bufsize,
+                      "%.100s", expected);
+    }
+    else {
+        PyOS_snprintf(msgbuf, bufsize,
+                      "must be %.50s, not %.50s", expected,
+                      arg == Py_None ? "None" : arg->ob_type->tp_name);
+    }
     return msgbuf;
 }
 
@@ -741,7 +747,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
         if (PyLong_Check(arg))
             ival = PyLong_AsUnsignedLongMask(arg);
         else
-            return converterr("integer<k>", arg, msgbuf, bufsize);
+            return converterr("int", arg, msgbuf, bufsize);
         *p = ival;
         break;
     }
@@ -766,7 +772,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
         if (PyLong_Check(arg))
             ival = PyLong_AsUnsignedLongLongMask(arg);
         else
-            return converterr("integer<K>", arg, msgbuf, bufsize);
+            return converterr("int", arg, msgbuf, bufsize);
         *p = ival;
         break;
     }
@@ -1123,9 +1129,11 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
             } else {
                 if (size + 1 > BUFFER_LEN) {
                     Py_DECREF(s);
-                    return converterr(
-                        "(buffer overflow)",
-                        arg, msgbuf, bufsize);
+                    PyErr_Format(PyExc_TypeError,
+                                 "encoded string too long "
+                                 "(%zd, maximum length %zd)",
+                                 (Py_ssize_t)size, (Py_ssize_t)(BUFFER_LEN-1));
+                    RETURN_ERR_OCCURRED;
                 }
             }
             memcpy(*buffer, ptr, size+1);
@@ -1147,7 +1155,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
             if ((Py_ssize_t)strlen(ptr) != size) {
                 Py_DECREF(s);
                 return converterr(
-                    "encoded string without NULL bytes",
+                    "encoded string without null bytes",
                     arg, msgbuf, bufsize);
             }
             *buffer = PyMem_NEW(char, size + 1);
@@ -1237,7 +1245,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
 
         if (*format != '*')
             return converterr(
-                "invalid use of 'w' format character",
+                "(invalid use of 'w' format character)",
                 arg, msgbuf, bufsize);
         format++;
 
@@ -1261,7 +1269,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     }
 
     default:
-        return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
+        return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
 
     }
 
index 2ad2848..c3f1e89 100644 (file)
@@ -4,7 +4,7 @@
 
 static const char cprt[] =
 "\
-Copyright (c) 2001-2015 Python Software Foundation.\n\
+Copyright (c) 2001-2016 Python Software Foundation.\n\
 All Rights Reserved.\n\
 \n\
 Copyright (c) 2000 BeOpen.com.\n\
index edf030d..0b843da 100644 (file)
@@ -671,9 +671,13 @@ PyImport_AddModuleObject(PyObject *name)
     PyObject *modules = PyImport_GetModuleDict();
     PyObject *m;
 
-    if ((m = PyDict_GetItem(modules, name)) != NULL &&
-        PyModule_Check(m))
+    if ((m = PyDict_GetItemWithError(modules, name)) != NULL &&
+        PyModule_Check(m)) {
         return m;
+    }
+    if (PyErr_Occurred()) {
+        return NULL;
+    }
     m = PyModule_NewObject(name);
     if (m == NULL)
         return NULL;
index a4daf62..7f6b753 100644 (file)
@@ -1611,378 +1611,379 @@ const unsigned char _Py_M__importlib[] = {
     1,12,2,22,1,13,1,3,1,13,1,13,4,9,2,12,
     1,4,2,7,2,8,2,114,176,0,0,0,99,3,0,0,
     0,0,0,0,0,4,0,0,0,4,0,0,0,67,0,0,
-    0,115,179,0,0,0,116,0,0,124,0,0,116,1,0,131,
+    0,115,185,0,0,0,116,0,0,124,0,0,116,1,0,131,
     2,0,115,42,0,116,2,0,100,1,0,106,3,0,116,4,
     0,124,0,0,131,1,0,131,1,0,131,1,0,130,1,0,
     124,2,0,100,2,0,107,0,0,114,66,0,116,5,0,100,
-    3,0,131,1,0,130,1,0,124,1,0,114,144,0,116,0,
-    0,124,1,0,116,1,0,131,2,0,115,102,0,116,2,0,
-    100,4,0,131,1,0,130,1,0,110,42,0,124,1,0,116,
-    6,0,106,7,0,107,7,0,114,144,0,100,5,0,125,3,
-    0,116,8,0,124,3,0,106,3,0,124,1,0,131,1,0,
-    131,1,0,130,1,0,124,0,0,12,114,175,0,124,2,0,
-    100,2,0,107,2,0,114,175,0,116,5,0,100,6,0,131,
-    1,0,130,1,0,100,7,0,83,41,8,122,28,86,101,114,
-    105,102,121,32,97,114,103,117,109,101,110,116,115,32,97,114,
-    101,32,34,115,97,110,101,34,46,122,31,109,111,100,117,108,
-    101,32,110,97,109,101,32,109,117,115,116,32,98,101,32,115,
-    116,114,44,32,110,111,116,32,123,125,114,33,0,0,0,122,
-    18,108,101,118,101,108,32,109,117,115,116,32,98,101,32,62,
-    61,32,48,122,31,95,95,112,97,99,107,97,103,101,95,95,
-    32,110,111,116,32,115,101,116,32,116,111,32,97,32,115,116,
-    114,105,110,103,122,61,80,97,114,101,110,116,32,109,111,100,
-    117,108,101,32,123,33,114,125,32,110,111,116,32,108,111,97,
-    100,101,100,44,32,99,97,110,110,111,116,32,112,101,114,102,
-    111,114,109,32,114,101,108,97,116,105,118,101,32,105,109,112,
-    111,114,116,122,17,69,109,112,116,121,32,109,111,100,117,108,
-    101,32,110,97,109,101,78,41,9,218,10,105,115,105,110,115,
-    116,97,110,99,101,218,3,115,116,114,218,9,84,121,112,101,
-    69,114,114,111,114,114,50,0,0,0,114,13,0,0,0,114,
-    168,0,0,0,114,14,0,0,0,114,21,0,0,0,218,11,
-    83,121,115,116,101,109,69,114,114,111,114,41,4,114,15,0,
-    0,0,114,169,0,0,0,114,170,0,0,0,114,147,0,0,
-    0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,13,95,115,97,110,105,116,121,95,99,104,101,99,107,151,
-    3,0,0,115,24,0,0,0,0,2,15,1,27,1,12,1,
-    12,1,6,1,15,1,15,1,15,1,6,2,21,1,19,1,
-    114,181,0,0,0,122,16,78,111,32,109,111,100,117,108,101,
-    32,110,97,109,101,100,32,122,4,123,33,114,125,99,2,0,
-    0,0,0,0,0,0,8,0,0,0,12,0,0,0,67,0,
-    0,0,115,40,1,0,0,100,0,0,125,2,0,124,0,0,
-    106,0,0,100,1,0,131,1,0,100,2,0,25,125,3,0,
-    124,3,0,114,175,0,124,3,0,116,1,0,106,2,0,107,
-    7,0,114,59,0,116,3,0,124,1,0,124,3,0,131,2,
-    0,1,124,0,0,116,1,0,106,2,0,107,6,0,114,85,
-    0,116,1,0,106,2,0,124,0,0,25,83,116,1,0,106,
-    2,0,124,3,0,25,125,4,0,121,13,0,124,4,0,106,
-    4,0,125,2,0,87,110,61,0,4,116,5,0,107,10,0,
-    114,174,0,1,1,1,116,6,0,100,3,0,23,106,7,0,
-    124,0,0,124,3,0,131,2,0,125,5,0,116,8,0,124,
-    5,0,100,4,0,124,0,0,131,1,1,100,0,0,130,2,
-    0,89,110,1,0,88,116,9,0,124,0,0,124,2,0,131,
-    2,0,125,6,0,124,6,0,100,0,0,107,8,0,114,232,
-    0,116,8,0,116,6,0,106,7,0,124,0,0,131,1,0,
-    100,4,0,124,0,0,131,1,1,130,1,0,110,12,0,116,
-    10,0,124,6,0,131,1,0,125,7,0,124,3,0,114,36,
-    1,116,1,0,106,2,0,124,3,0,25,125,4,0,116,11,
-    0,124,4,0,124,0,0,106,0,0,100,1,0,131,1,0,
-    100,5,0,25,124,7,0,131,3,0,1,124,7,0,83,41,
-    6,78,114,121,0,0,0,114,33,0,0,0,122,23,59,32,
-    123,33,114,125,32,105,115,32,110,111,116,32,97,32,112,97,
-    99,107,97,103,101,114,15,0,0,0,114,140,0,0,0,41,
-    12,114,122,0,0,0,114,14,0,0,0,114,21,0,0,0,
-    114,65,0,0,0,114,131,0,0,0,114,96,0,0,0,218,
-    8,95,69,82,82,95,77,83,71,114,50,0,0,0,114,77,
-    0,0,0,114,176,0,0,0,114,149,0,0,0,114,5,0,
-    0,0,41,8,114,15,0,0,0,218,7,105,109,112,111,114,
-    116,95,114,152,0,0,0,114,123,0,0,0,90,13,112,97,
-    114,101,110,116,95,109,111,100,117,108,101,114,147,0,0,0,
-    114,88,0,0,0,114,89,0,0,0,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,218,23,95,102,105,110,100,
-    95,97,110,100,95,108,111,97,100,95,117,110,108,111,99,107,
-    101,100,171,3,0,0,115,42,0,0,0,0,1,6,1,19,
-    1,6,1,15,1,13,2,15,1,11,1,13,1,3,1,13,
-    1,13,1,22,1,26,1,15,1,12,1,30,2,12,1,6,
-    2,13,1,29,1,114,184,0,0,0,99,2,0,0,0,0,
-    0,0,0,2,0,0,0,10,0,0,0,67,0,0,0,115,
-    37,0,0,0,116,0,0,124,0,0,131,1,0,143,18,0,
-    1,116,1,0,124,0,0,124,1,0,131,2,0,83,87,100,
-    1,0,81,82,88,100,1,0,83,41,2,122,54,70,105,110,
-    100,32,97,110,100,32,108,111,97,100,32,116,104,101,32,109,
-    111,100,117,108,101,44,32,97,110,100,32,114,101,108,101,97,
-    115,101,32,116,104,101,32,105,109,112,111,114,116,32,108,111,
-    99,107,46,78,41,2,114,54,0,0,0,114,184,0,0,0,
-    41,2,114,15,0,0,0,114,183,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,218,14,95,102,105,
-    110,100,95,97,110,100,95,108,111,97,100,198,3,0,0,115,
-    4,0,0,0,0,2,13,1,114,185,0,0,0,114,33,0,
-    0,0,99,3,0,0,0,0,0,0,0,5,0,0,0,4,
-    0,0,0,67,0,0,0,115,166,0,0,0,116,0,0,124,
-    0,0,124,1,0,124,2,0,131,3,0,1,124,2,0,100,
-    1,0,107,4,0,114,46,0,116,1,0,124,0,0,124,1,
-    0,124,2,0,131,3,0,125,0,0,116,2,0,106,3,0,
-    131,0,0,1,124,0,0,116,4,0,106,5,0,107,7,0,
-    114,84,0,116,6,0,124,0,0,116,7,0,131,2,0,83,
-    116,4,0,106,5,0,124,0,0,25,125,3,0,124,3,0,
-    100,2,0,107,8,0,114,152,0,116,2,0,106,8,0,131,
-    0,0,1,100,3,0,106,9,0,124,0,0,131,1,0,125,
-    4,0,116,10,0,124,4,0,100,4,0,124,0,0,131,1,
-    1,130,1,0,116,11,0,124,0,0,131,1,0,1,124,3,
-    0,83,41,5,97,50,1,0,0,73,109,112,111,114,116,32,
-    97,110,100,32,114,101,116,117,114,110,32,116,104,101,32,109,
-    111,100,117,108,101,32,98,97,115,101,100,32,111,110,32,105,
-    116,115,32,110,97,109,101,44,32,116,104,101,32,112,97,99,
-    107,97,103,101,32,116,104,101,32,99,97,108,108,32,105,115,
-    10,32,32,32,32,98,101,105,110,103,32,109,97,100,101,32,
-    102,114,111,109,44,32,97,110,100,32,116,104,101,32,108,101,
-    118,101,108,32,97,100,106,117,115,116,109,101,110,116,46,10,
-    10,32,32,32,32,84,104,105,115,32,102,117,110,99,116,105,
-    111,110,32,114,101,112,114,101,115,101,110,116,115,32,116,104,
-    101,32,103,114,101,97,116,101,115,116,32,99,111,109,109,111,
-    110,32,100,101,110,111,109,105,110,97,116,111,114,32,111,102,
-    32,102,117,110,99,116,105,111,110,97,108,105,116,121,10,32,
-    32,32,32,98,101,116,119,101,101,110,32,105,109,112,111,114,
-    116,95,109,111,100,117,108,101,32,97,110,100,32,95,95,105,
-    109,112,111,114,116,95,95,46,32,84,104,105,115,32,105,110,
-    99,108,117,100,101,115,32,115,101,116,116,105,110,103,32,95,
-    95,112,97,99,107,97,103,101,95,95,32,105,102,10,32,32,
-    32,32,116,104,101,32,108,111,97,100,101,114,32,100,105,100,
-    32,110,111,116,46,10,10,32,32,32,32,114,33,0,0,0,
-    78,122,40,105,109,112,111,114,116,32,111,102,32,123,125,32,
-    104,97,108,116,101,100,59,32,78,111,110,101,32,105,110,32,
-    115,121,115,46,109,111,100,117,108,101,115,114,15,0,0,0,
-    41,12,114,181,0,0,0,114,171,0,0,0,114,57,0,0,
-    0,114,145,0,0,0,114,14,0,0,0,114,21,0,0,0,
-    114,185,0,0,0,218,11,95,103,99,100,95,105,109,112,111,
-    114,116,114,58,0,0,0,114,50,0,0,0,114,77,0,0,
-    0,114,63,0,0,0,41,5,114,15,0,0,0,114,169,0,
-    0,0,114,170,0,0,0,114,89,0,0,0,114,74,0,0,
-    0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    114,186,0,0,0,204,3,0,0,115,28,0,0,0,0,9,
-    16,1,12,1,18,1,10,1,15,1,13,1,13,1,12,1,
-    10,1,6,1,9,1,18,1,10,1,114,186,0,0,0,99,
-    3,0,0,0,0,0,0,0,6,0,0,0,17,0,0,0,
-    67,0,0,0,115,239,0,0,0,116,0,0,124,0,0,100,
-    1,0,131,2,0,114,235,0,100,2,0,124,1,0,107,6,
-    0,114,83,0,116,1,0,124,1,0,131,1,0,125,1,0,
-    124,1,0,106,2,0,100,2,0,131,1,0,1,116,0,0,
-    124,0,0,100,3,0,131,2,0,114,83,0,124,1,0,106,
-    3,0,124,0,0,106,4,0,131,1,0,1,120,149,0,124,
-    1,0,68,93,141,0,125,3,0,116,0,0,124,0,0,124,
-    3,0,131,2,0,115,90,0,100,4,0,106,5,0,124,0,
-    0,106,6,0,124,3,0,131,2,0,125,4,0,121,17,0,
-    116,7,0,124,2,0,124,4,0,131,2,0,1,87,113,90,
-    0,4,116,8,0,107,10,0,114,230,0,1,125,5,0,1,
-    122,47,0,116,9,0,124,5,0,131,1,0,106,10,0,116,
-    11,0,131,1,0,114,209,0,124,5,0,106,12,0,124,4,
-    0,107,2,0,114,209,0,119,90,0,130,0,0,87,89,100,
-    5,0,100,5,0,125,5,0,126,5,0,88,113,90,0,88,
-    113,90,0,87,124,0,0,83,41,6,122,238,70,105,103,117,
-    114,101,32,111,117,116,32,119,104,97,116,32,95,95,105,109,
-    112,111,114,116,95,95,32,115,104,111,117,108,100,32,114,101,
-    116,117,114,110,46,10,10,32,32,32,32,84,104,101,32,105,
-    109,112,111,114,116,95,32,112,97,114,97,109,101,116,101,114,
-    32,105,115,32,97,32,99,97,108,108,97,98,108,101,32,119,
-    104,105,99,104,32,116,97,107,101,115,32,116,104,101,32,110,
-    97,109,101,32,111,102,32,109,111,100,117,108,101,32,116,111,
-    10,32,32,32,32,105,109,112,111,114,116,46,32,73,116,32,
-    105,115,32,114,101,113,117,105,114,101,100,32,116,111,32,100,
-    101,99,111,117,112,108,101,32,116,104,101,32,102,117,110,99,
-    116,105,111,110,32,102,114,111,109,32,97,115,115,117,109,105,
-    110,103,32,105,109,112,111,114,116,108,105,98,39,115,10,32,
-    32,32,32,105,109,112,111,114,116,32,105,109,112,108,101,109,
-    101,110,116,97,116,105,111,110,32,105,115,32,100,101,115,105,
-    114,101,100,46,10,10,32,32,32,32,114,131,0,0,0,250,
-    1,42,218,7,95,95,97,108,108,95,95,122,5,123,125,46,
-    123,125,78,41,13,114,4,0,0,0,114,130,0,0,0,218,
-    6,114,101,109,111,118,101,218,6,101,120,116,101,110,100,114,
-    188,0,0,0,114,50,0,0,0,114,1,0,0,0,114,65,
-    0,0,0,114,77,0,0,0,114,178,0,0,0,114,71,0,
-    0,0,218,15,95,69,82,82,95,77,83,71,95,80,82,69,
-    70,73,88,114,15,0,0,0,41,6,114,89,0,0,0,218,
-    8,102,114,111,109,108,105,115,116,114,183,0,0,0,218,1,
-    120,90,9,102,114,111,109,95,110,97,109,101,90,3,101,120,
-    99,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,16,95,104,97,110,100,108,101,95,102,114,111,109,108,105,
-    115,116,228,3,0,0,115,34,0,0,0,0,10,15,1,12,
-    1,12,1,13,1,15,1,16,1,13,1,15,1,21,1,3,
-    1,17,1,18,4,21,1,15,1,3,1,26,1,114,194,0,
-    0,0,99,1,0,0,0,0,0,0,0,2,0,0,0,2,
-    0,0,0,67,0,0,0,115,72,0,0,0,124,0,0,106,
-    0,0,100,1,0,131,1,0,125,1,0,124,1,0,100,2,
-    0,107,8,0,114,68,0,124,0,0,100,3,0,25,125,1,
-    0,100,4,0,124,0,0,107,7,0,114,68,0,124,1,0,
-    106,1,0,100,5,0,131,1,0,100,6,0,25,125,1,0,
-    124,1,0,83,41,7,122,167,67,97,108,99,117,108,97,116,
-    101,32,119,104,97,116,32,95,95,112,97,99,107,97,103,101,
-    95,95,32,115,104,111,117,108,100,32,98,101,46,10,10,32,
-    32,32,32,95,95,112,97,99,107,97,103,101,95,95,32,105,
-    115,32,110,111,116,32,103,117,97,114,97,110,116,101,101,100,
-    32,116,111,32,98,101,32,100,101,102,105,110,101,100,32,111,
-    114,32,99,111,117,108,100,32,98,101,32,115,101,116,32,116,
-    111,32,78,111,110,101,10,32,32,32,32,116,111,32,114,101,
-    112,114,101,115,101,110,116,32,116,104,97,116,32,105,116,115,
-    32,112,114,111,112,101,114,32,118,97,108,117,101,32,105,115,
-    32,117,110,107,110,111,119,110,46,10,10,32,32,32,32,114,
-    134,0,0,0,78,114,1,0,0,0,114,131,0,0,0,114,
-    121,0,0,0,114,33,0,0,0,41,2,114,42,0,0,0,
-    114,122,0,0,0,41,2,218,7,103,108,111,98,97,108,115,
-    114,169,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
-    11,0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,
-    99,107,97,103,101,95,95,4,4,0,0,115,12,0,0,0,
-    0,7,15,1,12,1,10,1,12,1,19,1,114,196,0,0,
-    0,99,5,0,0,0,0,0,0,0,9,0,0,0,5,0,
-    0,0,67,0,0,0,115,227,0,0,0,124,4,0,100,1,
-    0,107,2,0,114,27,0,116,0,0,124,0,0,131,1,0,
-    125,5,0,110,54,0,124,1,0,100,2,0,107,9,0,114,
-    45,0,124,1,0,110,3,0,105,0,0,125,6,0,116,1,
-    0,124,6,0,131,1,0,125,7,0,116,0,0,124,0,0,
-    124,7,0,124,4,0,131,3,0,125,5,0,124,3,0,115,
-    207,0,124,4,0,100,1,0,107,2,0,114,122,0,116,0,
+    3,0,131,1,0,130,1,0,124,2,0,100,2,0,107,4,
+    0,114,150,0,116,0,0,124,1,0,116,1,0,131,2,0,
+    115,108,0,116,2,0,100,4,0,131,1,0,130,1,0,110,
+    42,0,124,1,0,116,6,0,106,7,0,107,7,0,114,150,
+    0,100,5,0,125,3,0,116,8,0,124,3,0,106,3,0,
+    124,1,0,131,1,0,131,1,0,130,1,0,124,0,0,12,
+    114,181,0,124,2,0,100,2,0,107,2,0,114,181,0,116,
+    5,0,100,6,0,131,1,0,130,1,0,100,7,0,83,41,
+    8,122,28,86,101,114,105,102,121,32,97,114,103,117,109,101,
+    110,116,115,32,97,114,101,32,34,115,97,110,101,34,46,122,
+    31,109,111,100,117,108,101,32,110,97,109,101,32,109,117,115,
+    116,32,98,101,32,115,116,114,44,32,110,111,116,32,123,125,
+    114,33,0,0,0,122,18,108,101,118,101,108,32,109,117,115,
+    116,32,98,101,32,62,61,32,48,122,31,95,95,112,97,99,
+    107,97,103,101,95,95,32,110,111,116,32,115,101,116,32,116,
+    111,32,97,32,115,116,114,105,110,103,122,61,80,97,114,101,
+    110,116,32,109,111,100,117,108,101,32,123,33,114,125,32,110,
+    111,116,32,108,111,97,100,101,100,44,32,99,97,110,110,111,
+    116,32,112,101,114,102,111,114,109,32,114,101,108,97,116,105,
+    118,101,32,105,109,112,111,114,116,122,17,69,109,112,116,121,
+    32,109,111,100,117,108,101,32,110,97,109,101,78,41,9,218,
+    10,105,115,105,110,115,116,97,110,99,101,218,3,115,116,114,
+    218,9,84,121,112,101,69,114,114,111,114,114,50,0,0,0,
+    114,13,0,0,0,114,168,0,0,0,114,14,0,0,0,114,
+    21,0,0,0,218,11,83,121,115,116,101,109,69,114,114,111,
+    114,41,4,114,15,0,0,0,114,169,0,0,0,114,170,0,
+    0,0,114,147,0,0,0,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,218,13,95,115,97,110,105,116,121,95,
+    99,104,101,99,107,151,3,0,0,115,24,0,0,0,0,2,
+    15,1,27,1,12,1,12,1,12,1,15,1,15,1,15,1,
+    6,2,21,1,19,1,114,181,0,0,0,122,16,78,111,32,
+    109,111,100,117,108,101,32,110,97,109,101,100,32,122,4,123,
+    33,114,125,99,2,0,0,0,0,0,0,0,8,0,0,0,
+    12,0,0,0,67,0,0,0,115,40,1,0,0,100,0,0,
+    125,2,0,124,0,0,106,0,0,100,1,0,131,1,0,100,
+    2,0,25,125,3,0,124,3,0,114,175,0,124,3,0,116,
+    1,0,106,2,0,107,7,0,114,59,0,116,3,0,124,1,
+    0,124,3,0,131,2,0,1,124,0,0,116,1,0,106,2,
+    0,107,6,0,114,85,0,116,1,0,106,2,0,124,0,0,
+    25,83,116,1,0,106,2,0,124,3,0,25,125,4,0,121,
+    13,0,124,4,0,106,4,0,125,2,0,87,110,61,0,4,
+    116,5,0,107,10,0,114,174,0,1,1,1,116,6,0,100,
+    3,0,23,106,7,0,124,0,0,124,3,0,131,2,0,125,
+    5,0,116,8,0,124,5,0,100,4,0,124,0,0,131,1,
+    1,100,0,0,130,2,0,89,110,1,0,88,116,9,0,124,
+    0,0,124,2,0,131,2,0,125,6,0,124,6,0,100,0,
+    0,107,8,0,114,232,0,116,8,0,116,6,0,106,7,0,
+    124,0,0,131,1,0,100,4,0,124,0,0,131,1,1,130,
+    1,0,110,12,0,116,10,0,124,6,0,131,1,0,125,7,
+    0,124,3,0,114,36,1,116,1,0,106,2,0,124,3,0,
+    25,125,4,0,116,11,0,124,4,0,124,0,0,106,0,0,
+    100,1,0,131,1,0,100,5,0,25,124,7,0,131,3,0,
+    1,124,7,0,83,41,6,78,114,121,0,0,0,114,33,0,
+    0,0,122,23,59,32,123,33,114,125,32,105,115,32,110,111,
+    116,32,97,32,112,97,99,107,97,103,101,114,15,0,0,0,
+    114,140,0,0,0,41,12,114,122,0,0,0,114,14,0,0,
+    0,114,21,0,0,0,114,65,0,0,0,114,131,0,0,0,
+    114,96,0,0,0,218,8,95,69,82,82,95,77,83,71,114,
+    50,0,0,0,114,77,0,0,0,114,176,0,0,0,114,149,
+    0,0,0,114,5,0,0,0,41,8,114,15,0,0,0,218,
+    7,105,109,112,111,114,116,95,114,152,0,0,0,114,123,0,
+    0,0,90,13,112,97,114,101,110,116,95,109,111,100,117,108,
+    101,114,147,0,0,0,114,88,0,0,0,114,89,0,0,0,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,
+    23,95,102,105,110,100,95,97,110,100,95,108,111,97,100,95,
+    117,110,108,111,99,107,101,100,171,3,0,0,115,42,0,0,
+    0,0,1,6,1,19,1,6,1,15,1,13,2,15,1,11,
+    1,13,1,3,1,13,1,13,1,22,1,26,1,15,1,12,
+    1,30,2,12,1,6,2,13,1,29,1,114,184,0,0,0,
+    99,2,0,0,0,0,0,0,0,2,0,0,0,10,0,0,
+    0,67,0,0,0,115,37,0,0,0,116,0,0,124,0,0,
+    131,1,0,143,18,0,1,116,1,0,124,0,0,124,1,0,
+    131,2,0,83,87,100,1,0,81,82,88,100,1,0,83,41,
+    2,122,54,70,105,110,100,32,97,110,100,32,108,111,97,100,
+    32,116,104,101,32,109,111,100,117,108,101,44,32,97,110,100,
+    32,114,101,108,101,97,115,101,32,116,104,101,32,105,109,112,
+    111,114,116,32,108,111,99,107,46,78,41,2,114,54,0,0,
+    0,114,184,0,0,0,41,2,114,15,0,0,0,114,183,0,
+    0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+    0,218,14,95,102,105,110,100,95,97,110,100,95,108,111,97,
+    100,198,3,0,0,115,4,0,0,0,0,2,13,1,114,185,
+    0,0,0,114,33,0,0,0,99,3,0,0,0,0,0,0,
+    0,5,0,0,0,4,0,0,0,67,0,0,0,115,166,0,
+    0,0,116,0,0,124,0,0,124,1,0,124,2,0,131,3,
+    0,1,124,2,0,100,1,0,107,4,0,114,46,0,116,1,
+    0,124,0,0,124,1,0,124,2,0,131,3,0,125,0,0,
+    116,2,0,106,3,0,131,0,0,1,124,0,0,116,4,0,
+    106,5,0,107,7,0,114,84,0,116,6,0,124,0,0,116,
+    7,0,131,2,0,83,116,4,0,106,5,0,124,0,0,25,
+    125,3,0,124,3,0,100,2,0,107,8,0,114,152,0,116,
+    2,0,106,8,0,131,0,0,1,100,3,0,106,9,0,124,
+    0,0,131,1,0,125,4,0,116,10,0,124,4,0,100,4,
+    0,124,0,0,131,1,1,130,1,0,116,11,0,124,0,0,
+    131,1,0,1,124,3,0,83,41,5,97,50,1,0,0,73,
+    109,112,111,114,116,32,97,110,100,32,114,101,116,117,114,110,
+    32,116,104,101,32,109,111,100,117,108,101,32,98,97,115,101,
+    100,32,111,110,32,105,116,115,32,110,97,109,101,44,32,116,
+    104,101,32,112,97,99,107,97,103,101,32,116,104,101,32,99,
+    97,108,108,32,105,115,10,32,32,32,32,98,101,105,110,103,
+    32,109,97,100,101,32,102,114,111,109,44,32,97,110,100,32,
+    116,104,101,32,108,101,118,101,108,32,97,100,106,117,115,116,
+    109,101,110,116,46,10,10,32,32,32,32,84,104,105,115,32,
+    102,117,110,99,116,105,111,110,32,114,101,112,114,101,115,101,
+    110,116,115,32,116,104,101,32,103,114,101,97,116,101,115,116,
+    32,99,111,109,109,111,110,32,100,101,110,111,109,105,110,97,
+    116,111,114,32,111,102,32,102,117,110,99,116,105,111,110,97,
+    108,105,116,121,10,32,32,32,32,98,101,116,119,101,101,110,
+    32,105,109,112,111,114,116,95,109,111,100,117,108,101,32,97,
+    110,100,32,95,95,105,109,112,111,114,116,95,95,46,32,84,
+    104,105,115,32,105,110,99,108,117,100,101,115,32,115,101,116,
+    116,105,110,103,32,95,95,112,97,99,107,97,103,101,95,95,
+    32,105,102,10,32,32,32,32,116,104,101,32,108,111,97,100,
+    101,114,32,100,105,100,32,110,111,116,46,10,10,32,32,32,
+    32,114,33,0,0,0,78,122,40,105,109,112,111,114,116,32,
+    111,102,32,123,125,32,104,97,108,116,101,100,59,32,78,111,
+    110,101,32,105,110,32,115,121,115,46,109,111,100,117,108,101,
+    115,114,15,0,0,0,41,12,114,181,0,0,0,114,171,0,
+    0,0,114,57,0,0,0,114,145,0,0,0,114,14,0,0,
+    0,114,21,0,0,0,114,185,0,0,0,218,11,95,103,99,
+    100,95,105,109,112,111,114,116,114,58,0,0,0,114,50,0,
+    0,0,114,77,0,0,0,114,63,0,0,0,41,5,114,15,
+    0,0,0,114,169,0,0,0,114,170,0,0,0,114,89,0,
+    0,0,114,74,0,0,0,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,114,186,0,0,0,204,3,0,0,115,
+    28,0,0,0,0,9,16,1,12,1,18,1,10,1,15,1,
+    13,1,13,1,12,1,10,1,6,1,9,1,18,1,10,1,
+    114,186,0,0,0,99,3,0,0,0,0,0,0,0,6,0,
+    0,0,17,0,0,0,67,0,0,0,115,239,0,0,0,116,
+    0,0,124,0,0,100,1,0,131,2,0,114,235,0,100,2,
+    0,124,1,0,107,6,0,114,83,0,116,1,0,124,1,0,
+    131,1,0,125,1,0,124,1,0,106,2,0,100,2,0,131,
+    1,0,1,116,0,0,124,0,0,100,3,0,131,2,0,114,
+    83,0,124,1,0,106,3,0,124,0,0,106,4,0,131,1,
+    0,1,120,149,0,124,1,0,68,93,141,0,125,3,0,116,
+    0,0,124,0,0,124,3,0,131,2,0,115,90,0,100,4,
+    0,106,5,0,124,0,0,106,6,0,124,3,0,131,2,0,
+    125,4,0,121,17,0,116,7,0,124,2,0,124,4,0,131,
+    2,0,1,87,113,90,0,4,116,8,0,107,10,0,114,230,
+    0,1,125,5,0,1,122,47,0,116,9,0,124,5,0,131,
+    1,0,106,10,0,116,11,0,131,1,0,114,209,0,124,5,
+    0,106,12,0,124,4,0,107,2,0,114,209,0,119,90,0,
+    130,0,0,87,89,100,5,0,100,5,0,125,5,0,126,5,
+    0,88,113,90,0,88,113,90,0,87,124,0,0,83,41,6,
+    122,238,70,105,103,117,114,101,32,111,117,116,32,119,104,97,
+    116,32,95,95,105,109,112,111,114,116,95,95,32,115,104,111,
+    117,108,100,32,114,101,116,117,114,110,46,10,10,32,32,32,
+    32,84,104,101,32,105,109,112,111,114,116,95,32,112,97,114,
+    97,109,101,116,101,114,32,105,115,32,97,32,99,97,108,108,
+    97,98,108,101,32,119,104,105,99,104,32,116,97,107,101,115,
+    32,116,104,101,32,110,97,109,101,32,111,102,32,109,111,100,
+    117,108,101,32,116,111,10,32,32,32,32,105,109,112,111,114,
+    116,46,32,73,116,32,105,115,32,114,101,113,117,105,114,101,
+    100,32,116,111,32,100,101,99,111,117,112,108,101,32,116,104,
+    101,32,102,117,110,99,116,105,111,110,32,102,114,111,109,32,
+    97,115,115,117,109,105,110,103,32,105,109,112,111,114,116,108,
+    105,98,39,115,10,32,32,32,32,105,109,112,111,114,116,32,
+    105,109,112,108,101,109,101,110,116,97,116,105,111,110,32,105,
+    115,32,100,101,115,105,114,101,100,46,10,10,32,32,32,32,
+    114,131,0,0,0,250,1,42,218,7,95,95,97,108,108,95,
+    95,122,5,123,125,46,123,125,78,41,13,114,4,0,0,0,
+    114,130,0,0,0,218,6,114,101,109,111,118,101,218,6,101,
+    120,116,101,110,100,114,188,0,0,0,114,50,0,0,0,114,
+    1,0,0,0,114,65,0,0,0,114,77,0,0,0,114,178,
+    0,0,0,114,71,0,0,0,218,15,95,69,82,82,95,77,
+    83,71,95,80,82,69,70,73,88,114,15,0,0,0,41,6,
+    114,89,0,0,0,218,8,102,114,111,109,108,105,115,116,114,
+    183,0,0,0,218,1,120,90,9,102,114,111,109,95,110,97,
+    109,101,90,3,101,120,99,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,218,16,95,104,97,110,100,108,101,95,
+    102,114,111,109,108,105,115,116,228,3,0,0,115,34,0,0,
+    0,0,10,15,1,12,1,12,1,13,1,15,1,16,1,13,
+    1,15,1,21,1,3,1,17,1,18,4,21,1,15,1,3,
+    1,26,1,114,194,0,0,0,99,1,0,0,0,0,0,0,
+    0,2,0,0,0,2,0,0,0,67,0,0,0,115,72,0,
+    0,0,124,0,0,106,0,0,100,1,0,131,1,0,125,1,
+    0,124,1,0,100,2,0,107,8,0,114,68,0,124,0,0,
+    100,3,0,25,125,1,0,100,4,0,124,0,0,107,7,0,
+    114,68,0,124,1,0,106,1,0,100,5,0,131,1,0,100,
+    6,0,25,125,1,0,124,1,0,83,41,7,122,167,67,97,
+    108,99,117,108,97,116,101,32,119,104,97,116,32,95,95,112,
+    97,99,107,97,103,101,95,95,32,115,104,111,117,108,100,32,
+    98,101,46,10,10,32,32,32,32,95,95,112,97,99,107,97,
+    103,101,95,95,32,105,115,32,110,111,116,32,103,117,97,114,
+    97,110,116,101,101,100,32,116,111,32,98,101,32,100,101,102,
+    105,110,101,100,32,111,114,32,99,111,117,108,100,32,98,101,
+    32,115,101,116,32,116,111,32,78,111,110,101,10,32,32,32,
+    32,116,111,32,114,101,112,114,101,115,101,110,116,32,116,104,
+    97,116,32,105,116,115,32,112,114,111,112,101,114,32,118,97,
+    108,117,101,32,105,115,32,117,110,107,110,111,119,110,46,10,
+    10,32,32,32,32,114,134,0,0,0,78,114,1,0,0,0,
+    114,131,0,0,0,114,121,0,0,0,114,33,0,0,0,41,
+    2,114,42,0,0,0,114,122,0,0,0,41,2,218,7,103,
+    108,111,98,97,108,115,114,169,0,0,0,114,10,0,0,0,
+    114,10,0,0,0,114,11,0,0,0,218,17,95,99,97,108,
+    99,95,95,95,112,97,99,107,97,103,101,95,95,4,4,0,
+    0,115,12,0,0,0,0,7,15,1,12,1,10,1,12,1,
+    19,1,114,196,0,0,0,99,5,0,0,0,0,0,0,0,
+    9,0,0,0,5,0,0,0,67,0,0,0,115,227,0,0,
+    0,124,4,0,100,1,0,107,2,0,114,27,0,116,0,0,
+    124,0,0,131,1,0,125,5,0,110,54,0,124,1,0,100,
+    2,0,107,9,0,114,45,0,124,1,0,110,3,0,105,0,
+    0,125,6,0,116,1,0,124,6,0,131,1,0,125,7,0,
+    116,0,0,124,0,0,124,7,0,124,4,0,131,3,0,125,
+    5,0,124,3,0,115,207,0,124,4,0,100,1,0,107,2,
+    0,114,122,0,116,0,0,124,0,0,106,2,0,100,3,0,
+    131,1,0,100,1,0,25,131,1,0,83,124,0,0,115,132,
+    0,124,5,0,83,116,3,0,124,0,0,131,1,0,116,3,
     0,124,0,0,106,2,0,100,3,0,131,1,0,100,1,0,
-    25,131,1,0,83,124,0,0,115,132,0,124,5,0,83,116,
-    3,0,124,0,0,131,1,0,116,3,0,124,0,0,106,2,
-    0,100,3,0,131,1,0,100,1,0,25,131,1,0,24,125,
-    8,0,116,4,0,106,5,0,124,5,0,106,6,0,100,2,
-    0,116,3,0,124,5,0,106,6,0,131,1,0,124,8,0,
-    24,133,2,0,25,25,83,110,16,0,116,7,0,124,5,0,
-    124,3,0,116,0,0,131,3,0,83,100,2,0,83,41,4,
-    97,214,1,0,0,73,109,112,111,114,116,32,97,32,109,111,
-    100,117,108,101,46,10,10,32,32,32,32,84,104,101,32,39,
-    103,108,111,98,97,108,115,39,32,97,114,103,117,109,101,110,
-    116,32,105,115,32,117,115,101,100,32,116,111,32,105,110,102,
-    101,114,32,119,104,101,114,101,32,116,104,101,32,105,109,112,
-    111,114,116,32,105,115,32,111,99,99,117,114,105,110,103,32,
-    102,114,111,109,10,32,32,32,32,116,111,32,104,97,110,100,
-    108,101,32,114,101,108,97,116,105,118,101,32,105,109,112,111,
-    114,116,115,46,32,84,104,101,32,39,108,111,99,97,108,115,
-    39,32,97,114,103,117,109,101,110,116,32,105,115,32,105,103,
-    110,111,114,101,100,46,32,84,104,101,10,32,32,32,32,39,
-    102,114,111,109,108,105,115,116,39,32,97,114,103,117,109,101,
-    110,116,32,115,112,101,99,105,102,105,101,115,32,119,104,97,
-    116,32,115,104,111,117,108,100,32,101,120,105,115,116,32,97,
-    115,32,97,116,116,114,105,98,117,116,101,115,32,111,110,32,
-    116,104,101,32,109,111,100,117,108,101,10,32,32,32,32,98,
-    101,105,110,103,32,105,109,112,111,114,116,101,100,32,40,101,
-    46,103,46,32,96,96,102,114,111,109,32,109,111,100,117,108,
-    101,32,105,109,112,111,114,116,32,60,102,114,111,109,108,105,
-    115,116,62,96,96,41,46,32,32,84,104,101,32,39,108,101,
-    118,101,108,39,10,32,32,32,32,97,114,103,117,109,101,110,
-    116,32,114,101,112,114,101,115,101,110,116,115,32,116,104,101,
-    32,112,97,99,107,97,103,101,32,108,111,99,97,116,105,111,
-    110,32,116,111,32,105,109,112,111,114,116,32,102,114,111,109,
-    32,105,110,32,97,32,114,101,108,97,116,105,118,101,10,32,
-    32,32,32,105,109,112,111,114,116,32,40,101,46,103,46,32,
-    96,96,102,114,111,109,32,46,46,112,107,103,32,105,109,112,
-    111,114,116,32,109,111,100,96,96,32,119,111,117,108,100,32,
-    104,97,118,101,32,97,32,39,108,101,118,101,108,39,32,111,
-    102,32,50,41,46,10,10,32,32,32,32,114,33,0,0,0,
-    78,114,121,0,0,0,41,8,114,186,0,0,0,114,196,0,
-    0,0,218,9,112,97,114,116,105,116,105,111,110,114,167,0,
-    0,0,114,14,0,0,0,114,21,0,0,0,114,1,0,0,
-    0,114,194,0,0,0,41,9,114,15,0,0,0,114,195,0,
-    0,0,218,6,108,111,99,97,108,115,114,192,0,0,0,114,
-    170,0,0,0,114,89,0,0,0,90,8,103,108,111,98,97,
-    108,115,95,114,169,0,0,0,90,7,99,117,116,95,111,102,
-    102,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,10,95,95,105,109,112,111,114,116,95,95,19,4,0,0,
-    115,26,0,0,0,0,11,12,1,15,2,24,1,12,1,18,
-    1,6,3,12,1,23,1,6,1,4,4,35,3,40,2,114,
-    199,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0,
-    0,3,0,0,0,67,0,0,0,115,53,0,0,0,116,0,
-    0,106,1,0,124,0,0,131,1,0,125,1,0,124,1,0,
-    100,0,0,107,8,0,114,43,0,116,2,0,100,1,0,124,
-    0,0,23,131,1,0,130,1,0,116,3,0,124,1,0,131,
-    1,0,83,41,2,78,122,25,110,111,32,98,117,105,108,116,
-    45,105,110,32,109,111,100,117,108,101,32,110,97,109,101,100,
-    32,41,4,114,150,0,0,0,114,154,0,0,0,114,77,0,
-    0,0,114,149,0,0,0,41,2,114,15,0,0,0,114,88,
+    25,131,1,0,24,125,8,0,116,4,0,106,5,0,124,5,
+    0,106,6,0,100,2,0,116,3,0,124,5,0,106,6,0,
+    131,1,0,124,8,0,24,133,2,0,25,25,83,110,16,0,
+    116,7,0,124,5,0,124,3,0,116,0,0,131,3,0,83,
+    100,2,0,83,41,4,97,215,1,0,0,73,109,112,111,114,
+    116,32,97,32,109,111,100,117,108,101,46,10,10,32,32,32,
+    32,84,104,101,32,39,103,108,111,98,97,108,115,39,32,97,
+    114,103,117,109,101,110,116,32,105,115,32,117,115,101,100,32,
+    116,111,32,105,110,102,101,114,32,119,104,101,114,101,32,116,
+    104,101,32,105,109,112,111,114,116,32,105,115,32,111,99,99,
+    117,114,114,105,110,103,32,102,114,111,109,10,32,32,32,32,
+    116,111,32,104,97,110,100,108,101,32,114,101,108,97,116,105,
+    118,101,32,105,109,112,111,114,116,115,46,32,84,104,101,32,
+    39,108,111,99,97,108,115,39,32,97,114,103,117,109,101,110,
+    116,32,105,115,32,105,103,110,111,114,101,100,46,32,84,104,
+    101,10,32,32,32,32,39,102,114,111,109,108,105,115,116,39,
+    32,97,114,103,117,109,101,110,116,32,115,112,101,99,105,102,
+    105,101,115,32,119,104,97,116,32,115,104,111,117,108,100,32,
+    101,120,105,115,116,32,97,115,32,97,116,116,114,105,98,117,
+    116,101,115,32,111,110,32,116,104,101,32,109,111,100,117,108,
+    101,10,32,32,32,32,98,101,105,110,103,32,105,109,112,111,
+    114,116,101,100,32,40,101,46,103,46,32,96,96,102,114,111,
+    109,32,109,111,100,117,108,101,32,105,109,112,111,114,116,32,
+    60,102,114,111,109,108,105,115,116,62,96,96,41,46,32,32,
+    84,104,101,32,39,108,101,118,101,108,39,10,32,32,32,32,
+    97,114,103,117,109,101,110,116,32,114,101,112,114,101,115,101,
+    110,116,115,32,116,104,101,32,112,97,99,107,97,103,101,32,
+    108,111,99,97,116,105,111,110,32,116,111,32,105,109,112,111,
+    114,116,32,102,114,111,109,32,105,110,32,97,32,114,101,108,
+    97,116,105,118,101,10,32,32,32,32,105,109,112,111,114,116,
+    32,40,101,46,103,46,32,96,96,102,114,111,109,32,46,46,
+    112,107,103,32,105,109,112,111,114,116,32,109,111,100,96,96,
+    32,119,111,117,108,100,32,104,97,118,101,32,97,32,39,108,
+    101,118,101,108,39,32,111,102,32,50,41,46,10,10,32,32,
+    32,32,114,33,0,0,0,78,114,121,0,0,0,41,8,114,
+    186,0,0,0,114,196,0,0,0,218,9,112,97,114,116,105,
+    116,105,111,110,114,167,0,0,0,114,14,0,0,0,114,21,
+    0,0,0,114,1,0,0,0,114,194,0,0,0,41,9,114,
+    15,0,0,0,114,195,0,0,0,218,6,108,111,99,97,108,
+    115,114,192,0,0,0,114,170,0,0,0,114,89,0,0,0,
+    90,8,103,108,111,98,97,108,115,95,114,169,0,0,0,90,
+    7,99,117,116,95,111,102,102,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,218,10,95,95,105,109,112,111,114,
+    116,95,95,19,4,0,0,115,26,0,0,0,0,11,12,1,
+    15,2,24,1,12,1,18,1,6,3,12,1,23,1,6,1,
+    4,4,35,3,40,2,114,199,0,0,0,99,1,0,0,0,
+    0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,
+    115,53,0,0,0,116,0,0,106,1,0,124,0,0,131,1,
+    0,125,1,0,124,1,0,100,0,0,107,8,0,114,43,0,
+    116,2,0,100,1,0,124,0,0,23,131,1,0,130,1,0,
+    116,3,0,124,1,0,131,1,0,83,41,2,78,122,25,110,
+    111,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,
+    101,32,110,97,109,101,100,32,41,4,114,150,0,0,0,114,
+    154,0,0,0,114,77,0,0,0,114,149,0,0,0,41,2,
+    114,15,0,0,0,114,88,0,0,0,114,10,0,0,0,114,
+    10,0,0,0,114,11,0,0,0,218,18,95,98,117,105,108,
+    116,105,110,95,102,114,111,109,95,110,97,109,101,54,4,0,
+    0,115,8,0,0,0,0,1,15,1,12,1,16,1,114,200,
+    0,0,0,99,2,0,0,0,0,0,0,0,12,0,0,0,
+    12,0,0,0,67,0,0,0,115,74,1,0,0,124,1,0,
+    97,0,0,124,0,0,97,1,0,116,2,0,116,1,0,131,
+    1,0,125,2,0,120,123,0,116,1,0,106,3,0,106,4,
+    0,131,0,0,68,93,106,0,92,2,0,125,3,0,125,4,
+    0,116,5,0,124,4,0,124,2,0,131,2,0,114,40,0,
+    124,3,0,116,1,0,106,6,0,107,6,0,114,91,0,116,
+    7,0,125,5,0,110,27,0,116,0,0,106,8,0,124,3,
+    0,131,1,0,114,40,0,116,9,0,125,5,0,110,3,0,
+    113,40,0,116,10,0,124,4,0,124,5,0,131,2,0,125,
+    6,0,116,11,0,124,6,0,124,4,0,131,2,0,1,113,
+    40,0,87,116,1,0,106,3,0,116,12,0,25,125,7,0,
+    120,73,0,100,5,0,68,93,65,0,125,8,0,124,8,0,
+    116,1,0,106,3,0,107,7,0,114,206,0,116,13,0,124,
+    8,0,131,1,0,125,9,0,110,13,0,116,1,0,106,3,
+    0,124,8,0,25,125,9,0,116,14,0,124,7,0,124,8,
+    0,124,9,0,131,3,0,1,113,170,0,87,121,16,0,116,
+    13,0,100,2,0,131,1,0,125,10,0,87,110,24,0,4,
+    116,15,0,107,10,0,114,25,1,1,1,1,100,3,0,125,
+    10,0,89,110,1,0,88,116,14,0,124,7,0,100,2,0,
+    124,10,0,131,3,0,1,116,13,0,100,4,0,131,1,0,
+    125,11,0,116,14,0,124,7,0,100,4,0,124,11,0,131,
+    3,0,1,100,3,0,83,41,6,122,250,83,101,116,117,112,
+    32,105,109,112,111,114,116,108,105,98,32,98,121,32,105,109,
+    112,111,114,116,105,110,103,32,110,101,101,100,101,100,32,98,
+    117,105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,
+    97,110,100,32,105,110,106,101,99,116,105,110,103,32,116,104,
+    101,109,10,32,32,32,32,105,110,116,111,32,116,104,101,32,
+    103,108,111,98,97,108,32,110,97,109,101,115,112,97,99,101,
+    46,10,10,32,32,32,32,65,115,32,115,121,115,32,105,115,
+    32,110,101,101,100,101,100,32,102,111,114,32,115,121,115,46,
+    109,111,100,117,108,101,115,32,97,99,99,101,115,115,32,97,
+    110,100,32,95,105,109,112,32,105,115,32,110,101,101,100,101,
+    100,32,116,111,32,108,111,97,100,32,98,117,105,108,116,45,
+    105,110,10,32,32,32,32,109,111,100,117,108,101,115,44,32,
+    116,104,111,115,101,32,116,119,111,32,109,111,100,117,108,101,
+    115,32,109,117,115,116,32,98,101,32,101,120,112,108,105,99,
+    105,116,108,121,32,112,97,115,115,101,100,32,105,110,46,10,
+    10,32,32,32,32,114,141,0,0,0,114,34,0,0,0,78,
+    114,62,0,0,0,41,1,122,9,95,119,97,114,110,105,110,
+    103,115,41,16,114,57,0,0,0,114,14,0,0,0,114,13,
+    0,0,0,114,21,0,0,0,218,5,105,116,101,109,115,114,
+    177,0,0,0,114,76,0,0,0,114,150,0,0,0,114,82,
+    0,0,0,114,160,0,0,0,114,132,0,0,0,114,137,0,
+    0,0,114,1,0,0,0,114,200,0,0,0,114,5,0,0,
+    0,114,77,0,0,0,41,12,218,10,115,121,115,95,109,111,
+    100,117,108,101,218,11,95,105,109,112,95,109,111,100,117,108,
+    101,90,11,109,111,100,117,108,101,95,116,121,112,101,114,15,
+    0,0,0,114,89,0,0,0,114,99,0,0,0,114,88,0,
+    0,0,90,11,115,101,108,102,95,109,111,100,117,108,101,90,
+    12,98,117,105,108,116,105,110,95,110,97,109,101,90,14,98,
+    117,105,108,116,105,110,95,109,111,100,117,108,101,90,13,116,
+    104,114,101,97,100,95,109,111,100,117,108,101,90,14,119,101,
+    97,107,114,101,102,95,109,111,100,117,108,101,114,10,0,0,
+    0,114,10,0,0,0,114,11,0,0,0,218,6,95,115,101,
+    116,117,112,61,4,0,0,115,50,0,0,0,0,9,6,1,
+    6,3,12,1,28,1,15,1,15,1,9,1,15,1,9,2,
+    3,1,15,1,17,3,13,1,13,1,15,1,15,2,13,1,
+    20,3,3,1,16,1,13,2,11,1,16,3,12,1,114,204,
+    0,0,0,99,2,0,0,0,0,0,0,0,3,0,0,0,
+    3,0,0,0,67,0,0,0,115,87,0,0,0,116,0,0,
+    124,0,0,124,1,0,131,2,0,1,116,1,0,106,2,0,
+    106,3,0,116,4,0,131,1,0,1,116,1,0,106,2,0,
+    106,3,0,116,5,0,131,1,0,1,100,1,0,100,2,0,
+    108,6,0,125,2,0,124,2,0,97,7,0,124,2,0,106,
+    8,0,116,1,0,106,9,0,116,10,0,25,131,1,0,1,
+    100,2,0,83,41,3,122,50,73,110,115,116,97,108,108,32,
+    105,109,112,111,114,116,108,105,98,32,97,115,32,116,104,101,
+    32,105,109,112,108,101,109,101,110,116,97,116,105,111,110,32,
+    111,102,32,105,109,112,111,114,116,46,114,33,0,0,0,78,
+    41,11,114,204,0,0,0,114,14,0,0,0,114,174,0,0,
+    0,114,113,0,0,0,114,150,0,0,0,114,160,0,0,0,
+    218,26,95,102,114,111,122,101,110,95,105,109,112,111,114,116,
+    108,105,98,95,101,120,116,101,114,110,97,108,114,119,0,0,
+    0,218,8,95,105,110,115,116,97,108,108,114,21,0,0,0,
+    114,1,0,0,0,41,3,114,202,0,0,0,114,203,0,0,
+    0,114,205,0,0,0,114,10,0,0,0,114,10,0,0,0,
+    114,11,0,0,0,114,206,0,0,0,108,4,0,0,115,12,
+    0,0,0,0,2,13,2,16,1,16,3,12,1,6,1,114,
+    206,0,0,0,41,51,114,3,0,0,0,114,119,0,0,0,
+    114,12,0,0,0,114,16,0,0,0,114,17,0,0,0,114,
+    59,0,0,0,114,41,0,0,0,114,48,0,0,0,114,31,
+    0,0,0,114,32,0,0,0,114,53,0,0,0,114,54,0,
+    0,0,114,56,0,0,0,114,63,0,0,0,114,65,0,0,
+    0,114,75,0,0,0,114,81,0,0,0,114,84,0,0,0,
+    114,90,0,0,0,114,101,0,0,0,114,102,0,0,0,114,
+    106,0,0,0,114,85,0,0,0,218,6,111,98,106,101,99,
+    116,90,9,95,80,79,80,85,76,65,84,69,114,132,0,0,
+    0,114,137,0,0,0,114,144,0,0,0,114,97,0,0,0,
+    114,86,0,0,0,114,148,0,0,0,114,149,0,0,0,114,
+    87,0,0,0,114,150,0,0,0,114,160,0,0,0,114,165,
+    0,0,0,114,171,0,0,0,114,173,0,0,0,114,176,0,
+    0,0,114,181,0,0,0,114,191,0,0,0,114,182,0,0,
+    0,114,184,0,0,0,114,185,0,0,0,114,186,0,0,0,
+    114,194,0,0,0,114,196,0,0,0,114,199,0,0,0,114,
+    200,0,0,0,114,204,0,0,0,114,206,0,0,0,114,10,
     0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
-    0,0,218,18,95,98,117,105,108,116,105,110,95,102,114,111,
-    109,95,110,97,109,101,54,4,0,0,115,8,0,0,0,0,
-    1,15,1,12,1,16,1,114,200,0,0,0,99,2,0,0,
-    0,0,0,0,0,12,0,0,0,12,0,0,0,67,0,0,
-    0,115,74,1,0,0,124,1,0,97,0,0,124,0,0,97,
-    1,0,116,2,0,116,1,0,131,1,0,125,2,0,120,123,
-    0,116,1,0,106,3,0,106,4,0,131,0,0,68,93,106,
-    0,92,2,0,125,3,0,125,4,0,116,5,0,124,4,0,
-    124,2,0,131,2,0,114,40,0,124,3,0,116,1,0,106,
-    6,0,107,6,0,114,91,0,116,7,0,125,5,0,110,27,
-    0,116,0,0,106,8,0,124,3,0,131,1,0,114,40,0,
-    116,9,0,125,5,0,110,3,0,113,40,0,116,10,0,124,
-    4,0,124,5,0,131,2,0,125,6,0,116,11,0,124,6,
-    0,124,4,0,131,2,0,1,113,40,0,87,116,1,0,106,
-    3,0,116,12,0,25,125,7,0,120,73,0,100,5,0,68,
-    93,65,0,125,8,0,124,8,0,116,1,0,106,3,0,107,
-    7,0,114,206,0,116,13,0,124,8,0,131,1,0,125,9,
-    0,110,13,0,116,1,0,106,3,0,124,8,0,25,125,9,
-    0,116,14,0,124,7,0,124,8,0,124,9,0,131,3,0,
-    1,113,170,0,87,121,16,0,116,13,0,100,2,0,131,1,
-    0,125,10,0,87,110,24,0,4,116,15,0,107,10,0,114,
-    25,1,1,1,1,100,3,0,125,10,0,89,110,1,0,88,
-    116,14,0,124,7,0,100,2,0,124,10,0,131,3,0,1,
-    116,13,0,100,4,0,131,1,0,125,11,0,116,14,0,124,
-    7,0,100,4,0,124,11,0,131,3,0,1,100,3,0,83,
-    41,6,122,250,83,101,116,117,112,32,105,109,112,111,114,116,
-    108,105,98,32,98,121,32,105,109,112,111,114,116,105,110,103,
-    32,110,101,101,100,101,100,32,98,117,105,108,116,45,105,110,
-    32,109,111,100,117,108,101,115,32,97,110,100,32,105,110,106,
-    101,99,116,105,110,103,32,116,104,101,109,10,32,32,32,32,
-    105,110,116,111,32,116,104,101,32,103,108,111,98,97,108,32,
-    110,97,109,101,115,112,97,99,101,46,10,10,32,32,32,32,
-    65,115,32,115,121,115,32,105,115,32,110,101,101,100,101,100,
-    32,102,111,114,32,115,121,115,46,109,111,100,117,108,101,115,
-    32,97,99,99,101,115,115,32,97,110,100,32,95,105,109,112,
-    32,105,115,32,110,101,101,100,101,100,32,116,111,32,108,111,
-    97,100,32,98,117,105,108,116,45,105,110,10,32,32,32,32,
-    109,111,100,117,108,101,115,44,32,116,104,111,115,101,32,116,
-    119,111,32,109,111,100,117,108,101,115,32,109,117,115,116,32,
-    98,101,32,101,120,112,108,105,99,105,116,108,121,32,112,97,
-    115,115,101,100,32,105,110,46,10,10,32,32,32,32,114,141,
-    0,0,0,114,34,0,0,0,78,114,62,0,0,0,41,1,
-    122,9,95,119,97,114,110,105,110,103,115,41,16,114,57,0,
-    0,0,114,14,0,0,0,114,13,0,0,0,114,21,0,0,
-    0,218,5,105,116,101,109,115,114,177,0,0,0,114,76,0,
-    0,0,114,150,0,0,0,114,82,0,0,0,114,160,0,0,
-    0,114,132,0,0,0,114,137,0,0,0,114,1,0,0,0,
-    114,200,0,0,0,114,5,0,0,0,114,77,0,0,0,41,
-    12,218,10,115,121,115,95,109,111,100,117,108,101,218,11,95,
-    105,109,112,95,109,111,100,117,108,101,90,11,109,111,100,117,
-    108,101,95,116,121,112,101,114,15,0,0,0,114,89,0,0,
-    0,114,99,0,0,0,114,88,0,0,0,90,11,115,101,108,
-    102,95,109,111,100,117,108,101,90,12,98,117,105,108,116,105,
-    110,95,110,97,109,101,90,14,98,117,105,108,116,105,110,95,
-    109,111,100,117,108,101,90,13,116,104,114,101,97,100,95,109,
-    111,100,117,108,101,90,14,119,101,97,107,114,101,102,95,109,
-    111,100,117,108,101,114,10,0,0,0,114,10,0,0,0,114,
-    11,0,0,0,218,6,95,115,101,116,117,112,61,4,0,0,
-    115,50,0,0,0,0,9,6,1,6,3,12,1,28,1,15,
-    1,15,1,9,1,15,1,9,2,3,1,15,1,17,3,13,
-    1,13,1,15,1,15,2,13,1,20,3,3,1,16,1,13,
-    2,11,1,16,3,12,1,114,204,0,0,0,99,2,0,0,
-    0,0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,
-    0,115,87,0,0,0,116,0,0,124,0,0,124,1,0,131,
-    2,0,1,116,1,0,106,2,0,106,3,0,116,4,0,131,
-    1,0,1,116,1,0,106,2,0,106,3,0,116,5,0,131,
-    1,0,1,100,1,0,100,2,0,108,6,0,125,2,0,124,
-    2,0,97,7,0,124,2,0,106,8,0,116,1,0,106,9,
-    0,116,10,0,25,131,1,0,1,100,2,0,83,41,3,122,
-    50,73,110,115,116,97,108,108,32,105,109,112,111,114,116,108,
-    105,98,32,97,115,32,116,104,101,32,105,109,112,108,101,109,
-    101,110,116,97,116,105,111,110,32,111,102,32,105,109,112,111,
-    114,116,46,114,33,0,0,0,78,41,11,114,204,0,0,0,
-    114,14,0,0,0,114,174,0,0,0,114,113,0,0,0,114,
-    150,0,0,0,114,160,0,0,0,218,26,95,102,114,111,122,
-    101,110,95,105,109,112,111,114,116,108,105,98,95,101,120,116,
-    101,114,110,97,108,114,119,0,0,0,218,8,95,105,110,115,
-    116,97,108,108,114,21,0,0,0,114,1,0,0,0,41,3,
-    114,202,0,0,0,114,203,0,0,0,114,205,0,0,0,114,
-    10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,206,
-    0,0,0,108,4,0,0,115,12,0,0,0,0,2,13,2,
-    16,1,16,3,12,1,6,1,114,206,0,0,0,41,51,114,
-    3,0,0,0,114,119,0,0,0,114,12,0,0,0,114,16,
-    0,0,0,114,17,0,0,0,114,59,0,0,0,114,41,0,
-    0,0,114,48,0,0,0,114,31,0,0,0,114,32,0,0,
-    0,114,53,0,0,0,114,54,0,0,0,114,56,0,0,0,
-    114,63,0,0,0,114,65,0,0,0,114,75,0,0,0,114,
-    81,0,0,0,114,84,0,0,0,114,90,0,0,0,114,101,
-    0,0,0,114,102,0,0,0,114,106,0,0,0,114,85,0,
-    0,0,218,6,111,98,106,101,99,116,90,9,95,80,79,80,
-    85,76,65,84,69,114,132,0,0,0,114,137,0,0,0,114,
-    144,0,0,0,114,97,0,0,0,114,86,0,0,0,114,148,
-    0,0,0,114,149,0,0,0,114,87,0,0,0,114,150,0,
-    0,0,114,160,0,0,0,114,165,0,0,0,114,171,0,0,
-    0,114,173,0,0,0,114,176,0,0,0,114,181,0,0,0,
-    114,191,0,0,0,114,182,0,0,0,114,184,0,0,0,114,
-    185,0,0,0,114,186,0,0,0,114,194,0,0,0,114,196,
-    0,0,0,114,199,0,0,0,114,200,0,0,0,114,204,0,
-    0,0,114,206,0,0,0,114,10,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,218,8,60,109,111,
-    100,117,108,101,62,8,0,0,0,115,96,0,0,0,6,17,
-    6,2,12,8,12,4,19,20,6,2,6,3,22,4,19,68,
-    19,21,19,19,12,19,12,19,12,11,18,8,12,11,12,12,
-    12,16,12,36,19,27,19,101,24,26,9,3,18,45,18,60,
-    12,18,12,17,12,25,12,29,12,23,12,16,19,73,19,77,
-    19,13,12,9,12,9,15,40,12,17,6,1,10,2,12,27,
-    12,6,18,24,12,32,12,15,24,35,12,7,12,47,
+    0,0,218,8,60,109,111,100,117,108,101,62,8,0,0,0,
+    115,96,0,0,0,6,17,6,2,12,8,12,4,19,20,6,
+    2,6,3,22,4,19,68,19,21,19,19,12,19,12,19,12,
+    11,18,8,12,11,12,12,12,16,12,36,19,27,19,101,24,
+    26,9,3,18,45,18,60,12,18,12,17,12,25,12,29,12,
+    23,12,16,19,73,19,77,19,13,12,9,12,9,15,40,12,
+    17,6,1,10,2,12,27,12,6,18,24,12,32,12,15,24,
+    35,12,7,12,47,
 };
index b20ce17..47f5c62 100644 (file)
@@ -369,7 +369,7 @@ const unsigned char _Py_M__importlib_external[] = {
     116,97,103,90,15,97,108,109,111,115,116,95,102,105,108,101,
     110,97,109,101,114,4,0,0,0,114,4,0,0,0,114,5,
     0,0,0,218,17,99,97,99,104,101,95,102,114,111,109,95,
-    115,111,117,114,99,101,243,0,0,0,115,46,0,0,0,0,
+    115,111,117,114,99,101,246,0,0,0,115,46,0,0,0,0,
     18,12,1,9,1,7,1,12,1,6,1,12,1,18,1,18,
     1,24,1,12,1,12,1,12,1,36,1,12,1,18,1,9,
     2,12,1,12,1,12,1,12,1,21,1,21,1,114,79,0,
@@ -448,7 +448,7 @@ const unsigned char _Py_M__importlib_external[] = {
     95,108,101,118,101,108,90,13,98,97,115,101,95,102,105,108,
     101,110,97,109,101,114,4,0,0,0,114,4,0,0,0,114,
     5,0,0,0,218,17,115,111,117,114,99,101,95,102,114,111,
-    109,95,99,97,99,104,101,31,1,0,0,115,44,0,0,0,
+    109,95,99,97,99,104,101,34,1,0,0,115,44,0,0,0,
     0,9,18,1,12,1,18,1,18,1,12,1,9,1,15,1,
     15,1,12,1,9,1,15,1,12,1,22,1,15,1,9,1,
     12,1,22,1,12,1,9,1,12,1,19,1,114,85,0,0,
@@ -486,7 +486,7 @@ const unsigned char _Py_M__importlib_external[] = {
     115,105,111,110,218,11,115,111,117,114,99,101,95,112,97,116,
     104,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
     218,15,95,103,101,116,95,115,111,117,114,99,101,102,105,108,
-    101,64,1,0,0,115,20,0,0,0,0,7,18,1,4,1,
+    101,67,1,0,0,115,20,0,0,0,0,7,18,1,4,1,
     24,1,35,1,4,1,3,1,16,1,19,1,21,1,114,91,
     0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0,
     11,0,0,0,67,0,0,0,115,92,0,0,0,124,0,0,
@@ -500,7 +500,7 @@ const unsigned char _Py_M__importlib_external[] = {
     84,0,0,0,114,79,0,0,0,114,66,0,0,0,114,74,
     0,0,0,41,1,218,8,102,105,108,101,110,97,109,101,114,
     4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,11,
-    95,103,101,116,95,99,97,99,104,101,100,83,1,0,0,115,
+    95,103,101,116,95,99,97,99,104,101,100,86,1,0,0,115,
     16,0,0,0,0,1,21,1,3,1,14,1,13,1,8,1,
     21,1,4,2,114,95,0,0,0,99,1,0,0,0,0,0,
     0,0,2,0,0,0,11,0,0,0,67,0,0,0,115,60,
@@ -515,7 +515,7 @@ const unsigned char _Py_M__importlib_external[] = {
     41,3,114,39,0,0,0,114,41,0,0,0,114,40,0,0,
     0,41,2,114,35,0,0,0,114,42,0,0,0,114,4,0,
     0,0,114,4,0,0,0,114,5,0,0,0,218,10,95,99,
-    97,108,99,95,109,111,100,101,95,1,0,0,115,12,0,0,
+    97,108,99,95,109,111,100,101,98,1,0,0,115,12,0,0,
     0,0,2,3,1,19,1,13,1,11,3,10,1,114,97,0,
     0,0,218,9,118,101,114,98,111,115,105,116,121,114,29,0,
     0,0,99,1,0,0,0,1,0,0,0,3,0,0,0,4,
@@ -536,7 +536,7 @@ const unsigned char _Py_M__importlib_external[] = {
     218,6,115,116,100,101,114,114,41,3,114,75,0,0,0,114,
     98,0,0,0,218,4,97,114,103,115,114,4,0,0,0,114,
     4,0,0,0,114,5,0,0,0,218,16,95,118,101,114,98,
-    111,115,101,95,109,101,115,115,97,103,101,107,1,0,0,115,
+    111,115,101,95,109,101,115,115,97,103,101,110,1,0,0,115,
     8,0,0,0,0,2,18,1,15,1,10,1,114,105,0,0,
     0,99,1,0,0,0,0,0,0,0,3,0,0,0,11,0,
     0,0,3,0,0,0,115,84,0,0,0,100,1,0,135,0,
@@ -576,7 +576,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,90,6,107,119,97,114,103,115,41,1,218,6,109,101,
     116,104,111,100,114,4,0,0,0,114,5,0,0,0,218,19,
     95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112,
-    112,101,114,123,1,0,0,115,12,0,0,0,0,1,12,1,
+    112,101,114,126,1,0,0,115,12,0,0,0,0,1,12,1,
     12,1,15,1,6,1,25,1,122,40,95,99,104,101,99,107,
     95,110,97,109,101,46,60,108,111,99,97,108,115,62,46,95,
     99,104,101,99,107,95,110,97,109,101,95,119,114,97,112,112,
@@ -595,7 +595,7 @@ const unsigned char _Py_M__importlib_external[] = {
     116,97,116,116,114,218,8,95,95,100,105,99,116,95,95,218,
     6,117,112,100,97,116,101,41,3,90,3,110,101,119,90,3,
     111,108,100,114,52,0,0,0,114,4,0,0,0,114,4,0,
-    0,0,114,5,0,0,0,218,5,95,119,114,97,112,134,1,
+    0,0,114,5,0,0,0,218,5,95,119,114,97,112,137,1,
     0,0,115,8,0,0,0,0,1,25,1,15,1,29,1,122,
     26,95,99,104,101,99,107,95,110,97,109,101,46,60,108,111,
     99,97,108,115,62,46,95,119,114,97,112,41,3,218,10,95,
@@ -603,7 +603,7 @@ const unsigned char _Py_M__importlib_external[] = {
     78,97,109,101,69,114,114,111,114,41,3,114,109,0,0,0,
     114,110,0,0,0,114,120,0,0,0,114,4,0,0,0,41,
     1,114,109,0,0,0,114,5,0,0,0,218,11,95,99,104,
-    101,99,107,95,110,97,109,101,115,1,0,0,115,14,0,0,
+    101,99,107,95,110,97,109,101,118,1,0,0,115,14,0,0,
     0,0,8,21,7,3,1,13,1,13,2,17,5,13,1,114,
     123,0,0,0,99,2,0,0,0,0,0,0,0,5,0,0,
     0,4,0,0,0,67,0,0,0,115,84,0,0,0,124,0,
@@ -633,7 +633,7 @@ const unsigned char _Py_M__importlib_external[] = {
     218,8,112,111,114,116,105,111,110,115,218,3,109,115,103,114,
     4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,17,
     95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105,
-    109,143,1,0,0,115,10,0,0,0,0,10,21,1,24,1,
+    109,146,1,0,0,115,10,0,0,0,0,10,21,1,24,1,
     6,1,29,1,114,130,0,0,0,99,4,0,0,0,0,0,
     0,0,11,0,0,0,19,0,0,0,67,0,0,0,115,240,
     1,0,0,105,0,0,125,4,0,124,2,0,100,1,0,107,
@@ -718,7 +718,7 @@ const unsigned char _Py_M__importlib_external[] = {
     109,101,218,11,115,111,117,114,99,101,95,115,105,122,101,114,
     4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,25,
     95,118,97,108,105,100,97,116,101,95,98,121,116,101,99,111,
-    100,101,95,104,101,97,100,101,114,160,1,0,0,115,76,0,
+    100,101,95,104,101,97,100,101,114,163,1,0,0,115,76,0,
     0,0,0,11,6,1,12,1,13,3,6,1,12,1,10,1,
     16,1,16,1,16,1,12,1,18,1,13,1,18,1,18,1,
     15,1,13,1,15,1,18,1,15,1,13,1,12,1,12,1,
@@ -749,7 +749,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,106,0,0,0,114,89,0,0,0,114,90,0,0,0,218,
     4,99,111,100,101,114,4,0,0,0,114,4,0,0,0,114,
     5,0,0,0,218,17,95,99,111,109,112,105,108,101,95,98,
-    121,116,101,99,111,100,101,215,1,0,0,115,16,0,0,0,
+    121,116,101,99,111,100,101,218,1,0,0,115,16,0,0,0,
     0,2,15,1,15,1,13,1,12,1,16,1,4,2,18,1,
     114,147,0,0,0,114,59,0,0,0,99,3,0,0,0,0,
     0,0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,
@@ -769,7 +769,7 @@ const unsigned char _Py_M__importlib_external[] = {
     4,114,146,0,0,0,114,133,0,0,0,114,140,0,0,0,
     114,53,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
     5,0,0,0,218,17,95,99,111,100,101,95,116,111,95,98,
-    121,116,101,99,111,100,101,227,1,0,0,115,10,0,0,0,
+    121,116,101,99,111,100,101,230,1,0,0,115,10,0,0,0,
     0,3,12,1,19,1,19,1,22,1,114,150,0,0,0,99,
     1,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,
     67,0,0,0,115,89,0,0,0,100,1,0,100,2,0,108,
@@ -798,7 +798,7 @@ const unsigned char _Py_M__importlib_external[] = {
     100,105,110,103,90,15,110,101,119,108,105,110,101,95,100,101,
     99,111,100,101,114,114,4,0,0,0,114,4,0,0,0,114,
     5,0,0,0,218,13,100,101,99,111,100,101,95,115,111,117,
-    114,99,101,237,1,0,0,115,10,0,0,0,0,5,12,1,
+    114,99,101,240,1,0,0,115,10,0,0,0,0,5,12,1,
     18,1,15,1,18,1,114,155,0,0,0,114,127,0,0,0,
     218,26,115,117,98,109,111,100,117,108,101,95,115,101,97,114,
     99,104,95,108,111,99,97,116,105,111,110,115,99,2,0,0,
@@ -863,7 +863,7 @@ const unsigned char _Py_M__importlib_external[] = {
     159,0,0,0,90,7,100,105,114,110,97,109,101,114,4,0,
     0,0,114,4,0,0,0,114,5,0,0,0,218,23,115,112,
     101,99,95,102,114,111,109,95,102,105,108,101,95,108,111,99,
-    97,116,105,111,110,254,1,0,0,115,60,0,0,0,0,12,
+    97,116,105,111,110,1,2,0,0,115,60,0,0,0,0,12,
     12,4,6,1,15,2,3,1,19,1,13,1,5,8,24,1,
     9,3,12,1,22,1,21,1,15,1,9,1,5,2,4,3,
     12,2,15,1,3,1,19,1,13,1,5,2,6,1,12,2,
@@ -903,7 +903,7 @@ const unsigned char _Py_M__importlib_external[] = {
     79,67,65,76,95,77,65,67,72,73,78,69,41,2,218,3,
     99,108,115,218,3,107,101,121,114,4,0,0,0,114,4,0,
     0,0,114,5,0,0,0,218,14,95,111,112,101,110,95,114,
-    101,103,105,115,116,114,121,76,2,0,0,115,8,0,0,0,
+    101,103,105,115,116,114,121,79,2,0,0,115,8,0,0,0,
     0,2,3,1,23,1,13,1,122,36,87,105,110,100,111,119,
     115,82,101,103,105,115,116,114,121,70,105,110,100,101,114,46,
     95,111,112,101,110,95,114,101,103,105,115,116,114,121,99,2,
@@ -930,7 +930,7 @@ const unsigned char _Py_M__importlib_external[] = {
     171,0,0,0,90,4,104,107,101,121,218,8,102,105,108,101,
     112,97,116,104,114,4,0,0,0,114,4,0,0,0,114,5,
     0,0,0,218,16,95,115,101,97,114,99,104,95,114,101,103,
-    105,115,116,114,121,83,2,0,0,115,22,0,0,0,0,2,
+    105,115,116,114,121,86,2,0,0,115,22,0,0,0,0,2,
     9,1,12,2,9,1,15,1,22,1,3,1,18,1,29,1,
     13,1,9,1,122,38,87,105,110,100,111,119,115,82,101,103,
     105,115,116,114,121,70,105,110,100,101,114,46,95,115,101,97,
@@ -954,7 +954,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,35,0,0,0,218,6,116,97,114,103,101,116,114,177,0,
     0,0,114,127,0,0,0,114,166,0,0,0,114,164,0,0,
     0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
-    218,9,102,105,110,100,95,115,112,101,99,98,2,0,0,115,
+    218,9,102,105,110,100,95,115,112,101,99,101,2,0,0,115,
     26,0,0,0,0,2,15,1,12,1,4,1,3,1,14,1,
     13,1,9,1,22,1,21,1,9,1,15,1,9,1,122,31,
     87,105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,
@@ -974,7 +974,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,0,41,4,114,170,0,0,0,114,126,0,0,0,114,
     35,0,0,0,114,164,0,0,0,114,4,0,0,0,114,4,
     0,0,0,114,5,0,0,0,218,11,102,105,110,100,95,109,
-    111,100,117,108,101,114,2,0,0,115,8,0,0,0,0,7,
+    111,100,117,108,101,117,2,0,0,115,8,0,0,0,0,7,
     18,1,12,1,7,2,122,33,87,105,110,100,111,119,115,82,
     101,103,105,115,116,114,121,70,105,110,100,101,114,46,102,105,
     110,100,95,109,111,100,117,108,101,41,12,114,112,0,0,0,
@@ -983,7 +983,7 @@ const unsigned char _Py_M__importlib_external[] = {
     99,108,97,115,115,109,101,116,104,111,100,114,172,0,0,0,
     114,178,0,0,0,114,181,0,0,0,114,182,0,0,0,114,
     4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
-    0,0,0,114,168,0,0,0,64,2,0,0,115,20,0,0,
+    0,0,0,114,168,0,0,0,67,2,0,0,115,20,0,0,
     0,12,2,6,3,6,3,6,2,6,2,18,7,18,15,3,
     1,21,15,3,1,114,168,0,0,0,99,0,0,0,0,0,
     0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,
@@ -1021,7 +1021,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,0,114,94,0,0,0,90,13,102,105,108,101,110,97,
     109,101,95,98,97,115,101,90,9,116,97,105,108,95,110,97,
     109,101,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
-    0,114,159,0,0,0,133,2,0,0,115,8,0,0,0,0,
+    0,114,159,0,0,0,136,2,0,0,115,8,0,0,0,0,
     3,25,1,22,1,19,1,122,24,95,76,111,97,100,101,114,
     66,97,115,105,99,115,46,105,115,95,112,97,99,107,97,103,
     101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,
@@ -1031,7 +1031,7 @@ const unsigned char _Py_M__importlib_external[] = {
     117,108,101,32,99,114,101,97,116,105,111,110,46,78,114,4,
     0,0,0,41,2,114,108,0,0,0,114,164,0,0,0,114,
     4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,13,
-    99,114,101,97,116,101,95,109,111,100,117,108,101,141,2,0,
+    99,114,101,97,116,101,95,109,111,100,117,108,101,144,2,0,
     0,115,0,0,0,0,122,27,95,76,111,97,100,101,114,66,
     97,115,105,99,115,46,99,114,101,97,116,101,95,109,111,100,
     117,108,101,99,2,0,0,0,0,0,0,0,3,0,0,0,
@@ -1053,7 +1053,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,41,3,114,108,0,0,0,218,6,109,111,100,117,108,101,
     114,146,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
     5,0,0,0,218,11,101,120,101,99,95,109,111,100,117,108,
-    101,144,2,0,0,115,10,0,0,0,0,2,18,1,12,1,
+    101,147,2,0,0,115,10,0,0,0,0,2,18,1,12,1,
     9,1,15,1,122,25,95,76,111,97,100,101,114,66,97,115,
     105,99,115,46,101,120,101,99,95,109,111,100,117,108,101,99,
     2,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,
@@ -1062,14 +1062,14 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,0,218,17,95,108,111,97,100,95,109,111,100,117,108,
     101,95,115,104,105,109,41,2,114,108,0,0,0,114,126,0,
     0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
-    0,218,11,108,111,97,100,95,109,111,100,117,108,101,152,2,
+    0,218,11,108,111,97,100,95,109,111,100,117,108,101,155,2,
     0,0,115,2,0,0,0,0,1,122,25,95,76,111,97,100,
     101,114,66,97,115,105,99,115,46,108,111,97,100,95,109,111,
     100,117,108,101,78,41,8,114,112,0,0,0,114,111,0,0,
     0,114,113,0,0,0,114,114,0,0,0,114,159,0,0,0,
     114,186,0,0,0,114,191,0,0,0,114,193,0,0,0,114,
     4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
-    0,0,0,114,184,0,0,0,128,2,0,0,115,10,0,0,
+    0,0,0,114,184,0,0,0,131,2,0,0,115,10,0,0,
     0,12,3,6,2,12,8,12,3,12,8,114,184,0,0,0,
     99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,
     0,64,0,0,0,115,106,0,0,0,101,0,0,90,1,0,
@@ -1097,7 +1097,7 @@ const unsigned char _Py_M__importlib_external[] = {
     1,218,7,73,79,69,114,114,111,114,41,2,114,108,0,0,
     0,114,35,0,0,0,114,4,0,0,0,114,4,0,0,0,
     114,5,0,0,0,218,10,112,97,116,104,95,109,116,105,109,
-    101,158,2,0,0,115,2,0,0,0,0,6,122,23,83,111,
+    101,161,2,0,0,115,2,0,0,0,0,6,122,23,83,111,
     117,114,99,101,76,111,97,100,101,114,46,112,97,116,104,95,
     109,116,105,109,101,99,2,0,0,0,0,0,0,0,2,0,
     0,0,3,0,0,0,67,0,0,0,115,19,0,0,0,100,
@@ -1132,7 +1132,7 @@ const unsigned char _Py_M__importlib_external[] = {
     32,32,32,114,133,0,0,0,41,1,114,196,0,0,0,41,
     2,114,108,0,0,0,114,35,0,0,0,114,4,0,0,0,
     114,4,0,0,0,114,5,0,0,0,218,10,112,97,116,104,
-    95,115,116,97,116,115,166,2,0,0,115,2,0,0,0,0,
+    95,115,116,97,116,115,169,2,0,0,115,2,0,0,0,0,
     11,122,23,83,111,117,114,99,101,76,111,97,100,101,114,46,
     112,97,116,104,95,115,116,97,116,115,99,4,0,0,0,0,
     0,0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,
@@ -1156,7 +1156,7 @@ const unsigned char _Py_M__importlib_external[] = {
     90,0,0,0,90,10,99,97,99,104,101,95,112,97,116,104,
     114,53,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
     5,0,0,0,218,15,95,99,97,99,104,101,95,98,121,116,
-    101,99,111,100,101,179,2,0,0,115,2,0,0,0,0,8,
+    101,99,111,100,101,182,2,0,0,115,2,0,0,0,0,8,
     122,28,83,111,117,114,99,101,76,111,97,100,101,114,46,95,
     99,97,99,104,101,95,98,121,116,101,99,111,100,101,99,3,
     0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,67,
@@ -1173,7 +1173,7 @@ const unsigned char _Py_M__importlib_external[] = {
     32,32,32,32,32,32,78,114,4,0,0,0,41,3,114,108,
     0,0,0,114,35,0,0,0,114,53,0,0,0,114,4,0,
     0,0,114,4,0,0,0,114,5,0,0,0,114,198,0,0,
-    0,189,2,0,0,115,0,0,0,0,122,21,83,111,117,114,
+    0,192,2,0,0,115,0,0,0,0,122,21,83,111,117,114,
     99,101,76,111,97,100,101,114,46,115,101,116,95,100,97,116,
     97,99,2,0,0,0,0,0,0,0,5,0,0,0,16,0,
     0,0,67,0,0,0,115,105,0,0,0,124,0,0,106,0,
@@ -1195,7 +1195,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,114,126,0,0,0,114,35,0,0,0,114,153,0,0,
     0,218,3,101,120,99,114,4,0,0,0,114,4,0,0,0,
     114,5,0,0,0,218,10,103,101,116,95,115,111,117,114,99,
-    101,196,2,0,0,115,14,0,0,0,0,2,15,1,3,1,
+    101,199,2,0,0,115,14,0,0,0,0,2,15,1,3,1,
     19,1,18,1,9,1,31,1,122,23,83,111,117,114,99,101,
     76,111,97,100,101,114,46,103,101,116,95,115,111,117,114,99,
     101,218,9,95,111,112,116,105,109,105,122,101,114,29,0,0,
@@ -1217,7 +1217,7 @@ const unsigned char _Py_M__importlib_external[] = {
     101,41,4,114,108,0,0,0,114,53,0,0,0,114,35,0,
     0,0,114,203,0,0,0,114,4,0,0,0,114,4,0,0,
     0,114,5,0,0,0,218,14,115,111,117,114,99,101,95,116,
-    111,95,99,111,100,101,206,2,0,0,115,4,0,0,0,0,
+    111,95,99,111,100,101,209,2,0,0,115,4,0,0,0,0,
     5,21,1,122,27,83,111,117,114,99,101,76,111,97,100,101,
     114,46,115,111,117,114,99,101,95,116,111,95,99,111,100,101,
     99,2,0,0,0,0,0,0,0,10,0,0,0,43,0,0,
@@ -1278,7 +1278,7 @@ const unsigned char _Py_M__importlib_external[] = {
     98,121,116,101,115,95,100,97,116,97,114,153,0,0,0,90,
     11,99,111,100,101,95,111,98,106,101,99,116,114,4,0,0,
     0,114,4,0,0,0,114,5,0,0,0,114,187,0,0,0,
-    214,2,0,0,115,78,0,0,0,0,7,15,1,6,1,3,
+    217,2,0,0,115,78,0,0,0,0,7,15,1,6,1,3,
     1,16,1,13,1,11,2,3,1,19,1,13,1,5,2,16,
     1,3,1,19,1,13,1,5,2,3,1,9,1,12,1,13,
     1,19,1,5,2,9,1,7,1,15,1,6,1,7,1,15,
@@ -1290,7 +1290,7 @@ const unsigned char _Py_M__importlib_external[] = {
     199,0,0,0,114,198,0,0,0,114,202,0,0,0,114,206,
     0,0,0,114,187,0,0,0,114,4,0,0,0,114,4,0,
     0,0,114,4,0,0,0,114,5,0,0,0,114,194,0,0,
-    0,156,2,0,0,115,14,0,0,0,12,2,12,8,12,13,
+    0,159,2,0,0,115,14,0,0,0,12,2,12,8,12,13,
     12,10,12,7,12,10,18,8,114,194,0,0,0,99,0,0,
     0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,
     0,0,115,112,0,0,0,101,0,0,90,1,0,100,0,0,
@@ -1318,7 +1318,7 @@ const unsigned char _Py_M__importlib_external[] = {
     32,32,32,32,32,32,102,105,110,100,101,114,46,78,41,2,
     114,106,0,0,0,114,35,0,0,0,41,3,114,108,0,0,
     0,114,126,0,0,0,114,35,0,0,0,114,4,0,0,0,
-    114,4,0,0,0,114,5,0,0,0,114,185,0,0,0,15,
+    114,4,0,0,0,114,5,0,0,0,114,185,0,0,0,18,
     3,0,0,115,4,0,0,0,0,3,9,1,122,19,70,105,
     108,101,76,111,97,100,101,114,46,95,95,105,110,105,116,95,
     95,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0,
@@ -1328,7 +1328,7 @@ const unsigned char _Py_M__importlib_external[] = {
     41,2,218,9,95,95,99,108,97,115,115,95,95,114,118,0,
     0,0,41,2,114,108,0,0,0,218,5,111,116,104,101,114,
     114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,
-    6,95,95,101,113,95,95,21,3,0,0,115,4,0,0,0,
+    6,95,95,101,113,95,95,24,3,0,0,115,4,0,0,0,
     0,1,18,1,122,17,70,105,108,101,76,111,97,100,101,114,
     46,95,95,101,113,95,95,99,1,0,0,0,0,0,0,0,
     1,0,0,0,3,0,0,0,67,0,0,0,115,26,0,0,
@@ -1337,7 +1337,7 @@ const unsigned char _Py_M__importlib_external[] = {
     218,4,104,97,115,104,114,106,0,0,0,114,35,0,0,0,
     41,1,114,108,0,0,0,114,4,0,0,0,114,4,0,0,
     0,114,5,0,0,0,218,8,95,95,104,97,115,104,95,95,
-    25,3,0,0,115,2,0,0,0,0,1,122,19,70,105,108,
+    28,3,0,0,115,2,0,0,0,0,1,122,19,70,105,108,
     101,76,111,97,100,101,114,46,95,95,104,97,115,104,95,95,
     99,2,0,0,0,0,0,0,0,2,0,0,0,3,0,0,
     0,3,0,0,0,115,22,0,0,0,116,0,0,116,1,0,
@@ -1351,7 +1351,7 @@ const unsigned char _Py_M__importlib_external[] = {
     32,32,32,32,32,32,32,32,41,3,218,5,115,117,112,101,
     114,114,210,0,0,0,114,193,0,0,0,41,2,114,108,0,
     0,0,114,126,0,0,0,41,1,114,211,0,0,0,114,4,
-    0,0,0,114,5,0,0,0,114,193,0,0,0,28,3,0,
+    0,0,0,114,5,0,0,0,114,193,0,0,0,31,3,0,
     0,115,2,0,0,0,0,10,122,22,70,105,108,101,76,111,
     97,100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,
     99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,
@@ -1362,7 +1362,7 @@ const unsigned char _Py_M__importlib_external[] = {
     32,98,121,32,116,104,101,32,102,105,110,100,101,114,46,41,
     1,114,35,0,0,0,41,2,114,108,0,0,0,114,126,0,
     0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
-    0,114,157,0,0,0,40,3,0,0,115,2,0,0,0,0,
+    0,114,157,0,0,0,43,3,0,0,115,2,0,0,0,0,
     3,122,23,70,105,108,101,76,111,97,100,101,114,46,103,101,
     116,95,102,105,108,101,110,97,109,101,99,2,0,0,0,0,
     0,0,0,3,0,0,0,9,0,0,0,67,0,0,0,115,
@@ -1375,14 +1375,14 @@ const unsigned char _Py_M__importlib_external[] = {
     49,0,0,0,114,50,0,0,0,90,4,114,101,97,100,41,
     3,114,108,0,0,0,114,35,0,0,0,114,54,0,0,0,
     114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
-    200,0,0,0,45,3,0,0,115,4,0,0,0,0,2,21,
+    200,0,0,0,48,3,0,0,115,4,0,0,0,0,2,21,
     1,122,19,70,105,108,101,76,111,97,100,101,114,46,103,101,
     116,95,100,97,116,97,41,11,114,112,0,0,0,114,111,0,
     0,0,114,113,0,0,0,114,114,0,0,0,114,185,0,0,
     0,114,213,0,0,0,114,215,0,0,0,114,123,0,0,0,
     114,193,0,0,0,114,157,0,0,0,114,200,0,0,0,114,
     4,0,0,0,114,4,0,0,0,41,1,114,211,0,0,0,
-    114,5,0,0,0,114,210,0,0,0,10,3,0,0,115,14,
+    114,5,0,0,0,114,210,0,0,0,13,3,0,0,115,14,
     0,0,0,12,3,6,2,12,6,12,4,12,3,24,12,18,
     5,114,210,0,0,0,99,0,0,0,0,0,0,0,0,0,
     0,0,0,4,0,0,0,64,0,0,0,115,64,0,0,0,
@@ -1405,7 +1405,7 @@ const unsigned char _Py_M__importlib_external[] = {
     3,114,39,0,0,0,218,8,115,116,95,109,116,105,109,101,
     90,7,115,116,95,115,105,122,101,41,3,114,108,0,0,0,
     114,35,0,0,0,114,208,0,0,0,114,4,0,0,0,114,
-    4,0,0,0,114,5,0,0,0,114,197,0,0,0,55,3,
+    4,0,0,0,114,5,0,0,0,114,197,0,0,0,58,3,
     0,0,115,4,0,0,0,0,2,12,1,122,27,83,111,117,
     114,99,101,70,105,108,101,76,111,97,100,101,114,46,112,97,
     116,104,95,115,116,97,116,115,99,4,0,0,0,0,0,0,
@@ -1416,7 +1416,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,97,0,0,0,114,198,0,0,0,41,5,114,108,0,0,
     0,114,90,0,0,0,114,89,0,0,0,114,53,0,0,0,
     114,42,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    5,0,0,0,114,199,0,0,0,60,3,0,0,115,4,0,
+    5,0,0,0,114,199,0,0,0,63,3,0,0,115,4,0,
     0,0,0,2,12,1,122,32,83,111,117,114,99,101,70,105,
     108,101,76,111,97,100,101,114,46,95,99,97,99,104,101,95,
     98,121,116,101,99,111,100,101,114,220,0,0,0,105,182,1,
@@ -1454,7 +1454,7 @@ const unsigned char _Py_M__importlib_external[] = {
     53,0,0,0,114,220,0,0,0,218,6,112,97,114,101,110,
     116,114,94,0,0,0,114,27,0,0,0,114,23,0,0,0,
     114,201,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    5,0,0,0,114,198,0,0,0,65,3,0,0,115,38,0,
+    5,0,0,0,114,198,0,0,0,68,3,0,0,115,38,0,
     0,0,0,2,18,1,6,2,22,1,18,1,17,2,19,1,
     15,1,3,1,17,1,13,2,7,1,18,3,16,1,27,1,
     3,1,16,1,17,1,18,2,122,25,83,111,117,114,99,101,
@@ -1463,7 +1463,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,113,0,0,0,114,114,0,0,0,114,197,0,0,0,114,
     199,0,0,0,114,198,0,0,0,114,4,0,0,0,114,4,
     0,0,0,114,4,0,0,0,114,5,0,0,0,114,218,0,
-    0,0,51,3,0,0,115,8,0,0,0,12,2,6,2,12,
+    0,0,54,3,0,0,115,8,0,0,0,12,2,6,2,12,
     5,12,5,114,218,0,0,0,99,0,0,0,0,0,0,0,
     0,0,0,0,0,2,0,0,0,64,0,0,0,115,46,0,
     0,0,101,0,0,90,1,0,100,0,0,90,2,0,100,1,
@@ -1485,7 +1485,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,147,0,0,0,41,5,114,108,0,0,0,114,126,0,0,
     0,114,35,0,0,0,114,53,0,0,0,114,209,0,0,0,
     114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
-    187,0,0,0,98,3,0,0,115,8,0,0,0,0,1,15,
+    187,0,0,0,101,3,0,0,115,8,0,0,0,0,1,15,
     1,15,1,24,1,122,29,83,111,117,114,99,101,108,101,115,
     115,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,
     99,111,100,101,99,2,0,0,0,0,0,0,0,2,0,0,
@@ -1495,13 +1495,13 @@ const unsigned char _Py_M__importlib_external[] = {
     32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,4,
     0,0,0,41,2,114,108,0,0,0,114,126,0,0,0,114,
     4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,202,
-    0,0,0,104,3,0,0,115,2,0,0,0,0,2,122,31,
+    0,0,0,107,3,0,0,115,2,0,0,0,0,2,122,31,
     83,111,117,114,99,101,108,101,115,115,70,105,108,101,76,111,
     97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,78,
     41,6,114,112,0,0,0,114,111,0,0,0,114,113,0,0,
     0,114,114,0,0,0,114,187,0,0,0,114,202,0,0,0,
     114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    5,0,0,0,114,223,0,0,0,94,3,0,0,115,6,0,
+    5,0,0,0,114,223,0,0,0,97,3,0,0,115,6,0,
     0,0,12,2,6,2,12,6,114,223,0,0,0,99,0,0,
     0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,
     0,0,115,136,0,0,0,101,0,0,90,1,0,100,0,0,
@@ -1526,7 +1526,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,100,0,0,83,41,1,78,41,2,114,106,0,0,0,114,
     35,0,0,0,41,3,114,108,0,0,0,114,106,0,0,0,
     114,35,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    5,0,0,0,114,185,0,0,0,121,3,0,0,115,4,0,
+    5,0,0,0,114,185,0,0,0,124,3,0,0,115,4,0,
     0,0,0,1,9,1,122,28,69,120,116,101,110,115,105,111,
     110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110,
     105,116,95,95,99,2,0,0,0,0,0,0,0,2,0,0,
@@ -1535,7 +1535,7 @@ const unsigned char _Py_M__importlib_external[] = {
     124,0,0,106,1,0,124,1,0,106,1,0,107,2,0,83,
     41,1,78,41,2,114,211,0,0,0,114,118,0,0,0,41,
     2,114,108,0,0,0,114,212,0,0,0,114,4,0,0,0,
-    114,4,0,0,0,114,5,0,0,0,114,213,0,0,0,125,
+    114,4,0,0,0,114,5,0,0,0,114,213,0,0,0,128,
     3,0,0,115,4,0,0,0,0,1,18,1,122,26,69,120,
     116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,
     114,46,95,95,101,113,95,95,99,1,0,0,0,0,0,0,
@@ -1544,7 +1544,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,124,0,0,106,2,0,131,1,0,65,83,41,1,78,41,
     3,114,214,0,0,0,114,106,0,0,0,114,35,0,0,0,
     41,1,114,108,0,0,0,114,4,0,0,0,114,4,0,0,
-    0,114,5,0,0,0,114,215,0,0,0,129,3,0,0,115,
+    0,114,5,0,0,0,114,215,0,0,0,132,3,0,0,115,
     2,0,0,0,0,1,122,28,69,120,116,101,110,115,105,111,
     110,70,105,108,101,76,111,97,100,101,114,46,95,95,104,97,
     115,104,95,95,99,2,0,0,0,0,0,0,0,3,0,0,
@@ -1562,7 +1562,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,105,0,0,0,114,106,0,0,0,114,35,0,0,0,41,
     3,114,108,0,0,0,114,164,0,0,0,114,190,0,0,0,
     114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
-    186,0,0,0,132,3,0,0,115,10,0,0,0,0,2,6,
+    186,0,0,0,135,3,0,0,115,10,0,0,0,0,2,6,
     1,15,1,6,1,16,1,122,33,69,120,116,101,110,115,105,
     111,110,70,105,108,101,76,111,97,100,101,114,46,99,114,101,
     97,116,101,95,109,111,100,117,108,101,99,2,0,0,0,0,
@@ -1579,7 +1579,7 @@ const unsigned char _Py_M__importlib_external[] = {
     12,101,120,101,99,95,100,121,110,97,109,105,99,114,105,0,
     0,0,114,106,0,0,0,114,35,0,0,0,41,2,114,108,
     0,0,0,114,190,0,0,0,114,4,0,0,0,114,4,0,
-    0,0,114,5,0,0,0,114,191,0,0,0,140,3,0,0,
+    0,0,114,5,0,0,0,114,191,0,0,0,143,3,0,0,
     115,6,0,0,0,0,2,19,1,6,1,122,31,69,120,116,
     101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,
     46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0,
@@ -1598,7 +1598,7 @@ const unsigned char _Py_M__importlib_external[] = {
     78,114,4,0,0,0,41,2,114,22,0,0,0,218,6,115,
     117,102,102,105,120,41,1,218,9,102,105,108,101,95,110,97,
     109,101,114,4,0,0,0,114,5,0,0,0,250,9,60,103,
-    101,110,101,120,112,114,62,149,3,0,0,115,2,0,0,0,
+    101,110,101,120,112,114,62,152,3,0,0,115,2,0,0,0,
     6,1,122,49,69,120,116,101,110,115,105,111,110,70,105,108,
     101,76,111,97,100,101,114,46,105,115,95,112,97,99,107,97,
     103,101,46,60,108,111,99,97,108,115,62,46,60,103,101,110,
@@ -1606,7 +1606,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,218,3,97,110,121,218,18,69,88,84,69,78,83,73,79,
     78,95,83,85,70,70,73,88,69,83,41,2,114,108,0,0,
     0,114,126,0,0,0,114,4,0,0,0,41,1,114,226,0,
-    0,0,114,5,0,0,0,114,159,0,0,0,146,3,0,0,
+    0,0,114,5,0,0,0,114,159,0,0,0,149,3,0,0,
     115,6,0,0,0,0,2,19,1,18,1,122,30,69,120,116,
     101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,
     46,105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,
@@ -1618,7 +1618,7 @@ const unsigned char _Py_M__importlib_external[] = {
     99,111,100,101,32,111,98,106,101,99,116,46,78,114,4,0,
     0,0,41,2,114,108,0,0,0,114,126,0,0,0,114,4,
     0,0,0,114,4,0,0,0,114,5,0,0,0,114,187,0,
-    0,0,152,3,0,0,115,2,0,0,0,0,2,122,28,69,
+    0,0,155,3,0,0,115,2,0,0,0,0,2,122,28,69,
     120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,
     101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,
     0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,
@@ -1628,7 +1628,7 @@ const unsigned char _Py_M__importlib_external[] = {
     118,101,32,110,111,32,115,111,117,114,99,101,32,99,111,100,
     101,46,78,114,4,0,0,0,41,2,114,108,0,0,0,114,
     126,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
-    0,0,0,114,202,0,0,0,156,3,0,0,115,2,0,0,
+    0,0,0,114,202,0,0,0,159,3,0,0,115,2,0,0,
     0,0,2,122,30,69,120,116,101,110,115,105,111,110,70,105,
     108,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,
     114,99,101,99,2,0,0,0,0,0,0,0,2,0,0,0,
@@ -1639,7 +1639,7 @@ const unsigned char _Py_M__importlib_external[] = {
     117,110,100,32,98,121,32,116,104,101,32,102,105,110,100,101,
     114,46,41,1,114,35,0,0,0,41,2,114,108,0,0,0,
     114,126,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    5,0,0,0,114,157,0,0,0,160,3,0,0,115,2,0,
+    5,0,0,0,114,157,0,0,0,163,3,0,0,115,2,0,
     0,0,0,3,122,32,69,120,116,101,110,115,105,111,110,70,
     105,108,101,76,111,97,100,101,114,46,103,101,116,95,102,105,
     108,101,110,97,109,101,78,41,14,114,112,0,0,0,114,111,
@@ -1648,7 +1648,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,114,191,0,0,0,114,159,0,0,0,114,187,0,0,0,
     114,202,0,0,0,114,123,0,0,0,114,157,0,0,0,114,
     4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
-    0,0,0,114,224,0,0,0,113,3,0,0,115,20,0,0,
+    0,0,0,114,224,0,0,0,116,3,0,0,115,20,0,0,
     0,12,6,6,2,12,4,12,4,12,3,12,8,12,6,12,
     6,12,4,12,4,114,224,0,0,0,99,0,0,0,0,0,
     0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,
@@ -1692,7 +1692,7 @@ const unsigned char _Py_M__importlib_external[] = {
     95,112,97,116,104,95,102,105,110,100,101,114,41,4,114,108,
     0,0,0,114,106,0,0,0,114,35,0,0,0,218,11,112,
     97,116,104,95,102,105,110,100,101,114,114,4,0,0,0,114,
-    4,0,0,0,114,5,0,0,0,114,185,0,0,0,173,3,
+    4,0,0,0,114,5,0,0,0,114,185,0,0,0,176,3,
     0,0,115,8,0,0,0,0,1,9,1,9,1,21,1,122,
     23,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,
     95,95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,
@@ -1711,7 +1711,7 @@ const unsigned char _Py_M__importlib_external[] = {
     41,4,114,108,0,0,0,114,222,0,0,0,218,3,100,111,
     116,90,2,109,101,114,4,0,0,0,114,4,0,0,0,114,
     5,0,0,0,218,23,95,102,105,110,100,95,112,97,114,101,
-    110,116,95,112,97,116,104,95,110,97,109,101,115,179,3,0,
+    110,116,95,112,97,116,104,95,110,97,109,101,115,182,3,0,
     0,115,8,0,0,0,0,2,27,1,12,2,4,3,122,38,
     95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,
     102,105,110,100,95,112,97,114,101,110,116,95,112,97,116,104,
@@ -1725,7 +1725,7 @@ const unsigned char _Py_M__importlib_external[] = {
     110,116,95,109,111,100,117,108,101,95,110,97,109,101,90,14,
     112,97,116,104,95,97,116,116,114,95,110,97,109,101,114,4,
     0,0,0,114,4,0,0,0,114,5,0,0,0,114,233,0,
-    0,0,189,3,0,0,115,4,0,0,0,0,1,18,1,122,
+    0,0,192,3,0,0,115,4,0,0,0,0,1,18,1,122,
     31,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,
     95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104,
     99,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,
@@ -1743,7 +1743,7 @@ const unsigned char _Py_M__importlib_external[] = {
     108,0,0,0,90,11,112,97,114,101,110,116,95,112,97,116,
     104,114,164,0,0,0,114,4,0,0,0,114,4,0,0,0,
     114,5,0,0,0,218,12,95,114,101,99,97,108,99,117,108,
-    97,116,101,193,3,0,0,115,16,0,0,0,0,2,18,1,
+    97,116,101,196,3,0,0,115,16,0,0,0,0,2,18,1,
     15,1,21,3,27,1,9,1,12,1,9,1,122,27,95,78,
     97,109,101,115,112,97,99,101,80,97,116,104,46,95,114,101,
     99,97,108,99,117,108,97,116,101,99,1,0,0,0,0,0,
@@ -1752,14 +1752,14 @@ const unsigned char _Py_M__importlib_external[] = {
     1,0,83,41,1,78,41,2,218,4,105,116,101,114,114,240,
     0,0,0,41,1,114,108,0,0,0,114,4,0,0,0,114,
     4,0,0,0,114,5,0,0,0,218,8,95,95,105,116,101,
-    114,95,95,206,3,0,0,115,2,0,0,0,0,1,122,23,
+    114,95,95,209,3,0,0,115,2,0,0,0,0,1,122,23,
     95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,
     95,105,116,101,114,95,95,99,1,0,0,0,0,0,0,0,
     1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,
     0,116,0,0,124,0,0,106,1,0,131,0,0,131,1,0,
     83,41,1,78,41,2,114,31,0,0,0,114,240,0,0,0,
     41,1,114,108,0,0,0,114,4,0,0,0,114,4,0,0,
-    0,114,5,0,0,0,218,7,95,95,108,101,110,95,95,209,
+    0,114,5,0,0,0,218,7,95,95,108,101,110,95,95,212,
     3,0,0,115,2,0,0,0,0,1,122,22,95,78,97,109,
     101,115,112,97,99,101,80,97,116,104,46,95,95,108,101,110,
     95,95,99,1,0,0,0,0,0,0,0,1,0,0,0,2,
@@ -1769,7 +1769,7 @@ const unsigned char _Py_M__importlib_external[] = {
     123,33,114,125,41,41,2,114,47,0,0,0,114,232,0,0,
     0,41,1,114,108,0,0,0,114,4,0,0,0,114,4,0,
     0,0,114,5,0,0,0,218,8,95,95,114,101,112,114,95,
-    95,212,3,0,0,115,2,0,0,0,0,1,122,23,95,78,
+    95,215,3,0,0,115,2,0,0,0,0,1,122,23,95,78,
     97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,114,
     101,112,114,95,95,99,2,0,0,0,0,0,0,0,2,0,
     0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124,
@@ -1777,7 +1777,7 @@ const unsigned char _Py_M__importlib_external[] = {
     1,78,41,1,114,240,0,0,0,41,2,114,108,0,0,0,
     218,4,105,116,101,109,114,4,0,0,0,114,4,0,0,0,
     114,5,0,0,0,218,12,95,95,99,111,110,116,97,105,110,
-    115,95,95,215,3,0,0,115,2,0,0,0,0,1,122,27,
+    115,95,95,218,3,0,0,115,2,0,0,0,0,1,122,27,
     95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,
     95,99,111,110,116,97,105,110,115,95,95,99,2,0,0,0,
     0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,
@@ -1785,7 +1785,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,131,1,0,1,100,0,0,83,41,1,78,41,2,114,232,
     0,0,0,114,163,0,0,0,41,2,114,108,0,0,0,114,
     245,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
-    0,0,0,114,163,0,0,0,218,3,0,0,115,2,0,0,
+    0,0,0,114,163,0,0,0,221,3,0,0,115,2,0,0,
     0,0,1,122,21,95,78,97,109,101,115,112,97,99,101,80,
     97,116,104,46,97,112,112,101,110,100,78,41,13,114,112,0,
     0,0,114,111,0,0,0,114,113,0,0,0,114,114,0,0,
@@ -1793,7 +1793,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,240,0,0,0,114,242,0,0,0,114,243,0,0,0,114,
     244,0,0,0,114,246,0,0,0,114,163,0,0,0,114,4,
     0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,
-    0,0,114,230,0,0,0,166,3,0,0,115,20,0,0,0,
+    0,0,114,230,0,0,0,169,3,0,0,115,20,0,0,0,
     12,5,6,2,12,6,12,10,12,4,12,13,12,3,12,3,
     12,3,12,3,114,230,0,0,0,99,0,0,0,0,0,0,
     0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,118,
@@ -1812,7 +1812,7 @@ const unsigned char _Py_M__importlib_external[] = {
     41,1,78,41,2,114,230,0,0,0,114,232,0,0,0,41,
     4,114,108,0,0,0,114,106,0,0,0,114,35,0,0,0,
     114,236,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    5,0,0,0,114,185,0,0,0,224,3,0,0,115,2,0,
+    5,0,0,0,114,185,0,0,0,227,3,0,0,115,2,0,
     0,0,0,1,122,25,95,78,97,109,101,115,112,97,99,101,
     76,111,97,100,101,114,46,95,95,105,110,105,116,95,95,99,
     2,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,
@@ -1829,14 +1829,14 @@ const unsigned char _Py_M__importlib_external[] = {
     110,97,109,101,115,112,97,99,101,41,62,41,2,114,47,0,
     0,0,114,112,0,0,0,41,2,114,170,0,0,0,114,190,
     0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,
-    0,0,218,11,109,111,100,117,108,101,95,114,101,112,114,227,
+    0,0,218,11,109,111,100,117,108,101,95,114,101,112,114,230,
     3,0,0,115,2,0,0,0,0,7,122,28,95,78,97,109,
     101,115,112,97,99,101,76,111,97,100,101,114,46,109,111,100,
     117,108,101,95,114,101,112,114,99,2,0,0,0,0,0,0,
     0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,
     0,0,100,1,0,83,41,2,78,84,114,4,0,0,0,41,
     2,114,108,0,0,0,114,126,0,0,0,114,4,0,0,0,
-    114,4,0,0,0,114,5,0,0,0,114,159,0,0,0,236,
+    114,4,0,0,0,114,5,0,0,0,114,159,0,0,0,239,
     3,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109,
     101,115,112,97,99,101,76,111,97,100,101,114,46,105,115,95,
     112,97,99,107,97,103,101,99,2,0,0,0,0,0,0,0,
@@ -1844,7 +1844,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,100,1,0,83,41,2,78,114,30,0,0,0,114,4,0,
     0,0,41,2,114,108,0,0,0,114,126,0,0,0,114,4,
     0,0,0,114,4,0,0,0,114,5,0,0,0,114,202,0,
-    0,0,239,3,0,0,115,2,0,0,0,0,1,122,27,95,
+    0,0,242,3,0,0,115,2,0,0,0,0,1,122,27,95,
     78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,
     103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,
     0,0,0,2,0,0,0,6,0,0,0,67,0,0,0,115,
@@ -1853,7 +1853,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,122,8,60,115,116,114,105,110,103,62,114,189,0,0,
     0,114,204,0,0,0,84,41,1,114,205,0,0,0,41,2,
     114,108,0,0,0,114,126,0,0,0,114,4,0,0,0,114,
-    4,0,0,0,114,5,0,0,0,114,187,0,0,0,242,3,
+    4,0,0,0,114,5,0,0,0,114,187,0,0,0,245,3,
     0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101,
     115,112,97,99,101,76,111,97,100,101,114,46,103,101,116,95,
     99,111,100,101,99,2,0,0,0,0,0,0,0,2,0,0,
@@ -1863,14 +1863,14 @@ const unsigned char _Py_M__importlib_external[] = {
     109,111,100,117,108,101,32,99,114,101,97,116,105,111,110,46,
     78,114,4,0,0,0,41,2,114,108,0,0,0,114,164,0,
     0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
-    0,114,186,0,0,0,245,3,0,0,115,0,0,0,0,122,
+    0,114,186,0,0,0,248,3,0,0,115,0,0,0,0,122,
     30,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101,
     114,46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,
     2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,
     67,0,0,0,115,4,0,0,0,100,0,0,83,41,1,78,
     114,4,0,0,0,41,2,114,108,0,0,0,114,190,0,0,
     0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
-    114,191,0,0,0,248,3,0,0,115,2,0,0,0,0,1,
+    114,191,0,0,0,251,3,0,0,115,2,0,0,0,0,1,
     122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,
     101,114,46,101,120,101,99,95,109,111,100,117,108,101,99,2,
     0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,
@@ -1888,7 +1888,7 @@ const unsigned char _Py_M__importlib_external[] = {
     104,32,123,33,114,125,41,4,114,105,0,0,0,114,232,0,
     0,0,114,121,0,0,0,114,192,0,0,0,41,2,114,108,
     0,0,0,114,126,0,0,0,114,4,0,0,0,114,4,0,
-    0,0,114,5,0,0,0,114,193,0,0,0,251,3,0,0,
+    0,0,114,5,0,0,0,114,193,0,0,0,254,3,0,0,
     115,4,0,0,0,0,7,16,1,122,28,95,78,97,109,101,
     115,112,97,99,101,76,111,97,100,101,114,46,108,111,97,100,
     95,109,111,100,117,108,101,78,41,12,114,112,0,0,0,114,
@@ -1896,7 +1896,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,0,114,248,0,0,0,114,159,0,0,0,114,202,0,
     0,0,114,187,0,0,0,114,186,0,0,0,114,191,0,0,
     0,114,193,0,0,0,114,4,0,0,0,114,4,0,0,0,
-    114,4,0,0,0,114,5,0,0,0,114,247,0,0,0,223,
+    114,4,0,0,0,114,5,0,0,0,114,247,0,0,0,226,
     3,0,0,115,16,0,0,0,12,1,12,3,18,9,12,3,
     12,3,12,3,12,3,12,3,114,247,0,0,0,99,0,0,
     0,0,0,0,0,0,0,0,0,0,5,0,0,0,64,0,
@@ -1934,7 +1934,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,95,99,97,99,104,101,218,6,118,97,108,117,101,115,114,
     115,0,0,0,114,250,0,0,0,41,2,114,170,0,0,0,
     218,6,102,105,110,100,101,114,114,4,0,0,0,114,4,0,
-    0,0,114,5,0,0,0,114,250,0,0,0,12,4,0,0,
+    0,0,114,5,0,0,0,114,250,0,0,0,15,4,0,0,
     115,6,0,0,0,0,4,22,1,15,1,122,28,80,97,116,
     104,70,105,110,100,101,114,46,105,110,118,97,108,105,100,97,
     116,101,95,99,97,99,104,101,115,99,2,0,0,0,0,0,
@@ -1960,7 +1960,7 @@ const unsigned char _Py_M__importlib_external[] = {
     107,0,0,0,41,3,114,170,0,0,0,114,35,0,0,0,
     90,4,104,111,111,107,114,4,0,0,0,114,4,0,0,0,
     114,5,0,0,0,218,11,95,112,97,116,104,95,104,111,111,
-    107,115,20,4,0,0,115,16,0,0,0,0,7,25,1,16,
+    107,115,23,4,0,0,115,16,0,0,0,0,7,25,1,16,
     1,16,1,3,1,14,1,13,1,12,2,122,22,80,97,116,
     104,70,105,110,100,101,114,46,95,112,97,116,104,95,104,111,
     111,107,115,99,2,0,0,0,0,0,0,0,3,0,0,0,
@@ -1992,7 +1992,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,114,255,0,0,0,41,3,114,170,0,0,0,114,35,
     0,0,0,114,253,0,0,0,114,4,0,0,0,114,4,0,
     0,0,114,5,0,0,0,218,20,95,112,97,116,104,95,105,
-    109,112,111,114,116,101,114,95,99,97,99,104,101,37,4,0,
+    109,112,111,114,116,101,114,95,99,97,99,104,101,40,4,0,
     0,115,22,0,0,0,0,8,12,1,3,1,16,1,13,3,
     9,1,3,1,17,1,13,1,15,1,18,1,122,31,80,97,
     116,104,70,105,110,100,101,114,46,95,112,97,116,104,95,105,
@@ -2012,7 +2012,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,114,126,0,0,0,114,253,0,0,0,114,127,0,0,
     0,114,128,0,0,0,114,164,0,0,0,114,4,0,0,0,
     114,4,0,0,0,114,5,0,0,0,218,16,95,108,101,103,
-    97,99,121,95,103,101,116,95,115,112,101,99,59,4,0,0,
+    97,99,121,95,103,101,116,95,115,112,101,99,62,4,0,0,
     115,18,0,0,0,0,4,15,1,24,2,15,1,6,1,12,
     1,16,1,18,1,9,1,122,27,80,97,116,104,70,105,110,
     100,101,114,46,95,108,101,103,97,99,121,95,103,101,116,95,
@@ -2048,7 +2048,7 @@ const unsigned char _Py_M__importlib_external[] = {
     101,115,112,97,99,101,95,112,97,116,104,90,5,101,110,116,
     114,121,114,253,0,0,0,114,164,0,0,0,114,128,0,0,
     0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
-    218,9,95,103,101,116,95,115,112,101,99,74,4,0,0,115,
+    218,9,95,103,101,116,95,115,112,101,99,77,4,0,0,115,
     40,0,0,0,0,5,6,1,13,1,21,1,3,1,15,1,
     12,1,15,1,21,2,18,1,12,1,3,1,15,1,4,1,
     9,1,12,1,12,5,17,2,18,1,9,1,122,20,80,97,
@@ -2076,7 +2076,7 @@ const unsigned char _Py_M__importlib_external[] = {
     6,114,170,0,0,0,114,126,0,0,0,114,35,0,0,0,
     114,180,0,0,0,114,164,0,0,0,114,4,1,0,0,114,
     4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,181,
-    0,0,0,106,4,0,0,115,26,0,0,0,0,4,12,1,
+    0,0,0,109,4,0,0,115,26,0,0,0,0,4,12,1,
     9,1,21,1,12,1,4,1,15,1,9,1,6,3,9,1,
     24,1,4,2,7,2,122,20,80,97,116,104,70,105,110,100,
     101,114,46,102,105,110,100,95,115,112,101,99,99,3,0,0,
@@ -2098,7 +2098,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,181,0,0,0,114,127,0,0,0,41,4,114,170,0,0,
     0,114,126,0,0,0,114,35,0,0,0,114,164,0,0,0,
     114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
-    182,0,0,0,128,4,0,0,115,8,0,0,0,0,8,18,
+    182,0,0,0,131,4,0,0,115,8,0,0,0,0,8,18,
     1,12,1,4,1,122,22,80,97,116,104,70,105,110,100,101,
     114,46,102,105,110,100,95,109,111,100,117,108,101,41,12,114,
     112,0,0,0,114,111,0,0,0,114,113,0,0,0,114,114,
@@ -2106,7 +2106,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,114,1,1,0,0,114,2,1,0,0,114,5,1,0,
     0,114,181,0,0,0,114,182,0,0,0,114,4,0,0,0,
     114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
-    249,0,0,0,8,4,0,0,115,22,0,0,0,12,2,6,
+    249,0,0,0,11,4,0,0,115,22,0,0,0,12,2,6,
     2,18,8,18,17,18,22,18,15,3,1,18,31,3,1,21,
     21,3,1,114,249,0,0,0,99,0,0,0,0,0,0,0,
     0,0,0,0,0,3,0,0,0,64,0,0,0,115,133,0,
@@ -2155,7 +2155,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,86,1,113,3,0,100,0,0,83,41,1,78,114,4,0,
     0,0,41,2,114,22,0,0,0,114,225,0,0,0,41,1,
     114,127,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
-    227,0,0,0,157,4,0,0,115,2,0,0,0,6,0,122,
+    227,0,0,0,160,4,0,0,115,2,0,0,0,6,0,122,
     38,70,105,108,101,70,105,110,100,101,114,46,95,95,105,110,
     105,116,95,95,46,60,108,111,99,97,108,115,62,46,60,103,
     101,110,101,120,112,114,62,114,58,0,0,0,114,29,0,0,
@@ -2168,7 +2168,7 @@ const unsigned char _Py_M__importlib_external[] = {
     111,97,100,101,114,95,100,101,116,97,105,108,115,90,7,108,
     111,97,100,101,114,115,114,166,0,0,0,114,4,0,0,0,
     41,1,114,127,0,0,0,114,5,0,0,0,114,185,0,0,
-    0,151,4,0,0,115,16,0,0,0,0,4,6,1,19,1,
+    0,154,4,0,0,115,16,0,0,0,0,4,6,1,19,1,
     36,1,9,2,15,1,9,1,12,1,122,19,70,105,108,101,
     70,105,110,100,101,114,46,95,95,105,110,105,116,95,95,99,
     1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,
@@ -2178,7 +2178,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,121,32,109,116,105,109,101,46,114,29,0,0,0,78,114,
     87,0,0,0,41,1,114,8,1,0,0,41,1,114,108,0,
     0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
-    0,114,250,0,0,0,165,4,0,0,115,2,0,0,0,0,
+    0,114,250,0,0,0,168,4,0,0,115,2,0,0,0,0,
     2,122,28,70,105,108,101,70,105,110,100,101,114,46,105,110,
     118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,99,
     2,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,
@@ -2202,7 +2202,7 @@ const unsigned char _Py_M__importlib_external[] = {
     114,181,0,0,0,114,127,0,0,0,114,156,0,0,0,41,
     3,114,108,0,0,0,114,126,0,0,0,114,164,0,0,0,
     114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
-    124,0,0,0,171,4,0,0,115,8,0,0,0,0,7,15,
+    124,0,0,0,174,4,0,0,115,8,0,0,0,0,7,15,
     1,12,1,10,1,122,22,70,105,108,101,70,105,110,100,101,
     114,46,102,105,110,100,95,108,111,97,100,101,114,99,6,0,
     0,0,0,0,0,0,7,0,0,0,7,0,0,0,67,0,
@@ -2213,7 +2213,7 @@ const unsigned char _Py_M__importlib_external[] = {
     0,0,0,41,7,114,108,0,0,0,114,165,0,0,0,114,
     126,0,0,0,114,35,0,0,0,90,4,115,109,115,108,114,
     180,0,0,0,114,127,0,0,0,114,4,0,0,0,114,4,
-    0,0,0,114,5,0,0,0,114,5,1,0,0,183,4,0,
+    0,0,0,114,5,0,0,0,114,5,1,0,0,186,4,0,
     0,115,6,0,0,0,0,1,15,1,18,1,122,20,70,105,
     108,101,70,105,110,100,101,114,46,95,103,101,116,95,115,112,
     101,99,78,99,3,0,0,0,0,0,0,0,14,0,0,0,
@@ -2248,350 +2248,349 @@ const unsigned char _Py_M__importlib_external[] = {
     0,100,9,0,106,19,0,124,8,0,131,1,0,131,1,0,
     1,116,20,0,106,21,0,124,1,0,100,8,0,131,2,0,
     125,13,0,124,8,0,103,1,0,124,13,0,95,22,0,124,
-    13,0,83,100,8,0,83,41,11,122,125,84,114,121,32,116,
-    111,32,102,105,110,100,32,97,32,108,111,97,100,101,114,32,
-    102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,
-    100,32,109,111,100,117,108,101,44,32,111,114,32,116,104,101,
-    32,110,97,109,101,115,112,97,99,101,10,32,32,32,32,32,
-    32,32,32,112,97,99,107,97,103,101,32,112,111,114,116,105,
-    111,110,115,46,32,82,101,116,117,114,110,115,32,40,108,111,
-    97,100,101,114,44,32,108,105,115,116,45,111,102,45,112,111,
-    114,116,105,111,110,115,41,46,70,114,58,0,0,0,114,56,
-    0,0,0,114,29,0,0,0,114,185,0,0,0,122,9,116,
-    114,121,105,110,103,32,123,125,114,98,0,0,0,78,122,25,
-    112,111,115,115,105,98,108,101,32,110,97,109,101,115,112,97,
-    99,101,32,102,111,114,32,123,125,114,87,0,0,0,41,23,
-    114,32,0,0,0,114,39,0,0,0,114,35,0,0,0,114,
-    3,0,0,0,114,45,0,0,0,114,219,0,0,0,114,40,
-    0,0,0,114,8,1,0,0,218,11,95,102,105,108,108,95,
-    99,97,99,104,101,114,6,0,0,0,114,11,1,0,0,114,
-    88,0,0,0,114,10,1,0,0,114,28,0,0,0,114,7,
-    1,0,0,114,44,0,0,0,114,5,1,0,0,114,46,0,
-    0,0,114,105,0,0,0,114,47,0,0,0,114,121,0,0,
-    0,114,160,0,0,0,114,156,0,0,0,41,14,114,108,0,
-    0,0,114,126,0,0,0,114,180,0,0,0,90,12,105,115,
-    95,110,97,109,101,115,112,97,99,101,90,11,116,97,105,108,
-    95,109,111,100,117,108,101,114,133,0,0,0,90,5,99,97,
-    99,104,101,90,12,99,97,99,104,101,95,109,111,100,117,108,
-    101,90,9,98,97,115,101,95,112,97,116,104,114,225,0,0,
-    0,114,165,0,0,0,90,13,105,110,105,116,95,102,105,108,
-    101,110,97,109,101,90,9,102,117,108,108,95,112,97,116,104,
-    114,164,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    5,0,0,0,114,181,0,0,0,188,4,0,0,115,68,0,
-    0,0,0,3,6,1,19,1,3,1,34,1,13,1,11,1,
-    15,1,10,1,9,2,9,1,9,1,15,2,9,1,6,2,
-    12,1,18,1,22,1,10,1,15,1,12,1,32,4,12,2,
-    22,1,22,1,25,1,16,1,12,1,29,1,6,1,19,1,
-    18,1,12,1,4,1,122,20,70,105,108,101,70,105,110,100,
-    101,114,46,102,105,110,100,95,115,112,101,99,99,1,0,0,
-    0,0,0,0,0,9,0,0,0,13,0,0,0,67,0,0,
-    0,115,11,1,0,0,124,0,0,106,0,0,125,1,0,121,
-    31,0,116,1,0,106,2,0,124,1,0,112,33,0,116,1,
-    0,106,3,0,131,0,0,131,1,0,125,2,0,87,110,33,
-    0,4,116,4,0,116,5,0,116,6,0,102,3,0,107,10,
-    0,114,75,0,1,1,1,103,0,0,125,2,0,89,110,1,
-    0,88,116,7,0,106,8,0,106,9,0,100,1,0,131,1,
-    0,115,112,0,116,10,0,124,2,0,131,1,0,124,0,0,
-    95,11,0,110,111,0,116,10,0,131,0,0,125,3,0,120,
-    90,0,124,2,0,68,93,82,0,125,4,0,124,4,0,106,
-    12,0,100,2,0,131,1,0,92,3,0,125,5,0,125,6,
-    0,125,7,0,124,6,0,114,191,0,100,3,0,106,13,0,
-    124,5,0,124,7,0,106,14,0,131,0,0,131,2,0,125,
-    8,0,110,6,0,124,5,0,125,8,0,124,3,0,106,15,
-    0,124,8,0,131,1,0,1,113,128,0,87,124,3,0,124,
-    0,0,95,11,0,116,7,0,106,8,0,106,9,0,116,16,
-    0,131,1,0,114,7,1,100,4,0,100,5,0,132,0,0,
-    124,2,0,68,131,1,0,124,0,0,95,17,0,100,6,0,
-    83,41,7,122,68,70,105,108,108,32,116,104,101,32,99,97,
-    99,104,101,32,111,102,32,112,111,116,101,110,116,105,97,108,
-    32,109,111,100,117,108,101,115,32,97,110,100,32,112,97,99,
-    107,97,103,101,115,32,102,111,114,32,116,104,105,115,32,100,
-    105,114,101,99,116,111,114,121,46,114,0,0,0,0,114,58,
-    0,0,0,122,5,123,125,46,123,125,99,1,0,0,0,0,
-    0,0,0,2,0,0,0,3,0,0,0,83,0,0,0,115,
-    28,0,0,0,104,0,0,124,0,0,93,18,0,125,1,0,
-    124,1,0,106,0,0,131,0,0,146,2,0,113,6,0,83,
-    114,4,0,0,0,41,1,114,88,0,0,0,41,2,114,22,
-    0,0,0,90,2,102,110,114,4,0,0,0,114,4,0,0,
-    0,114,5,0,0,0,250,9,60,115,101,116,99,111,109,112,
-    62,6,5,0,0,115,2,0,0,0,9,0,122,41,70,105,
-    108,101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,
-    97,99,104,101,46,60,108,111,99,97,108,115,62,46,60,115,
-    101,116,99,111,109,112,62,78,41,18,114,35,0,0,0,114,
-    3,0,0,0,90,7,108,105,115,116,100,105,114,114,45,0,
-    0,0,114,0,1,0,0,218,15,80,101,114,109,105,115,115,
-    105,111,110,69,114,114,111,114,218,18,78,111,116,65,68,105,
-    114,101,99,116,111,114,121,69,114,114,111,114,114,7,0,0,
-    0,114,8,0,0,0,114,9,0,0,0,114,9,1,0,0,
-    114,10,1,0,0,114,83,0,0,0,114,47,0,0,0,114,
-    88,0,0,0,218,3,97,100,100,114,10,0,0,0,114,11,
-    1,0,0,41,9,114,108,0,0,0,114,35,0,0,0,90,
-    8,99,111,110,116,101,110,116,115,90,21,108,111,119,101,114,
-    95,115,117,102,102,105,120,95,99,111,110,116,101,110,116,115,
-    114,245,0,0,0,114,106,0,0,0,114,237,0,0,0,114,
-    225,0,0,0,90,8,110,101,119,95,110,97,109,101,114,4,
-    0,0,0,114,4,0,0,0,114,5,0,0,0,114,13,1,
-    0,0,233,4,0,0,115,34,0,0,0,0,2,9,1,3,
-    1,31,1,22,3,11,3,18,1,18,7,9,1,13,1,24,
-    1,6,1,27,2,6,1,17,1,9,1,18,1,122,22,70,
-    105,108,101,70,105,110,100,101,114,46,95,102,105,108,108,95,
-    99,97,99,104,101,99,1,0,0,0,0,0,0,0,3,0,
-    0,0,3,0,0,0,7,0,0,0,115,25,0,0,0,135,
-    0,0,135,1,0,102,2,0,100,1,0,100,2,0,134,0,
-    0,125,2,0,124,2,0,83,41,3,97,20,1,0,0,65,
-    32,99,108,97,115,115,32,109,101,116,104,111,100,32,119,104,
-    105,99,104,32,114,101,116,117,114,110,115,32,97,32,99,108,
-    111,115,117,114,101,32,116,111,32,117,115,101,32,111,110,32,
-    115,121,115,46,112,97,116,104,95,104,111,111,107,10,32,32,
-    32,32,32,32,32,32,119,104,105,99,104,32,119,105,108,108,
-    32,114,101,116,117,114,110,32,97,110,32,105,110,115,116,97,
-    110,99,101,32,117,115,105,110,103,32,116,104,101,32,115,112,
-    101,99,105,102,105,101,100,32,108,111,97,100,101,114,115,32,
-    97,110,100,32,116,104,101,32,112,97,116,104,10,32,32,32,
-    32,32,32,32,32,99,97,108,108,101,100,32,111,110,32,116,
-    104,101,32,99,108,111,115,117,114,101,46,10,10,32,32,32,
-    32,32,32,32,32,73,102,32,116,104,101,32,112,97,116,104,
-    32,99,97,108,108,101,100,32,111,110,32,116,104,101,32,99,
-    108,111,115,117,114,101,32,105,115,32,110,111,116,32,97,32,
-    100,105,114,101,99,116,111,114,121,44,32,73,109,112,111,114,
-    116,69,114,114,111,114,32,105,115,10,32,32,32,32,32,32,
-    32,32,114,97,105,115,101,100,46,10,10,32,32,32,32,32,
-    32,32,32,99,1,0,0,0,0,0,0,0,1,0,0,0,
-    4,0,0,0,19,0,0,0,115,43,0,0,0,116,0,0,
-    124,0,0,131,1,0,115,30,0,116,1,0,100,1,0,100,
-    2,0,124,0,0,131,1,1,130,1,0,136,0,0,124,0,
-    0,136,1,0,140,1,0,83,41,3,122,45,80,97,116,104,
-    32,104,111,111,107,32,102,111,114,32,105,109,112,111,114,116,
-    108,105,98,46,109,97,99,104,105,110,101,114,121,46,70,105,
-    108,101,70,105,110,100,101,114,46,122,30,111,110,108,121,32,
-    100,105,114,101,99,116,111,114,105,101,115,32,97,114,101,32,
-    115,117,112,112,111,114,116,101,100,114,35,0,0,0,41,2,
-    114,46,0,0,0,114,107,0,0,0,41,1,114,35,0,0,
-    0,41,2,114,170,0,0,0,114,12,1,0,0,114,4,0,
-    0,0,114,5,0,0,0,218,24,112,97,116,104,95,104,111,
+    13,0,83,100,8,0,83,41,11,122,102,84,114,121,32,116,
+    111,32,102,105,110,100,32,97,32,115,112,101,99,32,102,111,
+    114,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,
+    109,111,100,117,108,101,46,32,32,82,101,116,117,114,110,115,
+    32,116,104,101,10,32,32,32,32,32,32,32,32,109,97,116,
+    99,104,105,110,103,32,115,112,101,99,44,32,111,114,32,78,
+    111,110,101,32,105,102,32,110,111,116,32,102,111,117,110,100,
+    46,70,114,58,0,0,0,114,56,0,0,0,114,29,0,0,
+    0,114,185,0,0,0,122,9,116,114,121,105,110,103,32,123,
+    125,114,98,0,0,0,78,122,25,112,111,115,115,105,98,108,
+    101,32,110,97,109,101,115,112,97,99,101,32,102,111,114,32,
+    123,125,114,87,0,0,0,41,23,114,32,0,0,0,114,39,
+    0,0,0,114,35,0,0,0,114,3,0,0,0,114,45,0,
+    0,0,114,219,0,0,0,114,40,0,0,0,114,8,1,0,
+    0,218,11,95,102,105,108,108,95,99,97,99,104,101,114,6,
+    0,0,0,114,11,1,0,0,114,88,0,0,0,114,10,1,
+    0,0,114,28,0,0,0,114,7,1,0,0,114,44,0,0,
+    0,114,5,1,0,0,114,46,0,0,0,114,105,0,0,0,
+    114,47,0,0,0,114,121,0,0,0,114,160,0,0,0,114,
+    156,0,0,0,41,14,114,108,0,0,0,114,126,0,0,0,
+    114,180,0,0,0,90,12,105,115,95,110,97,109,101,115,112,
+    97,99,101,90,11,116,97,105,108,95,109,111,100,117,108,101,
+    114,133,0,0,0,90,5,99,97,99,104,101,90,12,99,97,
+    99,104,101,95,109,111,100,117,108,101,90,9,98,97,115,101,
+    95,112,97,116,104,114,225,0,0,0,114,165,0,0,0,90,
+    13,105,110,105,116,95,102,105,108,101,110,97,109,101,90,9,
+    102,117,108,108,95,112,97,116,104,114,164,0,0,0,114,4,
+    0,0,0,114,4,0,0,0,114,5,0,0,0,114,181,0,
+    0,0,191,4,0,0,115,68,0,0,0,0,3,6,1,19,
+    1,3,1,34,1,13,1,11,1,15,1,10,1,9,2,9,
+    1,9,1,15,2,9,1,6,2,12,1,18,1,22,1,10,
+    1,15,1,12,1,32,4,12,2,22,1,22,1,25,1,16,
+    1,12,1,29,1,6,1,19,1,18,1,12,1,4,1,122,
+    20,70,105,108,101,70,105,110,100,101,114,46,102,105,110,100,
+    95,115,112,101,99,99,1,0,0,0,0,0,0,0,9,0,
+    0,0,13,0,0,0,67,0,0,0,115,11,1,0,0,124,
+    0,0,106,0,0,125,1,0,121,31,0,116,1,0,106,2,
+    0,124,1,0,112,33,0,116,1,0,106,3,0,131,0,0,
+    131,1,0,125,2,0,87,110,33,0,4,116,4,0,116,5,
+    0,116,6,0,102,3,0,107,10,0,114,75,0,1,1,1,
+    103,0,0,125,2,0,89,110,1,0,88,116,7,0,106,8,
+    0,106,9,0,100,1,0,131,1,0,115,112,0,116,10,0,
+    124,2,0,131,1,0,124,0,0,95,11,0,110,111,0,116,
+    10,0,131,0,0,125,3,0,120,90,0,124,2,0,68,93,
+    82,0,125,4,0,124,4,0,106,12,0,100,2,0,131,1,
+    0,92,3,0,125,5,0,125,6,0,125,7,0,124,6,0,
+    114,191,0,100,3,0,106,13,0,124,5,0,124,7,0,106,
+    14,0,131,0,0,131,2,0,125,8,0,110,6,0,124,5,
+    0,125,8,0,124,3,0,106,15,0,124,8,0,131,1,0,
+    1,113,128,0,87,124,3,0,124,0,0,95,11,0,116,7,
+    0,106,8,0,106,9,0,116,16,0,131,1,0,114,7,1,
+    100,4,0,100,5,0,132,0,0,124,2,0,68,131,1,0,
+    124,0,0,95,17,0,100,6,0,83,41,7,122,68,70,105,
+    108,108,32,116,104,101,32,99,97,99,104,101,32,111,102,32,
+    112,111,116,101,110,116,105,97,108,32,109,111,100,117,108,101,
+    115,32,97,110,100,32,112,97,99,107,97,103,101,115,32,102,
+    111,114,32,116,104,105,115,32,100,105,114,101,99,116,111,114,
+    121,46,114,0,0,0,0,114,58,0,0,0,122,5,123,125,
+    46,123,125,99,1,0,0,0,0,0,0,0,2,0,0,0,
+    3,0,0,0,83,0,0,0,115,28,0,0,0,104,0,0,
+    124,0,0,93,18,0,125,1,0,124,1,0,106,0,0,131,
+    0,0,146,2,0,113,6,0,83,114,4,0,0,0,41,1,
+    114,88,0,0,0,41,2,114,22,0,0,0,90,2,102,110,
+    114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,250,
+    9,60,115,101,116,99,111,109,112,62,9,5,0,0,115,2,
+    0,0,0,9,0,122,41,70,105,108,101,70,105,110,100,101,
+    114,46,95,102,105,108,108,95,99,97,99,104,101,46,60,108,
+    111,99,97,108,115,62,46,60,115,101,116,99,111,109,112,62,
+    78,41,18,114,35,0,0,0,114,3,0,0,0,90,7,108,
+    105,115,116,100,105,114,114,45,0,0,0,114,0,1,0,0,
+    218,15,80,101,114,109,105,115,115,105,111,110,69,114,114,111,
+    114,218,18,78,111,116,65,68,105,114,101,99,116,111,114,121,
+    69,114,114,111,114,114,7,0,0,0,114,8,0,0,0,114,
+    9,0,0,0,114,9,1,0,0,114,10,1,0,0,114,83,
+    0,0,0,114,47,0,0,0,114,88,0,0,0,218,3,97,
+    100,100,114,10,0,0,0,114,11,1,0,0,41,9,114,108,
+    0,0,0,114,35,0,0,0,90,8,99,111,110,116,101,110,
+    116,115,90,21,108,111,119,101,114,95,115,117,102,102,105,120,
+    95,99,111,110,116,101,110,116,115,114,245,0,0,0,114,106,
+    0,0,0,114,237,0,0,0,114,225,0,0,0,90,8,110,
+    101,119,95,110,97,109,101,114,4,0,0,0,114,4,0,0,
+    0,114,5,0,0,0,114,13,1,0,0,236,4,0,0,115,
+    34,0,0,0,0,2,9,1,3,1,31,1,22,3,11,3,
+    18,1,18,7,9,1,13,1,24,1,6,1,27,2,6,1,
+    17,1,9,1,18,1,122,22,70,105,108,101,70,105,110,100,
+    101,114,46,95,102,105,108,108,95,99,97,99,104,101,99,1,
+    0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,7,
+    0,0,0,115,25,0,0,0,135,0,0,135,1,0,102,2,
+    0,100,1,0,100,2,0,134,0,0,125,2,0,124,2,0,
+    83,41,3,97,20,1,0,0,65,32,99,108,97,115,115,32,
+    109,101,116,104,111,100,32,119,104,105,99,104,32,114,101,116,
+    117,114,110,115,32,97,32,99,108,111,115,117,114,101,32,116,
+    111,32,117,115,101,32,111,110,32,115,121,115,46,112,97,116,
+    104,95,104,111,111,107,10,32,32,32,32,32,32,32,32,119,
+    104,105,99,104,32,119,105,108,108,32,114,101,116,117,114,110,
+    32,97,110,32,105,110,115,116,97,110,99,101,32,117,115,105,
+    110,103,32,116,104,101,32,115,112,101,99,105,102,105,101,100,
+    32,108,111,97,100,101,114,115,32,97,110,100,32,116,104,101,
+    32,112,97,116,104,10,32,32,32,32,32,32,32,32,99,97,
+    108,108,101,100,32,111,110,32,116,104,101,32,99,108,111,115,
+    117,114,101,46,10,10,32,32,32,32,32,32,32,32,73,102,
+    32,116,104,101,32,112,97,116,104,32,99,97,108,108,101,100,
+    32,111,110,32,116,104,101,32,99,108,111,115,117,114,101,32,
+    105,115,32,110,111,116,32,97,32,100,105,114,101,99,116,111,
+    114,121,44,32,73,109,112,111,114,116,69,114,114,111,114,32,
+    105,115,10,32,32,32,32,32,32,32,32,114,97,105,115,101,
+    100,46,10,10,32,32,32,32,32,32,32,32,99,1,0,0,
+    0,0,0,0,0,1,0,0,0,4,0,0,0,19,0,0,
+    0,115,43,0,0,0,116,0,0,124,0,0,131,1,0,115,
+    30,0,116,1,0,100,1,0,100,2,0,124,0,0,131,1,
+    1,130,1,0,136,0,0,124,0,0,136,1,0,140,1,0,
+    83,41,3,122,45,80,97,116,104,32,104,111,111,107,32,102,
+    111,114,32,105,109,112,111,114,116,108,105,98,46,109,97,99,
+    104,105,110,101,114,121,46,70,105,108,101,70,105,110,100,101,
+    114,46,122,30,111,110,108,121,32,100,105,114,101,99,116,111,
+    114,105,101,115,32,97,114,101,32,115,117,112,112,111,114,116,
+    101,100,114,35,0,0,0,41,2,114,46,0,0,0,114,107,
+    0,0,0,41,1,114,35,0,0,0,41,2,114,170,0,0,
+    0,114,12,1,0,0,114,4,0,0,0,114,5,0,0,0,
+    218,24,112,97,116,104,95,104,111,111,107,95,102,111,114,95,
+    70,105,108,101,70,105,110,100,101,114,21,5,0,0,115,6,
+    0,0,0,0,2,12,1,18,1,122,54,70,105,108,101,70,
+    105,110,100,101,114,46,112,97,116,104,95,104,111,111,107,46,
+    60,108,111,99,97,108,115,62,46,112,97,116,104,95,104,111,
     111,107,95,102,111,114,95,70,105,108,101,70,105,110,100,101,
-    114,18,5,0,0,115,6,0,0,0,0,2,12,1,18,1,
-    122,54,70,105,108,101,70,105,110,100,101,114,46,112,97,116,
-    104,95,104,111,111,107,46,60,108,111,99,97,108,115,62,46,
-    112,97,116,104,95,104,111,111,107,95,102,111,114,95,70,105,
-    108,101,70,105,110,100,101,114,114,4,0,0,0,41,3,114,
-    170,0,0,0,114,12,1,0,0,114,18,1,0,0,114,4,
-    0,0,0,41,2,114,170,0,0,0,114,12,1,0,0,114,
-    5,0,0,0,218,9,112,97,116,104,95,104,111,111,107,8,
-    5,0,0,115,4,0,0,0,0,10,21,6,122,20,70,105,
-    108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111,
-    111,107,99,1,0,0,0,0,0,0,0,1,0,0,0,2,
-    0,0,0,67,0,0,0,115,16,0,0,0,100,1,0,106,
-    0,0,124,0,0,106,1,0,131,1,0,83,41,2,78,122,
-    16,70,105,108,101,70,105,110,100,101,114,40,123,33,114,125,
-    41,41,2,114,47,0,0,0,114,35,0,0,0,41,1,114,
-    108,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
-    0,0,0,114,244,0,0,0,26,5,0,0,115,2,0,0,
-    0,0,1,122,19,70,105,108,101,70,105,110,100,101,114,46,
-    95,95,114,101,112,114,95,95,41,15,114,112,0,0,0,114,
-    111,0,0,0,114,113,0,0,0,114,114,0,0,0,114,185,
-    0,0,0,114,250,0,0,0,114,130,0,0,0,114,182,0,
-    0,0,114,124,0,0,0,114,5,1,0,0,114,181,0,0,
-    0,114,13,1,0,0,114,183,0,0,0,114,19,1,0,0,
-    114,244,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    4,0,0,0,114,5,0,0,0,114,6,1,0,0,142,4,
-    0,0,115,20,0,0,0,12,7,6,2,12,14,12,4,6,
-    2,12,12,12,5,15,45,12,31,18,18,114,6,1,0,0,
-    99,4,0,0,0,0,0,0,0,6,0,0,0,11,0,0,
-    0,67,0,0,0,115,195,0,0,0,124,0,0,106,0,0,
-    100,1,0,131,1,0,125,4,0,124,0,0,106,0,0,100,
-    2,0,131,1,0,125,5,0,124,4,0,115,99,0,124,5,
-    0,114,54,0,124,5,0,106,1,0,125,4,0,110,45,0,
-    124,2,0,124,3,0,107,2,0,114,84,0,116,2,0,124,
-    1,0,124,2,0,131,2,0,125,4,0,110,15,0,116,3,
-    0,124,1,0,124,2,0,131,2,0,125,4,0,124,5,0,
-    115,126,0,116,4,0,124,1,0,124,2,0,100,3,0,124,
-    4,0,131,2,1,125,5,0,121,44,0,124,5,0,124,0,
-    0,100,2,0,60,124,4,0,124,0,0,100,1,0,60,124,
-    2,0,124,0,0,100,4,0,60,124,3,0,124,0,0,100,
-    5,0,60,87,110,18,0,4,116,5,0,107,10,0,114,190,
-    0,1,1,1,89,110,1,0,88,100,0,0,83,41,6,78,
-    218,10,95,95,108,111,97,100,101,114,95,95,218,8,95,95,
-    115,112,101,99,95,95,114,127,0,0,0,90,8,95,95,102,
-    105,108,101,95,95,90,10,95,95,99,97,99,104,101,100,95,
-    95,41,6,218,3,103,101,116,114,127,0,0,0,114,223,0,
-    0,0,114,218,0,0,0,114,167,0,0,0,218,9,69,120,
-    99,101,112,116,105,111,110,41,6,90,2,110,115,114,106,0,
-    0,0,90,8,112,97,116,104,110,97,109,101,90,9,99,112,
-    97,116,104,110,97,109,101,114,127,0,0,0,114,164,0,0,
-    0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
-    218,14,95,102,105,120,95,117,112,95,109,111,100,117,108,101,
-    32,5,0,0,115,34,0,0,0,0,2,15,1,15,1,6,
-    1,6,1,12,1,12,1,18,2,15,1,6,1,21,1,3,
-    1,10,1,10,1,10,1,14,1,13,2,114,24,1,0,0,
-    99,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,
-    0,67,0,0,0,115,55,0,0,0,116,0,0,116,1,0,
-    106,2,0,131,0,0,102,2,0,125,0,0,116,3,0,116,
-    4,0,102,2,0,125,1,0,116,5,0,116,6,0,102,2,
-    0,125,2,0,124,0,0,124,1,0,124,2,0,103,3,0,
-    83,41,1,122,95,82,101,116,117,114,110,115,32,97,32,108,
-    105,115,116,32,111,102,32,102,105,108,101,45,98,97,115,101,
-    100,32,109,111,100,117,108,101,32,108,111,97,100,101,114,115,
-    46,10,10,32,32,32,32,69,97,99,104,32,105,116,101,109,
-    32,105,115,32,97,32,116,117,112,108,101,32,40,108,111,97,
-    100,101,114,44,32,115,117,102,102,105,120,101,115,41,46,10,
-    32,32,32,32,41,7,114,224,0,0,0,114,145,0,0,0,
-    218,18,101,120,116,101,110,115,105,111,110,95,115,117,102,102,
-    105,120,101,115,114,218,0,0,0,114,84,0,0,0,114,223,
-    0,0,0,114,74,0,0,0,41,3,90,10,101,120,116,101,
-    110,115,105,111,110,115,90,6,115,111,117,114,99,101,90,8,
-    98,121,116,101,99,111,100,101,114,4,0,0,0,114,4,0,
-    0,0,114,5,0,0,0,114,161,0,0,0,55,5,0,0,
-    115,8,0,0,0,0,5,18,1,12,1,12,1,114,161,0,
-    0,0,99,1,0,0,0,0,0,0,0,12,0,0,0,12,
-    0,0,0,67,0,0,0,115,70,2,0,0,124,0,0,97,
-    0,0,116,0,0,106,1,0,97,1,0,116,0,0,106,2,
-    0,97,2,0,116,1,0,106,3,0,116,4,0,25,125,1,
-    0,120,76,0,100,26,0,68,93,68,0,125,2,0,124,2,
-    0,116,1,0,106,3,0,107,7,0,114,83,0,116,0,0,
-    106,5,0,124,2,0,131,1,0,125,3,0,110,13,0,116,
-    1,0,106,3,0,124,2,0,25,125,3,0,116,6,0,124,
-    1,0,124,2,0,124,3,0,131,3,0,1,113,44,0,87,
-    100,5,0,100,6,0,103,1,0,102,2,0,100,7,0,100,
-    8,0,100,6,0,103,2,0,102,2,0,102,2,0,125,4,
-    0,120,149,0,124,4,0,68,93,129,0,92,2,0,125,5,
-    0,125,6,0,116,7,0,100,9,0,100,10,0,132,0,0,
-    124,6,0,68,131,1,0,131,1,0,115,199,0,116,8,0,
-    130,1,0,124,6,0,100,11,0,25,125,7,0,124,5,0,
-    116,1,0,106,3,0,107,6,0,114,241,0,116,1,0,106,
-    3,0,124,5,0,25,125,8,0,80,113,156,0,121,20,0,
-    116,0,0,106,5,0,124,5,0,131,1,0,125,8,0,80,
-    87,113,156,0,4,116,9,0,107,10,0,114,28,1,1,1,
-    1,119,156,0,89,113,156,0,88,113,156,0,87,116,9,0,
-    100,12,0,131,1,0,130,1,0,116,6,0,124,1,0,100,
-    13,0,124,8,0,131,3,0,1,116,6,0,124,1,0,100,
-    14,0,124,7,0,131,3,0,1,116,6,0,124,1,0,100,
-    15,0,100,16,0,106,10,0,124,6,0,131,1,0,131,3,
-    0,1,121,19,0,116,0,0,106,5,0,100,17,0,131,1,
-    0,125,9,0,87,110,24,0,4,116,9,0,107,10,0,114,
-    147,1,1,1,1,100,18,0,125,9,0,89,110,1,0,88,
-    116,6,0,124,1,0,100,17,0,124,9,0,131,3,0,1,
-    116,0,0,106,5,0,100,19,0,131,1,0,125,10,0,116,
-    6,0,124,1,0,100,19,0,124,10,0,131,3,0,1,124,
-    5,0,100,7,0,107,2,0,114,238,1,116,0,0,106,5,
-    0,100,20,0,131,1,0,125,11,0,116,6,0,124,1,0,
-    100,21,0,124,11,0,131,3,0,1,116,6,0,124,1,0,
-    100,22,0,116,11,0,131,0,0,131,3,0,1,116,12,0,
-    106,13,0,116,2,0,106,14,0,131,0,0,131,1,0,1,
-    124,5,0,100,7,0,107,2,0,114,66,2,116,15,0,106,
-    16,0,100,23,0,131,1,0,1,100,24,0,116,12,0,107,
-    6,0,114,66,2,100,25,0,116,17,0,95,18,0,100,18,
-    0,83,41,27,122,205,83,101,116,117,112,32,116,104,101,32,
-    112,97,116,104,45,98,97,115,101,100,32,105,109,112,111,114,
-    116,101,114,115,32,102,111,114,32,105,109,112,111,114,116,108,
-    105,98,32,98,121,32,105,109,112,111,114,116,105,110,103,32,
-    110,101,101,100,101,100,10,32,32,32,32,98,117,105,108,116,
-    45,105,110,32,109,111,100,117,108,101,115,32,97,110,100,32,
-    105,110,106,101,99,116,105,110,103,32,116,104,101,109,32,105,
-    110,116,111,32,116,104,101,32,103,108,111,98,97,108,32,110,
-    97,109,101,115,112,97,99,101,46,10,10,32,32,32,32,79,
-    116,104,101,114,32,99,111,109,112,111,110,101,110,116,115,32,
-    97,114,101,32,101,120,116,114,97,99,116,101,100,32,102,114,
-    111,109,32,116,104,101,32,99,111,114,101,32,98,111,111,116,
-    115,116,114,97,112,32,109,111,100,117,108,101,46,10,10,32,
-    32,32,32,114,49,0,0,0,114,60,0,0,0,218,8,98,
-    117,105,108,116,105,110,115,114,142,0,0,0,90,5,112,111,
-    115,105,120,250,1,47,218,2,110,116,250,1,92,99,1,0,
-    0,0,0,0,0,0,2,0,0,0,3,0,0,0,115,0,
-    0,0,115,33,0,0,0,124,0,0,93,23,0,125,1,0,
-    116,0,0,124,1,0,131,1,0,100,0,0,107,2,0,86,
-    1,113,3,0,100,1,0,83,41,2,114,29,0,0,0,78,
-    41,1,114,31,0,0,0,41,2,114,22,0,0,0,114,77,
+    114,114,4,0,0,0,41,3,114,170,0,0,0,114,12,1,
+    0,0,114,18,1,0,0,114,4,0,0,0,41,2,114,170,
+    0,0,0,114,12,1,0,0,114,5,0,0,0,218,9,112,
+    97,116,104,95,104,111,111,107,11,5,0,0,115,4,0,0,
+    0,0,10,21,6,122,20,70,105,108,101,70,105,110,100,101,
+    114,46,112,97,116,104,95,104,111,111,107,99,1,0,0,0,
+    0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0,
+    115,16,0,0,0,100,1,0,106,0,0,124,0,0,106,1,
+    0,131,1,0,83,41,2,78,122,16,70,105,108,101,70,105,
+    110,100,101,114,40,123,33,114,125,41,41,2,114,47,0,0,
+    0,114,35,0,0,0,41,1,114,108,0,0,0,114,4,0,
+    0,0,114,4,0,0,0,114,5,0,0,0,114,244,0,0,
+    0,29,5,0,0,115,2,0,0,0,0,1,122,19,70,105,
+    108,101,70,105,110,100,101,114,46,95,95,114,101,112,114,95,
+    95,41,15,114,112,0,0,0,114,111,0,0,0,114,113,0,
+    0,0,114,114,0,0,0,114,185,0,0,0,114,250,0,0,
+    0,114,130,0,0,0,114,182,0,0,0,114,124,0,0,0,
+    114,5,1,0,0,114,181,0,0,0,114,13,1,0,0,114,
+    183,0,0,0,114,19,1,0,0,114,244,0,0,0,114,4,
     0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,
-    0,0,114,227,0,0,0,91,5,0,0,115,2,0,0,0,
-    6,0,122,25,95,115,101,116,117,112,46,60,108,111,99,97,
-    108,115,62,46,60,103,101,110,101,120,112,114,62,114,59,0,
-    0,0,122,30,105,109,112,111,114,116,108,105,98,32,114,101,
-    113,117,105,114,101,115,32,112,111,115,105,120,32,111,114,32,
-    110,116,114,3,0,0,0,114,25,0,0,0,114,21,0,0,
-    0,114,30,0,0,0,90,7,95,116,104,114,101,97,100,78,
-    90,8,95,119,101,97,107,114,101,102,90,6,119,105,110,114,
-    101,103,114,169,0,0,0,114,6,0,0,0,122,4,46,112,
-    121,119,122,6,95,100,46,112,121,100,84,41,4,122,3,95,
-    105,111,122,9,95,119,97,114,110,105,110,103,115,122,8,98,
-    117,105,108,116,105,110,115,122,7,109,97,114,115,104,97,108,
-    41,19,114,121,0,0,0,114,7,0,0,0,114,145,0,0,
-    0,114,239,0,0,0,114,112,0,0,0,90,18,95,98,117,
-    105,108,116,105,110,95,102,114,111,109,95,110,97,109,101,114,
-    116,0,0,0,218,3,97,108,108,218,14,65,115,115,101,114,
-    116,105,111,110,69,114,114,111,114,114,107,0,0,0,114,26,
-    0,0,0,114,11,0,0,0,114,229,0,0,0,114,149,0,
-    0,0,114,25,1,0,0,114,84,0,0,0,114,163,0,0,
-    0,114,168,0,0,0,114,173,0,0,0,41,12,218,17,95,
-    98,111,111,116,115,116,114,97,112,95,109,111,100,117,108,101,
-    90,11,115,101,108,102,95,109,111,100,117,108,101,90,12,98,
-    117,105,108,116,105,110,95,110,97,109,101,90,14,98,117,105,
-    108,116,105,110,95,109,111,100,117,108,101,90,10,111,115,95,
-    100,101,116,97,105,108,115,90,10,98,117,105,108,116,105,110,
-    95,111,115,114,21,0,0,0,114,25,0,0,0,90,9,111,
-    115,95,109,111,100,117,108,101,90,13,116,104,114,101,97,100,
-    95,109,111,100,117,108,101,90,14,119,101,97,107,114,101,102,
-    95,109,111,100,117,108,101,90,13,119,105,110,114,101,103,95,
-    109,111,100,117,108,101,114,4,0,0,0,114,4,0,0,0,
-    114,5,0,0,0,218,6,95,115,101,116,117,112,66,5,0,
-    0,115,82,0,0,0,0,8,6,1,9,1,9,3,13,1,
-    13,1,15,1,18,2,13,1,20,3,33,1,19,2,31,1,
-    10,1,15,1,13,1,4,2,3,1,15,1,5,1,13,1,
-    12,2,12,1,16,1,16,1,25,3,3,1,19,1,13,2,
-    11,1,16,3,15,1,16,3,12,1,15,1,16,3,19,1,
-    19,1,12,1,13,1,12,1,114,33,1,0,0,99,1,0,
-    0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,
-    0,0,115,116,0,0,0,116,0,0,124,0,0,131,1,0,
-    1,116,1,0,131,0,0,125,1,0,116,2,0,106,3,0,
-    106,4,0,116,5,0,106,6,0,124,1,0,140,0,0,103,
-    1,0,131,1,0,1,116,7,0,106,8,0,100,1,0,107,
-    2,0,114,78,0,116,2,0,106,9,0,106,10,0,116,11,
-    0,131,1,0,1,116,2,0,106,9,0,106,10,0,116,12,
-    0,131,1,0,1,116,5,0,124,0,0,95,5,0,116,13,
-    0,124,0,0,95,13,0,100,2,0,83,41,3,122,41,73,
-    110,115,116,97,108,108,32,116,104,101,32,112,97,116,104,45,
-    98,97,115,101,100,32,105,109,112,111,114,116,32,99,111,109,
-    112,111,110,101,110,116,115,46,114,28,1,0,0,78,41,14,
-    114,33,1,0,0,114,161,0,0,0,114,7,0,0,0,114,
-    254,0,0,0,114,149,0,0,0,114,6,1,0,0,114,19,
-    1,0,0,114,3,0,0,0,114,112,0,0,0,218,9,109,
-    101,116,97,95,112,97,116,104,114,163,0,0,0,114,168,0,
-    0,0,114,249,0,0,0,114,218,0,0,0,41,2,114,32,
-    1,0,0,90,17,115,117,112,112,111,114,116,101,100,95,108,
-    111,97,100,101,114,115,114,4,0,0,0,114,4,0,0,0,
-    114,5,0,0,0,218,8,95,105,110,115,116,97,108,108,134,
-    5,0,0,115,16,0,0,0,0,2,10,1,9,1,28,1,
-    15,1,16,1,16,4,9,1,114,35,1,0,0,41,3,122,
-    3,119,105,110,114,1,0,0,0,114,2,0,0,0,41,57,
-    114,114,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
-    17,0,0,0,114,19,0,0,0,114,28,0,0,0,114,38,
-    0,0,0,114,39,0,0,0,114,43,0,0,0,114,44,0,
-    0,0,114,46,0,0,0,114,55,0,0,0,218,4,116,121,
-    112,101,218,8,95,95,99,111,100,101,95,95,114,144,0,0,
-    0,114,15,0,0,0,114,135,0,0,0,114,14,0,0,0,
-    114,18,0,0,0,90,17,95,82,65,87,95,77,65,71,73,
-    67,95,78,85,77,66,69,82,114,73,0,0,0,114,72,0,
-    0,0,114,84,0,0,0,114,74,0,0,0,90,23,68,69,
-    66,85,71,95,66,89,84,69,67,79,68,69,95,83,85,70,
-    70,73,88,69,83,90,27,79,80,84,73,77,73,90,69,68,
-    95,66,89,84,69,67,79,68,69,95,83,85,70,70,73,88,
-    69,83,114,79,0,0,0,114,85,0,0,0,114,91,0,0,
-    0,114,95,0,0,0,114,97,0,0,0,114,105,0,0,0,
-    114,123,0,0,0,114,130,0,0,0,114,141,0,0,0,114,
-    147,0,0,0,114,150,0,0,0,114,155,0,0,0,218,6,
-    111,98,106,101,99,116,114,162,0,0,0,114,167,0,0,0,
-    114,168,0,0,0,114,184,0,0,0,114,194,0,0,0,114,
-    210,0,0,0,114,218,0,0,0,114,223,0,0,0,114,229,
-    0,0,0,114,224,0,0,0,114,230,0,0,0,114,247,0,
-    0,0,114,249,0,0,0,114,6,1,0,0,114,24,1,0,
-    0,114,161,0,0,0,114,33,1,0,0,114,35,1,0,0,
-    114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
-    5,0,0,0,218,8,60,109,111,100,117,108,101,62,8,0,
-    0,0,115,100,0,0,0,6,17,6,3,12,12,12,5,12,
-    5,12,6,12,12,12,10,12,9,12,5,12,7,15,22,15,
-    110,22,1,18,2,6,1,6,2,9,2,9,2,10,2,21,
-    44,12,33,12,19,12,12,12,12,18,8,12,28,12,17,21,
-    55,21,12,18,10,12,14,9,3,12,1,15,65,19,64,19,
-    28,22,110,19,41,25,43,25,16,6,3,25,53,19,57,19,
-    41,19,134,19,146,15,23,12,11,12,68,
+    0,0,114,6,1,0,0,145,4,0,0,115,20,0,0,0,
+    12,7,6,2,12,14,12,4,6,2,12,12,12,5,15,45,
+    12,31,18,18,114,6,1,0,0,99,4,0,0,0,0,0,
+    0,0,6,0,0,0,11,0,0,0,67,0,0,0,115,195,
+    0,0,0,124,0,0,106,0,0,100,1,0,131,1,0,125,
+    4,0,124,0,0,106,0,0,100,2,0,131,1,0,125,5,
+    0,124,4,0,115,99,0,124,5,0,114,54,0,124,5,0,
+    106,1,0,125,4,0,110,45,0,124,2,0,124,3,0,107,
+    2,0,114,84,0,116,2,0,124,1,0,124,2,0,131,2,
+    0,125,4,0,110,15,0,116,3,0,124,1,0,124,2,0,
+    131,2,0,125,4,0,124,5,0,115,126,0,116,4,0,124,
+    1,0,124,2,0,100,3,0,124,4,0,131,2,1,125,5,
+    0,121,44,0,124,5,0,124,0,0,100,2,0,60,124,4,
+    0,124,0,0,100,1,0,60,124,2,0,124,0,0,100,4,
+    0,60,124,3,0,124,0,0,100,5,0,60,87,110,18,0,
+    4,116,5,0,107,10,0,114,190,0,1,1,1,89,110,1,
+    0,88,100,0,0,83,41,6,78,218,10,95,95,108,111,97,
+    100,101,114,95,95,218,8,95,95,115,112,101,99,95,95,114,
+    127,0,0,0,90,8,95,95,102,105,108,101,95,95,90,10,
+    95,95,99,97,99,104,101,100,95,95,41,6,218,3,103,101,
+    116,114,127,0,0,0,114,223,0,0,0,114,218,0,0,0,
+    114,167,0,0,0,218,9,69,120,99,101,112,116,105,111,110,
+    41,6,90,2,110,115,114,106,0,0,0,90,8,112,97,116,
+    104,110,97,109,101,90,9,99,112,97,116,104,110,97,109,101,
+    114,127,0,0,0,114,164,0,0,0,114,4,0,0,0,114,
+    4,0,0,0,114,5,0,0,0,218,14,95,102,105,120,95,
+    117,112,95,109,111,100,117,108,101,35,5,0,0,115,34,0,
+    0,0,0,2,15,1,15,1,6,1,6,1,12,1,12,1,
+    18,2,15,1,6,1,21,1,3,1,10,1,10,1,10,1,
+    14,1,13,2,114,24,1,0,0,99,0,0,0,0,0,0,
+    0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,55,
+    0,0,0,116,0,0,116,1,0,106,2,0,131,0,0,102,
+    2,0,125,0,0,116,3,0,116,4,0,102,2,0,125,1,
+    0,116,5,0,116,6,0,102,2,0,125,2,0,124,0,0,
+    124,1,0,124,2,0,103,3,0,83,41,1,122,95,82,101,
+    116,117,114,110,115,32,97,32,108,105,115,116,32,111,102,32,
+    102,105,108,101,45,98,97,115,101,100,32,109,111,100,117,108,
+    101,32,108,111,97,100,101,114,115,46,10,10,32,32,32,32,
+    69,97,99,104,32,105,116,101,109,32,105,115,32,97,32,116,
+    117,112,108,101,32,40,108,111,97,100,101,114,44,32,115,117,
+    102,102,105,120,101,115,41,46,10,32,32,32,32,41,7,114,
+    224,0,0,0,114,145,0,0,0,218,18,101,120,116,101,110,
+    115,105,111,110,95,115,117,102,102,105,120,101,115,114,218,0,
+    0,0,114,84,0,0,0,114,223,0,0,0,114,74,0,0,
+    0,41,3,90,10,101,120,116,101,110,115,105,111,110,115,90,
+    6,115,111,117,114,99,101,90,8,98,121,116,101,99,111,100,
+    101,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
+    114,161,0,0,0,58,5,0,0,115,8,0,0,0,0,5,
+    18,1,12,1,12,1,114,161,0,0,0,99,1,0,0,0,
+    0,0,0,0,12,0,0,0,12,0,0,0,67,0,0,0,
+    115,70,2,0,0,124,0,0,97,0,0,116,0,0,106,1,
+    0,97,1,0,116,0,0,106,2,0,97,2,0,116,1,0,
+    106,3,0,116,4,0,25,125,1,0,120,76,0,100,26,0,
+    68,93,68,0,125,2,0,124,2,0,116,1,0,106,3,0,
+    107,7,0,114,83,0,116,0,0,106,5,0,124,2,0,131,
+    1,0,125,3,0,110,13,0,116,1,0,106,3,0,124,2,
+    0,25,125,3,0,116,6,0,124,1,0,124,2,0,124,3,
+    0,131,3,0,1,113,44,0,87,100,5,0,100,6,0,103,
+    1,0,102,2,0,100,7,0,100,8,0,100,6,0,103,2,
+    0,102,2,0,102,2,0,125,4,0,120,149,0,124,4,0,
+    68,93,129,0,92,2,0,125,5,0,125,6,0,116,7,0,
+    100,9,0,100,10,0,132,0,0,124,6,0,68,131,1,0,
+    131,1,0,115,199,0,116,8,0,130,1,0,124,6,0,100,
+    11,0,25,125,7,0,124,5,0,116,1,0,106,3,0,107,
+    6,0,114,241,0,116,1,0,106,3,0,124,5,0,25,125,
+    8,0,80,113,156,0,121,20,0,116,0,0,106,5,0,124,
+    5,0,131,1,0,125,8,0,80,87,113,156,0,4,116,9,
+    0,107,10,0,114,28,1,1,1,1,119,156,0,89,113,156,
+    0,88,113,156,0,87,116,9,0,100,12,0,131,1,0,130,
+    1,0,116,6,0,124,1,0,100,13,0,124,8,0,131,3,
+    0,1,116,6,0,124,1,0,100,14,0,124,7,0,131,3,
+    0,1,116,6,0,124,1,0,100,15,0,100,16,0,106,10,
+    0,124,6,0,131,1,0,131,3,0,1,121,19,0,116,0,
+    0,106,5,0,100,17,0,131,1,0,125,9,0,87,110,24,
+    0,4,116,9,0,107,10,0,114,147,1,1,1,1,100,18,
+    0,125,9,0,89,110,1,0,88,116,6,0,124,1,0,100,
+    17,0,124,9,0,131,3,0,1,116,0,0,106,5,0,100,
+    19,0,131,1,0,125,10,0,116,6,0,124,1,0,100,19,
+    0,124,10,0,131,3,0,1,124,5,0,100,7,0,107,2,
+    0,114,238,1,116,0,0,106,5,0,100,20,0,131,1,0,
+    125,11,0,116,6,0,124,1,0,100,21,0,124,11,0,131,
+    3,0,1,116,6,0,124,1,0,100,22,0,116,11,0,131,
+    0,0,131,3,0,1,116,12,0,106,13,0,116,2,0,106,
+    14,0,131,0,0,131,1,0,1,124,5,0,100,7,0,107,
+    2,0,114,66,2,116,15,0,106,16,0,100,23,0,131,1,
+    0,1,100,24,0,116,12,0,107,6,0,114,66,2,100,25,
+    0,116,17,0,95,18,0,100,18,0,83,41,27,122,205,83,
+    101,116,117,112,32,116,104,101,32,112,97,116,104,45,98,97,
+    115,101,100,32,105,109,112,111,114,116,101,114,115,32,102,111,
+    114,32,105,109,112,111,114,116,108,105,98,32,98,121,32,105,
+    109,112,111,114,116,105,110,103,32,110,101,101,100,101,100,10,
+    32,32,32,32,98,117,105,108,116,45,105,110,32,109,111,100,
+    117,108,101,115,32,97,110,100,32,105,110,106,101,99,116,105,
+    110,103,32,116,104,101,109,32,105,110,116,111,32,116,104,101,
+    32,103,108,111,98,97,108,32,110,97,109,101,115,112,97,99,
+    101,46,10,10,32,32,32,32,79,116,104,101,114,32,99,111,
+    109,112,111,110,101,110,116,115,32,97,114,101,32,101,120,116,
+    114,97,99,116,101,100,32,102,114,111,109,32,116,104,101,32,
+    99,111,114,101,32,98,111,111,116,115,116,114,97,112,32,109,
+    111,100,117,108,101,46,10,10,32,32,32,32,114,49,0,0,
+    0,114,60,0,0,0,218,8,98,117,105,108,116,105,110,115,
+    114,142,0,0,0,90,5,112,111,115,105,120,250,1,47,218,
+    2,110,116,250,1,92,99,1,0,0,0,0,0,0,0,2,
+    0,0,0,3,0,0,0,115,0,0,0,115,33,0,0,0,
+    124,0,0,93,23,0,125,1,0,116,0,0,124,1,0,131,
+    1,0,100,0,0,107,2,0,86,1,113,3,0,100,1,0,
+    83,41,2,114,29,0,0,0,78,41,1,114,31,0,0,0,
+    41,2,114,22,0,0,0,114,77,0,0,0,114,4,0,0,
+    0,114,4,0,0,0,114,5,0,0,0,114,227,0,0,0,
+    94,5,0,0,115,2,0,0,0,6,0,122,25,95,115,101,
+    116,117,112,46,60,108,111,99,97,108,115,62,46,60,103,101,
+    110,101,120,112,114,62,114,59,0,0,0,122,30,105,109,112,
+    111,114,116,108,105,98,32,114,101,113,117,105,114,101,115,32,
+    112,111,115,105,120,32,111,114,32,110,116,114,3,0,0,0,
+    114,25,0,0,0,114,21,0,0,0,114,30,0,0,0,90,
+    7,95,116,104,114,101,97,100,78,90,8,95,119,101,97,107,
+    114,101,102,90,6,119,105,110,114,101,103,114,169,0,0,0,
+    114,6,0,0,0,122,4,46,112,121,119,122,6,95,100,46,
+    112,121,100,84,41,4,122,3,95,105,111,122,9,95,119,97,
+    114,110,105,110,103,115,122,8,98,117,105,108,116,105,110,115,
+    122,7,109,97,114,115,104,97,108,41,19,114,121,0,0,0,
+    114,7,0,0,0,114,145,0,0,0,114,239,0,0,0,114,
+    112,0,0,0,90,18,95,98,117,105,108,116,105,110,95,102,
+    114,111,109,95,110,97,109,101,114,116,0,0,0,218,3,97,
+    108,108,218,14,65,115,115,101,114,116,105,111,110,69,114,114,
+    111,114,114,107,0,0,0,114,26,0,0,0,114,11,0,0,
+    0,114,229,0,0,0,114,149,0,0,0,114,25,1,0,0,
+    114,84,0,0,0,114,163,0,0,0,114,168,0,0,0,114,
+    173,0,0,0,41,12,218,17,95,98,111,111,116,115,116,114,
+    97,112,95,109,111,100,117,108,101,90,11,115,101,108,102,95,
+    109,111,100,117,108,101,90,12,98,117,105,108,116,105,110,95,
+    110,97,109,101,90,14,98,117,105,108,116,105,110,95,109,111,
+    100,117,108,101,90,10,111,115,95,100,101,116,97,105,108,115,
+    90,10,98,117,105,108,116,105,110,95,111,115,114,21,0,0,
+    0,114,25,0,0,0,90,9,111,115,95,109,111,100,117,108,
+    101,90,13,116,104,114,101,97,100,95,109,111,100,117,108,101,
+    90,14,119,101,97,107,114,101,102,95,109,111,100,117,108,101,
+    90,13,119,105,110,114,101,103,95,109,111,100,117,108,101,114,
+    4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,6,
+    95,115,101,116,117,112,69,5,0,0,115,82,0,0,0,0,
+    8,6,1,9,1,9,3,13,1,13,1,15,1,18,2,13,
+    1,20,3,33,1,19,2,31,1,10,1,15,1,13,1,4,
+    2,3,1,15,1,5,1,13,1,12,2,12,1,16,1,16,
+    1,25,3,3,1,19,1,13,2,11,1,16,3,15,1,16,
+    3,12,1,15,1,16,3,19,1,19,1,12,1,13,1,12,
+    1,114,33,1,0,0,99,1,0,0,0,0,0,0,0,2,
+    0,0,0,3,0,0,0,67,0,0,0,115,116,0,0,0,
+    116,0,0,124,0,0,131,1,0,1,116,1,0,131,0,0,
+    125,1,0,116,2,0,106,3,0,106,4,0,116,5,0,106,
+    6,0,124,1,0,140,0,0,103,1,0,131,1,0,1,116,
+    7,0,106,8,0,100,1,0,107,2,0,114,78,0,116,2,
+    0,106,9,0,106,10,0,116,11,0,131,1,0,1,116,2,
+    0,106,9,0,106,10,0,116,12,0,131,1,0,1,116,5,
+    0,124,0,0,95,5,0,116,13,0,124,0,0,95,13,0,
+    100,2,0,83,41,3,122,41,73,110,115,116,97,108,108,32,
+    116,104,101,32,112,97,116,104,45,98,97,115,101,100,32,105,
+    109,112,111,114,116,32,99,111,109,112,111,110,101,110,116,115,
+    46,114,28,1,0,0,78,41,14,114,33,1,0,0,114,161,
+    0,0,0,114,7,0,0,0,114,254,0,0,0,114,149,0,
+    0,0,114,6,1,0,0,114,19,1,0,0,114,3,0,0,
+    0,114,112,0,0,0,218,9,109,101,116,97,95,112,97,116,
+    104,114,163,0,0,0,114,168,0,0,0,114,249,0,0,0,
+    114,218,0,0,0,41,2,114,32,1,0,0,90,17,115,117,
+    112,112,111,114,116,101,100,95,108,111,97,100,101,114,115,114,
+    4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,8,
+    95,105,110,115,116,97,108,108,137,5,0,0,115,16,0,0,
+    0,0,2,10,1,9,1,28,1,15,1,16,1,16,4,9,
+    1,114,35,1,0,0,41,3,122,3,119,105,110,114,1,0,
+    0,0,114,2,0,0,0,41,57,114,114,0,0,0,114,10,
+    0,0,0,114,11,0,0,0,114,17,0,0,0,114,19,0,
+    0,0,114,28,0,0,0,114,38,0,0,0,114,39,0,0,
+    0,114,43,0,0,0,114,44,0,0,0,114,46,0,0,0,
+    114,55,0,0,0,218,4,116,121,112,101,218,8,95,95,99,
+    111,100,101,95,95,114,144,0,0,0,114,15,0,0,0,114,
+    135,0,0,0,114,14,0,0,0,114,18,0,0,0,90,17,
+    95,82,65,87,95,77,65,71,73,67,95,78,85,77,66,69,
+    82,114,73,0,0,0,114,72,0,0,0,114,84,0,0,0,
+    114,74,0,0,0,90,23,68,69,66,85,71,95,66,89,84,
+    69,67,79,68,69,95,83,85,70,70,73,88,69,83,90,27,
+    79,80,84,73,77,73,90,69,68,95,66,89,84,69,67,79,
+    68,69,95,83,85,70,70,73,88,69,83,114,79,0,0,0,
+    114,85,0,0,0,114,91,0,0,0,114,95,0,0,0,114,
+    97,0,0,0,114,105,0,0,0,114,123,0,0,0,114,130,
+    0,0,0,114,141,0,0,0,114,147,0,0,0,114,150,0,
+    0,0,114,155,0,0,0,218,6,111,98,106,101,99,116,114,
+    162,0,0,0,114,167,0,0,0,114,168,0,0,0,114,184,
+    0,0,0,114,194,0,0,0,114,210,0,0,0,114,218,0,
+    0,0,114,223,0,0,0,114,229,0,0,0,114,224,0,0,
+    0,114,230,0,0,0,114,247,0,0,0,114,249,0,0,0,
+    114,6,1,0,0,114,24,1,0,0,114,161,0,0,0,114,
+    33,1,0,0,114,35,1,0,0,114,4,0,0,0,114,4,
+    0,0,0,114,4,0,0,0,114,5,0,0,0,218,8,60,
+    109,111,100,117,108,101,62,8,0,0,0,115,100,0,0,0,
+    6,17,6,3,12,12,12,5,12,5,12,6,12,12,12,10,
+    12,9,12,5,12,7,15,22,15,113,22,1,18,2,6,1,
+    6,2,9,2,9,2,10,2,21,44,12,33,12,19,12,12,
+    12,12,18,8,12,28,12,17,21,55,21,12,18,10,12,14,
+    9,3,12,1,15,65,19,64,19,28,22,110,19,41,25,43,
+    25,16,6,3,25,53,19,57,19,41,19,134,19,146,15,23,
+    12,11,12,68,
 };
index f89cd04..5b8de99 100644 (file)
@@ -1644,7 +1644,7 @@ The file must be an open file object such as sys.stdout or returned by\n\
 open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\
 \n\
 If the value has (or contains an object that has) an unsupported type, a\n\
-ValueError exception is raised  but garbage data will also be written\n\
+ValueError exception is raised - but garbage data will also be written\n\
 to the file. The object will not be properly read back by load()\n\
 \n\
 The version argument indicates the data format that dump should use.");
@@ -1695,7 +1695,7 @@ PyDoc_STRVAR(load_doc,
 "load(file)\n\
 \n\
 Read one value from the open file and return it. If no valid value is\n\
-read (e.g. because the data has a different Python versions\n\
+read (e.g. because the data has a different Python version's\n\
 incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
 The file must be an open file object opened in binary mode ('rb' or\n\
 'r+b').\n\
index 6c938dd..0d09371 100644 (file)
@@ -63,48 +63,84 @@ static PyObject *do_mkdict(const char**, va_list *, int, int, int);
 static PyObject *do_mkvalue(const char**, va_list *, int);
 
 
+static void
+do_ignore(const char **p_format, va_list *p_va, int endchar, int n, int flags)
+{
+    PyObject *v;
+    int i;
+    assert(PyErr_Occurred());
+    v = PyTuple_New(n);
+    for (i = 0; i < n; i++) {
+        PyObject *exception, *value, *tb, *w;
+
+        PyErr_Fetch(&exception, &value, &tb);
+        w = do_mkvalue(p_format, p_va, flags);
+        PyErr_Restore(exception, value, tb);
+        if (w != NULL) {
+            if (v != NULL) {
+                PyTuple_SET_ITEM(v, i, w);
+            }
+            else {
+                Py_DECREF(w);
+            }
+        }
+    }
+    Py_XDECREF(v);
+    if (**p_format != endchar) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unmatched paren in format");
+        return;
+    }
+    if (endchar)
+        ++*p_format;
+}
+
 static PyObject *
 do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
 {
     PyObject *d;
     int i;
-    int itemfailed = 0;
     if (n < 0)
         return NULL;
-    if ((d = PyDict_New()) == NULL)
+    if (n % 2) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Bad dict format");
+        do_ignore(p_format, p_va, endchar, n, flags);
         return NULL;
+    }
     /* Note that we can't bail immediately on error as this will leak
        refcounts on any 'N' arguments. */
+    if ((d = PyDict_New()) == NULL) {
+        do_ignore(p_format, p_va, endchar, n, flags);
+        return NULL;
+    }
     for (i = 0; i < n; i+= 2) {
         PyObject *k, *v;
-        int err;
+
         k = do_mkvalue(p_format, p_va, flags);
         if (k == NULL) {
-            itemfailed = 1;
-            Py_INCREF(Py_None);
-            k = Py_None;
+            do_ignore(p_format, p_va, endchar, n - i - 1, flags);
+            Py_DECREF(d);
+            return NULL;
         }
         v = do_mkvalue(p_format, p_va, flags);
-        if (v == NULL) {
-            itemfailed = 1;
-            Py_INCREF(Py_None);
-            v = Py_None;
-        }
-        err = PyDict_SetItem(d, k, v);
-        Py_DECREF(k);
-        Py_DECREF(v);
-        if (err < 0 || itemfailed) {
+        if (v == NULL || PyDict_SetItem(d, k, v) < 0) {
+            do_ignore(p_format, p_va, endchar, n - i - 2, flags);
+            Py_DECREF(k);
+            Py_XDECREF(v);
             Py_DECREF(d);
             return NULL;
         }
+        Py_DECREF(k);
+        Py_DECREF(v);
     }
-    if (d != NULL && **p_format != endchar) {
+    if (**p_format != endchar) {
         Py_DECREF(d);
-        d = NULL;
         PyErr_SetString(PyExc_SystemError,
                         "Unmatched paren in format");
+        return NULL;
     }
-    else if (endchar)
+    if (endchar)
         ++*p_format;
     return d;
 }
@@ -114,29 +150,24 @@ do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
 {
     PyObject *v;
     int i;
-    int itemfailed = 0;
     if (n < 0)
         return NULL;
-    v = PyList_New(n);
-    if (v == NULL)
-        return NULL;
     /* Note that we can't bail immediately on error as this will leak
        refcounts on any 'N' arguments. */
+    v = PyList_New(n);
+    if (v == NULL) {
+        do_ignore(p_format, p_va, endchar, n, flags);
+        return NULL;
+    }
     for (i = 0; i < n; i++) {
         PyObject *w = do_mkvalue(p_format, p_va, flags);
         if (w == NULL) {
-            itemfailed = 1;
-            Py_INCREF(Py_None);
-            w = Py_None;
+            do_ignore(p_format, p_va, endchar, n - i - 1, flags);
+            Py_DECREF(v);
+            return NULL;
         }
         PyList_SET_ITEM(v, i, w);
     }
-
-    if (itemfailed) {
-        /* do_mkvalue() should have already set an error */
-        Py_DECREF(v);
-        return NULL;
-    }
     if (**p_format != endchar) {
         Py_DECREF(v);
         PyErr_SetString(PyExc_SystemError,
@@ -153,37 +184,23 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
 {
     PyObject *v;
     int i;
-    int itemfailed = 0;
     if (n < 0)
         return NULL;
-    if ((v = PyTuple_New(n)) == NULL)
-        return NULL;
     /* Note that we can't bail immediately on error as this will leak
        refcounts on any 'N' arguments. */
+    if ((v = PyTuple_New(n)) == NULL) {
+        do_ignore(p_format, p_va, endchar, n, flags);
+        return NULL;
+    }
     for (i = 0; i < n; i++) {
-        PyObject *w;
-
-        if (itemfailed) {
-            PyObject *exception, *value, *tb;
-            PyErr_Fetch(&exception, &value, &tb);
-            w = do_mkvalue(p_format, p_va, flags);
-            PyErr_Restore(exception, value, tb);
-        }
-        else {
-            w = do_mkvalue(p_format, p_va, flags);
-        }
+        PyObject *w = do_mkvalue(p_format, p_va, flags);
         if (w == NULL) {
-            itemfailed = 1;
-            Py_INCREF(Py_None);
-            w = Py_None;
+            do_ignore(p_format, p_va, endchar, n - i - 1, flags);
+            Py_DECREF(v);
+            return NULL;
         }
         PyTuple_SET_ITEM(v, i, w);
     }
-    if (itemfailed) {
-        /* do_mkvalue() should have already set an error */
-        Py_DECREF(v);
-        return NULL;
-    }
     if (**p_format != endchar) {
         Py_DECREF(v);
         PyErr_SetString(PyExc_SystemError,
index 59ad3b7..4e657fa 100644 (file)
@@ -344,7 +344,7 @@ markblocks(unsigned char *code, Py_ssize_t len)
    appear before MAKE_FUNCTION; in this case both opcodes are skipped.
    EXTENDED_ARG preceding any other opcode causes the optimizer to bail.
 
-   Optimizations are restricted to simple transformations occuring within a
+   Optimizations are restricted to simple transformations occurring within a
    single basic block.  All transformations keep the code size the same or
    smaller.  For those that reduce size, the gaps are initially filled with
    NOPs.  Later those NOPs are removed and the jump addresses retargeted in
index 4f5efc9..ce52990 100644 (file)
@@ -1135,15 +1135,6 @@ initstdio(void)
     encoding = _Py_StandardStreamEncoding;
     errors = _Py_StandardStreamErrors;
     if (!encoding || !errors) {
-        if (!errors) {
-            /* When the LC_CTYPE locale is the POSIX locale ("C locale"),
-               stdin and stdout use the surrogateescape error handler by
-               default, instead of the strict error handler. */
-            char *loc = setlocale(LC_CTYPE, NULL);
-            if (loc != NULL && strcmp(loc, "C") == 0)
-                errors = "surrogateescape";
-        }
-
         pythonioencoding = Py_GETENV("PYTHONIOENCODING");
         if (pythonioencoding) {
             char *err;
@@ -1156,7 +1147,7 @@ initstdio(void)
             if (err) {
                 *err = '\0';
                 err++;
-                if (*err && !_Py_StandardStreamErrors) {
+                if (*err && !errors) {
                     errors = err;
                 }
             }
@@ -1164,6 +1155,14 @@ initstdio(void)
                 encoding = pythonioencoding;
             }
         }
+        if (!errors && !(pythonioencoding && *pythonioencoding)) {
+            /* When the LC_CTYPE locale is the POSIX locale ("C locale"),
+               stdin and stdout use the surrogateescape error handler by
+               default, instead of the strict error handler. */
+            char *loc = setlocale(LC_CTYPE, NULL);
+            if (loc != NULL && strcmp(loc, "C") == 0)
+                errors = "surrogateescape";
+        }
     }
 
     /* Set sys.stdin */
@@ -1241,31 +1240,62 @@ initstdio(void)
 }
 
 
+static void
+_Py_FatalError_DumpTracebacks(int fd)
+{
+    PyThreadState *tstate;
+
+#ifdef WITH_THREAD
+    /* PyGILState_GetThisThreadState() works even if the GIL was released */
+    tstate = PyGILState_GetThisThreadState();
+#else
+    tstate = PyThreadState_GET();
+#endif
+    if (tstate == NULL) {
+        /* _Py_DumpTracebackThreads() requires the thread state to display
+         * frames */
+        return;
+    }
+
+    fputc('\n', stderr);
+    fflush(stderr);
+
+    /* display the current Python stack */
+    _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
+}
+
 /* Print the current exception (if an exception is set) with its traceback,
- * or display the current Python stack.
- *
- * Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
- * called on catastrophic cases. */
+   or display the current Python stack.
 
-static void
-_Py_PrintFatalError(int fd)
+   Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
+   called on catastrophic cases.
+
+   Return 1 if the traceback was displayed, 0 otherwise. */
+
+static int
+_Py_FatalError_PrintExc(int fd)
 {
     PyObject *ferr, *res;
     PyObject *exception, *v, *tb;
     int has_tb;
-    PyThreadState *tstate;
+
+    if (PyThreadState_GET() == NULL) {
+        /* The GIL is released: trying to acquire it is likely to deadlock,
+           just give up. */
+        return 0;
+    }
 
     PyErr_Fetch(&exception, &v, &tb);
     if (exception == NULL) {
         /* No current exception */
-        goto display_stack;
+        return 0;
     }
 
     ferr = _PySys_GetObjectId(&PyId_stderr);
     if (ferr == NULL || ferr == Py_None) {
         /* sys.stderr is not set yet or set to None,
            no need to try to display the exception */
-        goto display_stack;
+        return 0;
     }
 
     PyErr_NormalizeException(&exception, &v, &tb);
@@ -1276,7 +1306,7 @@ _Py_PrintFatalError(int fd)
     PyException_SetTraceback(v, tb);
     if (exception == NULL) {
         /* PyErr_NormalizeException() failed */
-        goto display_stack;
+        return 0;
     }
 
     has_tb = (tb != Py_None);
@@ -1292,28 +1322,9 @@ _Py_PrintFatalError(int fd)
     else
         Py_DECREF(res);
 
-    if (has_tb)
-        return;
-
-display_stack:
-#ifdef WITH_THREAD
-    /* PyGILState_GetThisThreadState() works even if the GIL was released */
-    tstate = PyGILState_GetThisThreadState();
-#else
-    tstate = PyThreadState_GET();
-#endif
-    if (tstate == NULL) {
-        /* _Py_DumpTracebackThreads() requires the thread state to display
-         * frames */
-        return;
-    }
-
-    fputc('\n', stderr);
-    fflush(stderr);
-
-    /* display the current Python stack */
-    _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
+    return has_tb;
 }
+
 /* Print fatal error message and abort */
 
 void
@@ -1339,16 +1350,20 @@ Py_FatalError(const char *msg)
 
     /* Print the exception (if an exception is set) with its traceback,
      * or display the current Python stack. */
-    _Py_PrintFatalError(fd);
-
-    /* Flush sys.stdout and sys.stderr */
-    flush_std_files();
+    if (!_Py_FatalError_PrintExc(fd))
+        _Py_FatalError_DumpTracebacks(fd);
 
     /* The main purpose of faulthandler is to display the traceback. We already
      * did our best to display it. So faulthandler can now be disabled.
      * (Don't trigger it on abort().) */
     _PyFaulthandler_Fini();
 
+    /* Check if the current Python thread hold the GIL */
+    if (PyThreadState_GET() != NULL) {
+        /* Flush sys.stdout and sys.stderr */
+        flush_std_files();
+    }
+
 #ifdef MS_WINDOWS
     len = strlen(msg);
 
index 7e0267a..6d1c6d0 100644 (file)
@@ -3,6 +3,14 @@
 
 #include "Python.h"
 
+#define GET_TSTATE() \
+    ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
+#define SET_TSTATE(value) \
+    _Py_atomic_store_relaxed(&_PyThreadState_Current, (Py_uintptr_t)(value))
+#define GET_INTERP_STATE() \
+    (GET_TSTATE()->interp)
+
+
 /* --------------------------------------------------------------------------
 CAUTION
 
@@ -48,7 +56,7 @@ static PyInterpreterState *interp_head = NULL;
 
 /* Assuming the current thread holds the GIL, this is the
    PyThreadState for the current thread. */
-_Py_atomic_address _PyThreadState_Current = {NULL};
+_Py_atomic_address _PyThreadState_Current = {0};
 PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
 
 #ifdef WITH_THREAD
@@ -254,7 +262,7 @@ PyObject*
 PyState_FindModule(struct PyModuleDef* module)
 {
     Py_ssize_t index = module->m_base.m_index;
-    PyInterpreterState *state = PyThreadState_GET()->interp;
+    PyInterpreterState *state = GET_INTERP_STATE();
     PyObject *res;
     if (module->m_slots) {
         return NULL;
@@ -278,7 +286,7 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def)
                         "PyState_AddModule called on module with slots");
         return -1;
     }
-    state = PyThreadState_GET()->interp;
+    state = GET_INTERP_STATE();
     if (!def)
         return -1;
     if (!state->modules_by_index) {
@@ -298,7 +306,7 @@ int
 PyState_AddModule(PyObject* module, struct PyModuleDef* def)
 {
     Py_ssize_t index;
-    PyInterpreterState *state = PyThreadState_GET()->interp;
+    PyInterpreterState *state = GET_INTERP_STATE();
     if (!def) {
         Py_FatalError("PyState_AddModule: Module Definition is NULL");
         return -1;
@@ -325,7 +333,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
                         "PyState_RemoveModule called on module with slots");
         return -1;
     }
-    state = PyThreadState_GET()->interp;
+    state = GET_INTERP_STATE();
     if (index == 0) {
         Py_FatalError("PyState_RemoveModule: Module index invalid.");
         return -1;
@@ -345,7 +353,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
 void
 _PyState_ClearModules(void)
 {
-    PyInterpreterState *state = PyThreadState_GET()->interp;
+    PyInterpreterState *state = GET_INTERP_STATE();
     if (state->modules_by_index) {
         Py_ssize_t i;
         for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) {
@@ -423,7 +431,7 @@ tstate_delete_common(PyThreadState *tstate)
 void
 PyThreadState_Delete(PyThreadState *tstate)
 {
-    if (tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
+    if (tstate == GET_TSTATE())
         Py_FatalError("PyThreadState_Delete: tstate is still current");
 #ifdef WITH_THREAD
     if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
@@ -437,12 +445,11 @@ PyThreadState_Delete(PyThreadState *tstate)
 void
 PyThreadState_DeleteCurrent()
 {
-    PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
-        &_PyThreadState_Current);
+    PyThreadState *tstate = GET_TSTATE();
     if (tstate == NULL)
         Py_FatalError(
             "PyThreadState_DeleteCurrent: no current tstate");
-    _Py_atomic_store_relaxed(&_PyThreadState_Current, NULL);
+    SET_TSTATE(NULL);
     if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
         PyThread_delete_key_value(autoTLSkey);
     tstate_delete_common(tstate);
@@ -489,10 +496,16 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
 
 
 PyThreadState *
+_PyThreadState_UncheckedGet(void)
+{
+    return GET_TSTATE();
+}
+
+
+PyThreadState *
 PyThreadState_Get(void)
 {
-    PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
-        &_PyThreadState_Current);
+    PyThreadState *tstate = GET_TSTATE();
     if (tstate == NULL)
         Py_FatalError("PyThreadState_Get: no current thread");
 
@@ -503,10 +516,9 @@ PyThreadState_Get(void)
 PyThreadState *
 PyThreadState_Swap(PyThreadState *newts)
 {
-    PyThreadState *oldts = (PyThreadState*)_Py_atomic_load_relaxed(
-        &_PyThreadState_Current);
+    PyThreadState *oldts = GET_TSTATE();
 
-    _Py_atomic_store_relaxed(&_PyThreadState_Current, newts);
+    SET_TSTATE(newts);
     /* It should not be possible for more than one thread state
        to be used for a thread.  Check this the best we can in debug
        builds.
@@ -535,8 +547,7 @@ PyThreadState_Swap(PyThreadState *newts)
 PyObject *
 PyThreadState_GetDict(void)
 {
-    PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
-        &_PyThreadState_Current);
+    PyThreadState *tstate = GET_TSTATE();
     if (tstate == NULL)
         return NULL;
 
@@ -560,8 +571,7 @@ PyThreadState_GetDict(void)
 
 int
 PyThreadState_SetAsyncExc(long id, PyObject *exc) {
-    PyThreadState *tstate = PyThreadState_GET();
-    PyInterpreterState *interp = tstate->interp;
+    PyInterpreterState *interp = GET_INTERP_STATE();
     PyThreadState *p;
 
     /* Although the GIL is held, a few C API functions can be called
@@ -682,7 +692,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
 {
     /* Must be the tstate for this thread */
     assert(PyGILState_GetThisThreadState()==tstate);
-    return tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current);
+    return tstate == GET_TSTATE();
 }
 
 /* Internal initialization/finalization functions called by
@@ -774,9 +784,7 @@ PyGILState_GetThisThreadState(void)
 int
 PyGILState_Check(void)
 {
-    /* can't use PyThreadState_Get() since it will assert that it has the GIL */
-    PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
-        &_PyThreadState_Current);
+    PyThreadState *tstate = GET_TSTATE();
     return tstate && (tstate == PyGILState_GetThisThreadState());
 }
 
index ebedd12..7fbf06e 100644 (file)
@@ -766,8 +766,11 @@ print_exception(PyObject *f, PyObject *value)
         /* only print colon if the str() of the
            object is not the empty string
         */
-        if (s == NULL)
+        if (s == NULL) {
+            PyErr_Clear();
             err = -1;
+            PyFile_WriteString(": <exception str() failed>", f);
+        }
         else if (!PyUnicode_Check(s) ||
             PyUnicode_GetLength(s) != 0)
             err = PyFile_WriteString(": ", f);
@@ -776,6 +779,9 @@ print_exception(PyObject *f, PyObject *value)
         Py_XDECREF(s);
     }
     /* try to write a newline in any case */
+    if (err < 0) {
+        PyErr_Clear();
+    }
     err += PyFile_WriteString("\n", f);
     Py_XDECREF(tb);
     Py_DECREF(value);
@@ -1419,7 +1425,7 @@ PyOS_CheckStack(void)
 
 #endif /* USE_STACKCHECK */
 
-/* Deprecated C API functions still provided for binary compatiblity */
+/* Deprecated C API functions still provided for binary compatibility */
 
 #undef PyParser_SimpleParseFile
 PyAPI_FUNC(node *)
index 772bfef..07dacfe 100644 (file)
@@ -6,6 +6,9 @@
 #  ifdef HAVE_SYS_STAT_H
 #    include <sys/stat.h>
 #  endif
+#  ifdef HAVE_LINUX_RANDOM_H
+#    include <linux/random.h>
+#  endif
 #  ifdef HAVE_GETRANDOM
 #    include <sys/random.h>
 #  elif defined(HAVE_GETRANDOM_SYSCALL)
@@ -72,6 +75,8 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
     return 0;
 }
 
+/* Issue #25003: Don't use getentropy() on Solaris (available since
+ * Solaris 11.3), it is blocking whereas os.urandom() should not block. */
 #elif defined(HAVE_GETENTROPY) && !defined(sun)
 #define PY_GETENTROPY 1
 
@@ -111,8 +116,6 @@ py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal)
 
 #else
 
-/* Issue #25003: Don' use getentropy() on Solaris (available since
- * Solaris 11.3), it is blocking whereas os.urandom() should not block. */
 #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
 #define PY_GETRANDOM 1
 
@@ -122,25 +125,36 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
     /* Is getrandom() supported by the running kernel?
      * Need Linux kernel 3.17 or newer, or Solaris 11.3 or newer */
     static int getrandom_works = 1;
-    /* Use non-blocking /dev/urandom device. On Linux at boot, the getrandom()
-     * syscall blocks until /dev/urandom is initialized with enough entropy. */
-    const int flags = 0;
+
+    /* getrandom() on Linux will block if called before the kernel has
+     * initialized the urandom entropy pool. This will cause Python
+     * to hang on startup if called very early in the boot process -
+     * see https://bugs.python.org/issue26839. To avoid this, use the
+     * GRND_NONBLOCK flag. */
+    const int flags = GRND_NONBLOCK;
     int n;
 
     if (!getrandom_works)
         return 0;
 
     while (0 < size) {
-        errno = 0;
+#ifdef sun
+        /* Issue #26735: On Solaris, getrandom() is limited to returning up
+           to 1024 bytes */
+        n = Py_MIN(size, 1024);
+#else
+        n = size;
+#endif
 
+        errno = 0;
 #ifdef HAVE_GETRANDOM
         if (raise) {
             Py_BEGIN_ALLOW_THREADS
-            n = getrandom(buffer, size, flags);
+            n = getrandom(buffer, n, flags);
             Py_END_ALLOW_THREADS
         }
         else {
-            n = getrandom(buffer, size, flags);
+            n = getrandom(buffer, n, flags);
         }
 #else
         /* On Linux, use the syscall() function because the GNU libc doesn't
@@ -148,11 +162,11 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
          * https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
         if (raise) {
             Py_BEGIN_ALLOW_THREADS
-            n = syscall(SYS_getrandom, buffer, size, flags);
+            n = syscall(SYS_getrandom, buffer, n, flags);
             Py_END_ALLOW_THREADS
         }
         else {
-            n = syscall(SYS_getrandom, buffer, size, flags);
+            n = syscall(SYS_getrandom, buffer, n, flags);
         }
 #endif
 
@@ -161,6 +175,17 @@ py_getrandom(void *buffer, Py_ssize_t size, int raise)
                 getrandom_works = 0;
                 return 0;
             }
+            if (errno == EAGAIN) {
+                /* If we failed with EAGAIN, the entropy pool was
+                 * uninitialized. In this case, we return failure to fall
+                 * back to reading from /dev/urandom.
+                 *
+                 * Note: In this case the data read will not be random so
+                 * should not be used for cryptographic purposes. Retaining
+                 * the existing semantics for practical purposes. */
+                getrandom_works = 0;
+                return 0;
+            }
 
             if (errno == EINTR) {
                 if (PyErr_CheckSignals()) {
index 64910d8..1591a20 100644 (file)
@@ -368,15 +368,20 @@ error_at_directive(PySTEntryObject *ste, PyObject *name)
     Py_ssize_t i;
     PyObject *data;
     assert(ste->ste_directives);
-    for (i = 0; ; i++) {
+    for (i = 0; i < PyList_GET_SIZE(ste->ste_directives); i++) {
         data = PyList_GET_ITEM(ste->ste_directives, i);
         assert(PyTuple_CheckExact(data));
-        if (PyTuple_GET_ITEM(data, 0) == name)
-            break;
+        assert(PyUnicode_CheckExact(PyTuple_GET_ITEM(data, 0)));
+        if (PyUnicode_Compare(PyTuple_GET_ITEM(data, 0), name) == 0) {
+            PyErr_SyntaxLocationObject(ste->ste_table->st_filename,
+                                       PyLong_AsLong(PyTuple_GET_ITEM(data, 1)),
+                                       PyLong_AsLong(PyTuple_GET_ITEM(data, 2)));
+
+            return 0;
+        }   
     }
-    PyErr_SyntaxLocationObject(ste->ste_table->st_filename,
-                               PyLong_AsLong(PyTuple_GET_ITEM(data, 1)),
-                               PyLong_AsLong(PyTuple_GET_ITEM(data, 2)));
+    PyErr_SetString(PyExc_RuntimeError,
+                    "BUG: internal directive bookkeeping broken");
     return 0;
 }
 
@@ -849,7 +854,7 @@ analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free,
 
     /* Copy the bound and global dictionaries.
 
-       These dictionary are used by all blocks enclosed by the
+       These dictionaries are used by all blocks enclosed by the
        current block.  The analyze_block() call modifies these
        dictionaries.
 
@@ -1115,14 +1120,17 @@ symtable_new_tmpname(struct symtable *st)
 static int
 symtable_record_directive(struct symtable *st, identifier name, stmt_ty s)
 {
-    PyObject *data;
+    PyObject *data, *mangled;
     int res;
     if (!st->st_cur->ste_directives) {
         st->st_cur->ste_directives = PyList_New(0);
         if (!st->st_cur->ste_directives)
             return 0;
     }
-    data = Py_BuildValue("(Oii)", name, s->lineno, s->col_offset);
+    mangled = _Py_Mangle(st->st_private, name);
+    if (!mangled)
+        return 0;
+    data = Py_BuildValue("(Nii)", mangled, s->lineno, s->col_offset);
     if (!data)
         return 0;
     res = PyList_Append(st->st_cur->ste_directives, data);
index 334f5d0..8d7e05a 100644 (file)
@@ -1397,7 +1397,7 @@ error:
     Py_XDECREF(name);
     Py_XDECREF(value);
     /* No return value, therefore clear error state if possible */
-    if (_Py_atomic_load_relaxed(&_PyThreadState_Current))
+    if (_PyThreadState_UncheckedGet())
         PyErr_Clear();
 }
 
index 84452cd..b29b1b6 100644 (file)
@@ -231,7 +231,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
 }
 
 /*
- * Return the thread Id instead of an handle. The Id is said to uniquely identify the
+ * Return the thread Id instead of a handle. The Id is said to uniquely identify the
  * thread in the system
  */
 long
diff --git a/README b/README
index 84aaef9..9a07bfd 100644 (file)
--- a/README
+++ b/README
@@ -1,8 +1,8 @@
-This is Python version 3.5.1
+This is Python version 3.5.2
 ============================
 
 Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
-2012, 2013, 2014, 2015 Python Software Foundation.  All rights reserved.
+2012, 2013, 2014, 2015, 2016 Python Software Foundation.  All rights reserved.
 
 Python 3.x is a new version of the language, which is incompatible with the
 2.x line of releases.  The language is mostly the same, but many details,
@@ -58,7 +58,7 @@ PGO takes advantage of recent versions of the GCC or Clang compilers.
 If ran, the "profile-opt" rule will do several steps.
 
 First, the entire Python directory is cleaned of temporary files that
-may resulted in a previous compilation.
+may have resulted in a previous compilation.
 
 Then, an instrumented version of the interpreter is built, using suitable
 compiler flags for each flavour. Note that this is just an intermediary
@@ -71,7 +71,7 @@ profile the interpreter execution. Note also that any output, both stdout
 and stderr, that may appear at this step is supressed.
 
 Finally, the last step is to rebuild the interpreter, using the information
-collected in the previous one. The end result will be a the Python binary
+collected in the previous one. The end result will be a Python binary
 that is optimized and suitable for distribution or production installation.
 
 
@@ -203,7 +203,7 @@ Copyright and License Information
 ---------------------------------
 
 Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
-2012, 2013, 2014, 2015 Python Software Foundation.  All rights reserved.
+2012, 2013, 2014, 2015, 2016 Python Software Foundation.  All rights reserved.
 
 Copyright (c) 2000 BeOpen.com.  All rights reserved.
 
index 3ce3587..1d851da 100755 (executable)
@@ -176,6 +176,13 @@ def rstrip_lines(s):
     text.pop()
     return output()
 
+def format_escape(s):
+    # double up curly-braces, this string will be used
+    # as part of a format_map() template later
+    s = s.replace('{', '{{')
+    s = s.replace('}', '}}')
+    return s
+
 def linear_format(s, **kwargs):
     """
     Perform str.format-like substitution, except:
@@ -199,7 +206,7 @@ def linear_format(s, **kwargs):
             add('\n')
             continue
 
-        name, curl, trailing = trailing.partition('}')
+        name, curly, trailing = trailing.partition('}')
         if not curly or name not in kwargs:
             add(line)
             add('\n')
@@ -996,7 +1003,7 @@ class CLanguage(Language):
         count_min = sys.maxsize
         count_max = -1
 
-        add("switch (PyTuple_GET_SIZE(args)) {{\n")
+        add("switch (PyTuple_GET_SIZE(args)) {\n")
         for subset in permute_optional_groups(left, required, right):
             count = len(subset)
             count_min = min(count_min, count)
@@ -1012,7 +1019,6 @@ class CLanguage(Language):
             d = {}
             d['count'] = count
             d['name'] = f.name
-            d['groups'] = sorted(group_ids)
             d['format_units'] = "".join(p.converter.format_unit for p in subset)
 
             parse_arguments = []
@@ -1039,8 +1045,8 @@ class CLanguage(Language):
         s = '        PyErr_SetString(PyExc_TypeError, "{} requires {} to {} arguments");\n'
         add(s.format(f.full_name, count_min, count_max))
         add('        goto exit;\n')
-        add("}}")
-        template_dict['option_group_parsing'] = output()
+        add("}")
+        template_dict['option_group_parsing'] = format_escape(output())
 
     def render_function(self, clinic, f):
         if not f:
@@ -1135,7 +1141,7 @@ class CLanguage(Language):
         f.return_converter.render(f, data)
         template_dict['impl_return_type'] = f.return_converter.type
 
-        template_dict['declarations'] = "\n".join(data.declarations)
+        template_dict['declarations'] = format_escape("\n".join(data.declarations))
         template_dict['initializers'] = "\n\n".join(data.initializers)
         template_dict['modifications'] = '\n\n'.join(data.modifications)
         template_dict['keywords'] = '"' + '", "'.join(data.keywords) + '"'
@@ -1143,8 +1149,8 @@ class CLanguage(Language):
         template_dict['parse_arguments'] = ', '.join(data.parse_arguments)
         template_dict['impl_parameters'] = ", ".join(data.impl_parameters)
         template_dict['impl_arguments'] = ", ".join(data.impl_arguments)
-        template_dict['return_conversion'] = "".join(data.return_conversion).rstrip()
-        template_dict['cleanup'] = "".join(data.cleanup)
+        template_dict['return_conversion'] = format_escape("".join(data.return_conversion).rstrip())
+        template_dict['cleanup'] = format_escape("".join(data.cleanup))
         template_dict['return_value'] = data.return_value
 
         # used by unpack tuple code generator
@@ -2439,12 +2445,7 @@ class CConverter(metaclass=CConverterAutoRegister):
             declaration.append('\nPy_ssize_clean_t ')
             declaration.append(self.length_name())
             declaration.append(';')
-        s = "".join(declaration)
-        # double up curly-braces, this string will be used
-        # as part of a format_map() template later
-        s = s.replace("{", "{{")
-        s = s.replace("}", "}}")
-        return s
+        return "".join(declaration)
 
     def initialize(self):
         """
index cd21000..ac0640c 100644 (file)
@@ -3,7 +3,6 @@
 # Licensed to the PSF under a contributor agreement.
 #
 
-import builtins
 import clinic
 from clinic import DSLParser
 import collections
@@ -747,15 +746,6 @@ Not at column 0!
     Nested docstring here, goeth.
 """.strip(), function.docstring)
 
-    def test_parser_regression_special_character_in_parameter_column_of_docstring_first_line(self):
-        function = self.parse_function("""
-module os
-os.stat
-    path: str
-This/used to break Clinic!
-""")
-        self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring)
-
     def test_directive(self):
         c = FakeClinic()
         parser = DSLParser(c)
index 32e804c..fa43faf 100644 (file)
@@ -17,12 +17,12 @@ def makemakefile(outfp, makevars, files, target):
             base = os.path.basename(file)
             dest = base[:-2] + '.o'
             outfp.write("%s: %s\n" % (dest, file))
-            outfp.write("\t$(CC) $(CFLAGS) $(CPPFLAGS) -c %s\n" % file)
+            outfp.write("\t$(CC) $(PY_CFLAGS) $(PY_CPPFLAGS) -c %s\n" % file)
             files[i] = dest
             deps.append(dest)
 
     outfp.write("\n%s: %s\n" % (target, ' '.join(deps)))
-    outfp.write("\t$(LINKCC) $(LDFLAGS) $(LINKFORSHARED) %s -o %s $(LDLAST)\n" %
+    outfp.write("\t$(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) %s -o %s $(LDLAST)\n" %
                 (' '.join(files), target))
 
     outfp.write("\nclean:\n\t-rm -f *.o %s\n" % target)
index 32341e7..75f1ccb 100755 (executable)
@@ -56,20 +56,33 @@ if sys.version_info[0] >= 3:
     long = int
 
 # Look up the gdb.Type for some standard types:
-_type_char_ptr = gdb.lookup_type('char').pointer() # char*
-_type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer() # unsigned char*
-_type_void_ptr = gdb.lookup_type('void').pointer() # void*
-_type_unsigned_short_ptr = gdb.lookup_type('unsigned short').pointer()
-_type_unsigned_int_ptr = gdb.lookup_type('unsigned int').pointer()
+# Those need to be refreshed as types (pointer sizes) may change when
+# gdb loads different executables
 
-# value computed later, see PyUnicodeObjectPtr.proxy()
-_is_pep393 = None
+def _type_char_ptr():
+    return gdb.lookup_type('char').pointer()  # char*
 
-SIZEOF_VOID_P = _type_void_ptr.sizeof
 
+def _type_unsigned_char_ptr():
+    return gdb.lookup_type('unsigned char').pointer()  # unsigned char*
+
+
+def _type_unsigned_short_ptr():
+    return gdb.lookup_type('unsigned short').pointer()
+
+
+def _type_unsigned_int_ptr():
+    return gdb.lookup_type('unsigned int').pointer()
 
-Py_TPFLAGS_HEAPTYPE = (1 << 9)
 
+def _sizeof_void_p():
+    return gdb.lookup_type('void').pointer().sizeof
+
+
+# value computed later, see PyUnicodeObjectPtr.proxy()
+_is_pep393 = None
+
+Py_TPFLAGS_HEAPTYPE = (1 << 9)
 Py_TPFLAGS_LONG_SUBCLASS     = (1 << 24)
 Py_TPFLAGS_LIST_SUBCLASS     = (1 << 25)
 Py_TPFLAGS_TUPLE_SUBCLASS    = (1 << 26)
@@ -460,8 +473,8 @@ def _PyObject_VAR_SIZE(typeobj, nitems):
 
     return ( ( typeobj.field('tp_basicsize') +
                nitems * typeobj.field('tp_itemsize') +
-               (SIZEOF_VOID_P - 1)
-             ) & ~(SIZEOF_VOID_P - 1)
+               (_sizeof_void_p() - 1)
+             ) & ~(_sizeof_void_p() - 1)
            ).cast(_PyObject_VAR_SIZE._type_size_t)
 _PyObject_VAR_SIZE._type_size_t = None
 
@@ -485,9 +498,9 @@ class HeapTypeObjectPtr(PyObjectPtr):
                     size = _PyObject_VAR_SIZE(typeobj, tsize)
                     dictoffset += size
                     assert dictoffset > 0
-                    assert dictoffset % SIZEOF_VOID_P == 0
+                    assert dictoffset % _sizeof_void_p() == 0
 
-                dictptr = self._gdbval.cast(_type_char_ptr) + dictoffset
+                dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset
                 PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer()
                 dictptr = dictptr.cast(PyObjectPtrPtr)
                 return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
@@ -1004,7 +1017,7 @@ class PyBytesObjectPtr(PyObjectPtr):
     def __str__(self):
         field_ob_size = self.field('ob_size')
         field_ob_sval = self.field('ob_sval')
-        char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr)
+        char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr())
         return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)])
 
     def proxyval(self, visited):
@@ -1135,11 +1148,11 @@ class PyUnicodeObjectPtr(PyObjectPtr):
                     field_str = self.field('data')['any']
                 repr_kind = int(state['kind'])
                 if repr_kind == 1:
-                    field_str = field_str.cast(_type_unsigned_char_ptr)
+                    field_str = field_str.cast(_type_unsigned_char_ptr())
                 elif repr_kind == 2:
-                    field_str = field_str.cast(_type_unsigned_short_ptr)
+                    field_str = field_str.cast(_type_unsigned_short_ptr())
                 elif repr_kind == 4:
-                    field_str = field_str.cast(_type_unsigned_int_ptr)
+                    field_str = field_str.cast(_type_unsigned_int_ptr())
         else:
             # Python 3.2 and earlier
             field_length = long(self.field('length'))
index fc7cb9f..2eae07a 100644 (file)
@@ -168,7 +168,7 @@ if not "%SKIPBUILD%" EQU "1" (
             "%BUILD%python.exe" %PGO%\r
         )\r
         \r
-        @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGUpdate -t %TARGET% %CERTOPTS%\r
+        @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGUpdate -t Build %CERTOPTS%\r
     )\r
     @if errorlevel 1 exit /B\r
     @echo off\r
index 8ff4c3b..4d9c97a 100644 (file)
@@ -66,7 +66,7 @@
 
         <Checkbox Name="Include_launcher" X="185" Y="251" Width="100" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_launcherLabel)</Checkbox>
         <Checkbox Name="CustomInstallLauncherAllUsers" X="285" Y="251" Width="-11" Height="24" TabStop="yes" FontId="3">#(loc.InstallLauncherAllUsersLabel)</Checkbox>
-        <Text X="205" Y="276" Width="-11" Height="24" TabStop="no" FontId="5">#(loc.Include_launcherHelpLabel)</Text>
+        <Text Name="Include_launcherHelp" X="205" Y="276" Width="-11" Height="24" TabStop="no" FontId="5"></Text>
 
         <Button Name="Custom1BackButton" X="185" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CustomBackButton)</Button>
         <Button Name="CustomNextButton" X="-101" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CustomNextButton)</Button>
index 1f3e77c..697066b 100644 (file)
@@ -76,7 +76,9 @@ Select Customize to review current options.</String>
   <String Id="Include_testLabel">Python &amp;test suite</String>
   <String Id="Include_testHelpLabel">Installs the standard library test suite.</String>
   <String Id="Include_launcherLabel">py &amp;launcher</String>
-  <String Id="Include_launcherHelpLabel">Installs the global 'py' launcher to make it easier to start Python.</String>
+  <String Id="Include_launcherHelp">Installs the global 'py' launcher to make it easier to start Python.</String>
+  <String Id="Include_launcherRemove">Use Programs and Features to remove the 'py' launcher.</String>
+  <String Id="Include_launcherUpgrade">Upgrades the global 'py' launcher from the previous version.</String>
   
   <String Id="AssociateFilesLabel">Associate &amp;files with Python (requires the py launcher)</String>
   <String Id="ShortcutsLabel">Create shortcuts for installed applications</String>
index 9d94e3b..1462d7b 100644 (file)
@@ -94,6 +94,7 @@ enum CONTROL_ID {
     ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX,
     ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX,
     ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX,
+    ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL,
     ID_CUSTOM_COMPILE_ALL_CHECKBOX,
     ID_CUSTOM_BROWSE_BUTTON,
     ID_CUSTOM_BROWSE_BUTTON_LABEL,
@@ -158,6 +159,7 @@ static THEME_ASSIGN_CONTROL_ID CONTROL_ID_NAMES[] = {
     { ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, L"AssociateFiles" },
     { ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX, L"InstallAllUsers" },
     { ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, L"CustomInstallLauncherAllUsers" },
+    { ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL, L"Include_launcherHelp" },
     { ID_CUSTOM_COMPILE_ALL_CHECKBOX, L"CompileAll" },
     { ID_CUSTOM_BROWSE_BUTTON, L"CustomBrowseButton" },
     { ID_CUSTOM_BROWSE_BUTTON_LABEL, L"CustomBrowseButtonLabel" },
@@ -454,6 +456,20 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
 
         ThemeSendControlMessage(_theme, ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, BM_SETCHECK,
             installLauncherAllUsers ? BST_CHECKED : BST_UNCHECKED, 0);
+
+        LOC_STRING *pLocString = nullptr;
+        LPCWSTR locKey = L"#(loc.Include_launcherHelp)";
+        LONGLONG detectedLauncher;
+
+        if (SUCCEEDED(BalGetNumericVariable(L"DetectedLauncher", &detectedLauncher)) && detectedLauncher) {
+            locKey = L"#(loc.Include_launcherRemove)";
+        } else if (SUCCEEDED(BalGetNumericVariable(L"DetectedOldLauncher", &detectedLauncher)) && detectedLauncher) {
+            locKey = L"#(loc.Include_launcherUpgrade)";
+        }
+
+        if (SUCCEEDED(LocGetString(_wixLoc, locKey, &pLocString)) && pLocString) {
+            ThemeSetTextControl(_theme, ID_CUSTOM_INCLUDE_LAUNCHER_HELP_LABEL, pLocString->wzText);
+        }
     }
 
     void Custom2Page_Show() {
@@ -641,6 +657,29 @@ public: // IBootstrapperApplication
         return nResult;
     }
 
+    virtual STDMETHODIMP_(int) OnDetectRelatedMsiPackage(
+        __in_z LPCWSTR wzPackageId,
+        __in_z LPCWSTR /*wzProductCode*/,
+        __in BOOL fPerMachine,
+        __in DWORD64 /*dw64Version*/,
+        __in BOOTSTRAPPER_RELATED_OPERATION operation
+    ) {
+        if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == operation && 
+            (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_AllUsers", -1) ||
+             CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_JustForMe", -1))) {
+            auto hr = LoadAssociateFilesStateFromKey(_engine, fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER);
+            if (hr == S_OK) {
+                _engine->SetVariableNumeric(L"AssociateFiles", 1);
+            } else if (FAILED(hr)) {
+                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr);
+            }
+
+            _engine->SetVariableNumeric(L"Include_launcher", 1);
+            _engine->SetVariableNumeric(L"DetectedOldLauncher", 1);
+            _engine->SetVariableNumeric(L"InstallLauncherAllUsers", fPerMachine ? 1 : 0);
+        }
+        return CheckCanceled() ? IDCANCEL : IDNOACTION;
+    }
 
     virtual STDMETHODIMP_(int) OnDetectRelatedBundle(
         __in LPCWSTR wzBundleId,
@@ -656,24 +695,8 @@ public: // IBootstrapperApplication
         if (BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE == operation) {
             _downgradingOtherVersion = TRUE;
         } else if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == operation) {
-            _upgradingOldVersion = TRUE;
-
-            // Assume we don't want the launcher or file associations, and if
-            // they have already been installed then loading the state will
-            // reactivate these settings.
-            _engine->SetVariableNumeric(L"Include_launcher", 0);
-            _engine->SetVariableNumeric(L"AssociateFiles", 0);
-            auto hr = LoadLauncherStateFromKey(_engine, HKEY_CURRENT_USER);
-            if (hr == S_FALSE) {
-                hr = LoadLauncherStateFromKey(_engine, HKEY_LOCAL_MACHINE);
-            }
-            if (FAILED(hr)) {
-                BalLog(
-                    BOOTSTRAPPER_LOG_LEVEL_ERROR,
-                    "Failed to load launcher state: error code 0x%08X",
-                    hr
-                );
-            }
+            BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Detected previous version - planning upgrade");
+            _upgrading = TRUE;
 
             LoadOptionalFeatureStates(_engine);
         } else if (BOOTSTRAPPER_RELATED_OPERATION_NONE == operation) {
@@ -699,9 +722,42 @@ public: // IBootstrapperApplication
 
     virtual STDMETHODIMP_(void) OnDetectPackageComplete(
         __in LPCWSTR wzPackageId,
-        __in HRESULT /*hrStatus*/,
+        __in HRESULT hrStatus,
         __in BOOTSTRAPPER_PACKAGE_STATE state
-    ) { }
+    ) {
+        if (FAILED(hrStatus)) {
+            return;
+        }
+
+        BOOL detectedLauncher = FALSE;
+        HKEY hkey = HKEY_LOCAL_MACHINE;
+        if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_AllUsers", -1)) {
+            if (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state || BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == state) {
+                detectedLauncher = TRUE;
+                _engine->SetVariableNumeric(L"InstallLauncherAllUsers", 1);
+            }
+        } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, L"launcher_JustForMe", -1)) {
+            if (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state || BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == state) {
+                detectedLauncher = TRUE;
+                _engine->SetVariableNumeric(L"InstallLauncherAllUsers", 0);
+            }
+        }
+
+        if (detectedLauncher) {
+            /* When we detect the current version of the launcher. */
+            _engine->SetVariableNumeric(L"Include_launcher", 1);
+            _engine->SetVariableNumeric(L"DetectedLauncher", 1);
+            _engine->SetVariableString(L"Include_launcherState", L"disable");
+            _engine->SetVariableString(L"InstallLauncherAllUsersState", L"disable");
+
+            auto hr = LoadAssociateFilesStateFromKey(_engine, hkey);
+            if (hr == S_OK) {
+                _engine->SetVariableNumeric(L"AssociateFiles", 1);
+            } else if (FAILED(hr)) {
+                BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr);
+            }
+        }
+    }
 
 
     virtual STDMETHODIMP_(void) OnDetectComplete(__in HRESULT hrStatus) {
@@ -716,32 +772,7 @@ public: // IBootstrapperApplication
 
         if (SUCCEEDED(hrStatus)) {
             // Ensure the default path has been set
-            LONGLONG installAll;
-            LPWSTR targetDir = nullptr;
-            LPWSTR defaultTargetDir = nullptr;
-
-            hrStatus = BalGetStringVariable(L"TargetDir", &targetDir);
-            if (FAILED(hrStatus) || !targetDir || !targetDir[0]) {
-                ReleaseStr(targetDir);
-                targetDir = nullptr;
-
-                if (FAILED(BalGetNumericVariable(L"InstallAllUsers", &installAll))) {
-                    installAll = 0;
-                }
-
-                hrStatus = BalGetStringVariable(
-                    installAll ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir",
-                    &defaultTargetDir
-                );
-
-                if (SUCCEEDED(hrStatus) && defaultTargetDir) {
-                    if (defaultTargetDir[0] && SUCCEEDED(BalFormatString(defaultTargetDir, &targetDir))) {
-                        hrStatus = _engine->SetVariableString(L"TargetDir", targetDir);
-                        ReleaseStr(targetDir);
-                    }
-                    ReleaseStr(defaultTargetDir);
-                }
-            }
+            hrStatus = EnsureTargetDir();
         }
 
         SetState(PYBA_STATE_DETECTED, hrStatus);
@@ -1396,9 +1427,14 @@ private:
 
         hr = LoadBootstrapperBAFunctions();
         BalExitOnFailure(hr, "Failed to load bootstrapper functions.");
+
         hr = UpdateUIStrings(_command.action);
         BalExitOnFailure(hr, "Failed to load UI strings.");
 
+        if (_command.action == BOOTSTRAPPER_ACTION_MODIFY) {
+            LoadOptionalFeatureStates(_engine);
+        }
+
         GetBundleFileVersion();
         // don't fail if we couldn't get the version info; best-effort only
     LExit:
@@ -1906,27 +1942,6 @@ private:
         for (DWORD i = 0; i < _theme->cControls; ++i) {
             THEME_CONTROL* pControl = _theme->rgControls + i;
             LPWSTR text = nullptr;
-            LPWSTR name = nullptr;
-            LOC_STRING *locText = nullptr;
-
-            // If a command link has a note, then add it.
-            if ((pControl->dwStyle & BS_TYPEMASK) == BS_COMMANDLINK ||
-                (pControl->dwStyle & BS_TYPEMASK) == BS_DEFCOMMANDLINK) {
-                hr = StrAllocFormatted(&name, L"#(loc.%lsNote)", pControl->sczName);
-                if (SUCCEEDED(hr)) {
-                    hr = LocGetString(_wixLoc, name, &locText);
-                    ReleaseStr(name);
-                    if (SUCCEEDED(hr) && locText && locText->wzText && locText->wzText[0]) {
-                        hr = BalFormatString(locText->wzText, &text);
-                        if (SUCCEEDED(hr) && text && text[0]) {
-                            ThemeSendControlMessage(_theme, pControl->wId, BCM_SETNOTE, 0, (LPARAM)text);
-                            ReleaseStr(text);
-                            text = nullptr;
-                        }
-                    }
-                }
-                hr = S_OK;
-            }
 
             if (!pControl->wPageId && pControl->sczText && *pControl->sczText) {
                 HRESULT hrFormat;
@@ -2048,6 +2063,7 @@ private:
 
         return;
     }
+
     HRESULT UpdateUIStrings(__in BOOTSTRAPPER_ACTION action) {
         HRESULT hr = S_OK;
         LPCWSTR likeInstalling = nullptr;
@@ -2270,6 +2286,30 @@ private:
                     StrFree(controlState);
                 }
                 StrFree(controlName);
+                controlName = nullptr;
+
+
+                // If a command link has a note, then add it.
+                if ((pControl->dwStyle & BS_TYPEMASK) == BS_COMMANDLINK ||
+                    (pControl->dwStyle & BS_TYPEMASK) == BS_DEFCOMMANDLINK) {
+                    hr = StrAllocFormatted(&controlName, L"#(loc.%lsNote)", pControl->sczName);
+                    if (SUCCEEDED(hr)) {
+                        LOC_STRING *locText = nullptr;
+                        hr = LocGetString(_wixLoc, controlName, &locText);
+                        if (SUCCEEDED(hr) && locText && locText->wzText && locText->wzText[0]) {
+                            LPWSTR text = nullptr;
+                            hr = BalFormatString(locText->wzText, &text);
+                            if (SUCCEEDED(hr) && text && text[0]) {
+                                ThemeSendControlMessage(_theme, pControl->wId, BCM_SETNOTE, 0, (LPARAM)text);
+                                ReleaseStr(text);
+                                text = nullptr;
+                            }
+                        }
+                        ReleaseStr(controlName);
+                        controlName = nullptr;
+                    }
+                    hr = S_OK;
+                }
             }
 
             ThemeControlEnable(_theme, pControl->wId, enableControl);
@@ -2515,9 +2555,8 @@ private:
                 if (_installPage == PAGE_LOADING) {
                     switch (_command.action) {
                     case BOOTSTRAPPER_ACTION_INSTALL:
-                        if (_upgradingOldVersion) {
+                        if (_upgrading) {
                             _installPage = PAGE_UPGRADE;
-                            _upgrading = TRUE;
                         } else if (SUCCEEDED(BalGetNumericVariable(L"SimpleInstall", &simple)) && simple) {
                             _installPage = PAGE_SIMPLE_INSTALL;
                         } else {
@@ -2560,11 +2599,9 @@ private:
         static BAL_CONDITION WILL_ELEVATE_CONDITION = {
             L"not WixBundleElevated and ("
                 /*Elevate when installing for all users*/
-                L"InstallAllUsers or"
+                L"InstallAllUsers or "
                 /*Elevate when installing the launcher for all users and it was not detected*/
-                L"(InstallLauncherAllUsers and Include_launcher and not DetectedLauncher) or"
-                /*Elevate when the launcher was installed for all users and it is being removed*/
-                L"(DetectedLauncher and DetectedLauncherAllUsers and not Include_launcher)"
+                L"(Include_launcher and InstallLauncherAllUsers and not DetectedLauncher)"
             L")",
             L""
         };
@@ -2867,19 +2904,16 @@ private:
         return HRESULT_FROM_WIN32(res);
     }
 
-    static HRESULT LoadLauncherStateFromKey(
+    static HRESULT LoadAssociateFilesStateFromKey(
         __in IBootstrapperEngine* pEngine,
         __in HKEY hkHive
     ) {
         const LPCWSTR subkey = L"Software\\Python\\PyLauncher";
         HKEY hKey;
         LRESULT res;
+        HRESULT hr;
 
-        if (IsTargetPlatformx64(pEngine)) {
-            res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
-        } else {
-            res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
-        }
+        res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
 
         if (res == ERROR_FILE_NOT_FOUND) {
             return S_FALSE;
@@ -2888,26 +2922,17 @@ private:
             return HRESULT_FROM_WIN32(res);
         }
 
-        res = RegQueryValueExW(hKey, nullptr, nullptr, nullptr, nullptr, nullptr);
-        if (res == ERROR_FILE_NOT_FOUND) {
-            pEngine->SetVariableNumeric(L"Include_launcher", 0);
-        } else if (res == ERROR_SUCCESS) {
-            pEngine->SetVariableNumeric(L"Include_launcher", 1);
-            pEngine->SetVariableNumeric(L"DetectedLauncher", 1);
-            pEngine->SetVariableNumeric(L"InstallLauncherAllUsers", (hkHive == HKEY_LOCAL_MACHINE) ? 1 : 0);
-            pEngine->SetVariableNumeric(L"DetectedLauncherAllUsers", (hkHive == HKEY_LOCAL_MACHINE) ? 1 : 0);
-            pEngine->SetVariableString(L"InstallLauncherAllUsersState", L"disable");
-        }
-
         res = RegQueryValueExW(hKey, L"AssociateFiles", nullptr, nullptr, nullptr, nullptr);
         if (res == ERROR_FILE_NOT_FOUND) {
-            pEngine->SetVariableNumeric(L"AssociateFiles", 0);
+            hr = S_FALSE;
         } else if (res == ERROR_SUCCESS) {
-            pEngine->SetVariableNumeric(L"AssociateFiles", 1);
+            hr = S_OK;
+        } else {
+            hr = HRESULT_FROM_WIN32(res);
         }
 
         RegCloseKey(hKey);
-        return S_OK;
+        return hr;
     }
 
     static void LoadOptionalFeatureStates(__in IBootstrapperEngine* pEngine) {
@@ -2918,7 +2943,11 @@ private:
         HKEY hkHive;
 
         // The launcher installation is separate from the Python install, so we
-        // check its state later. This also checks the file association option.
+        // check its state later. For now, assume we don't want the launcher or
+        // file associations, and if they have already been installed then
+        // loading the state will reactivate these settings.
+        pEngine->SetVariableNumeric(L"Include_launcher", 0);
+        pEngine->SetVariableNumeric(L"AssociateFiles", 0);
 
         // Get the registry key from the bundle, to save having to duplicate it
         // in multiple places.
@@ -3089,7 +3118,6 @@ public:
         _hrFinal = hrHostInitialization;
 
         _downgradingOtherVersion = FALSE;
-        _upgradingOldVersion = FALSE;
         _restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE;
         _restartRequired = FALSE;
         _allowRestart = FALSE;
@@ -3113,8 +3141,6 @@ public:
 
         _hBAFModule = nullptr;
         _baFunction = nullptr;
-
-        EnsureTargetDir();
     }
 
 
@@ -3174,7 +3200,6 @@ private:
     DWORD _calculatedExecuteProgress;
 
     BOOL _downgradingOtherVersion;
-    BOOL _upgradingOldVersion;
     BOOTSTRAPPER_APPLY_RESTART _restartResult;
     BOOL _restartRequired;
     BOOL _allowRestart;
index 978efc0..38307e0 100644 (file)
@@ -51,7 +51,7 @@
     -->
     <Variable Name="DefaultCustomTargetDir" Value="" bal:Overridable="yes" />
 
-    <Variable Name="InstallAllUsersState" Value="enabled" />
+    <Variable Name="InstallAllUsersState" Value="enabled" bal:Overridable="yes" />
     <?if "$(var.PyTestExt)"="" ?>
     <Variable Name="InstallLauncherAllUsersState" Value="enabled" bal:Overridable="yes" />
     <?else ?>
@@ -72,6 +72,7 @@
     <Variable Name="Include_pip" Value="1" bal:Overridable="yes" />
     <?if "$(var.PyTestExt)"="" ?>
     <Variable Name="Include_launcher" Value="1" bal:Overridable="yes" />
+    <Variable Name="Include_launcherState" Value="enabled" bal:Overridable="yes" />
     <?else ?>
     <Variable Name="Include_launcher" Value="0" />
     <Variable Name="Include_launcherState" Value="disable" />
@@ -81,6 +82,7 @@
     
     <Variable Name="LauncherOnly" Value="0" bal:Overridable="yes" />
     <Variable Name="DetectedLauncher" Value="0" />
+    <Variable Name="DetectedOldLauncher" Value="0" />
     
     <Variable Name="AssociateFiles" Value="1" bal:Overridable="yes" />
     <Variable Name="Shortcuts" Value="1" bal:Overridable="yes" />
index 4b03fd2..4444f45 100644 (file)
@@ -11,7 +11,7 @@
                         EnableFeatureSelection="yes"
                         Permanent="yes"
                         Visible="yes"
-                        InstallCondition="(InstallAllUsers or InstallLauncherAllUsers) and Include_launcher" />
+                        InstallCondition="(InstallAllUsers or InstallLauncherAllUsers) and Include_launcher and not DetectedLauncher" />
 
             <MsiPackage Id="launcher_JustForMe"
                         SourceFile="launcher.msi"
@@ -21,7 +21,7 @@
                         EnableFeatureSelection="yes"
                         Permanent="yes"
                         Visible="yes"
-                        InstallCondition="not (InstallAllUsers or InstallLauncherAllUsers) and Include_launcher" />
+                        InstallCondition="not (InstallAllUsers or InstallLauncherAllUsers) and Include_launcher and not DetectedLauncher" />
         </PackageGroup>
     </Fragment>
 </Wix>
\ No newline at end of file
index b907872..4efad65 100644 (file)
@@ -21,8 +21,8 @@
             <UpgradeVersion Property="UPGRADE" Minimum="$(var.UpgradeMinimumVersion)" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" />
         </Upgrade>
         
+        <?ifdef CoreUpgradeCode ?>
         <?if $(var.UpgradeCode)!=$(var.CoreUpgradeCode) ?>
-        <?ifndef SkipMissingCore ?>
         <Upgrade Id="$(var.CoreUpgradeCode)">
             <UpgradeVersion Property="MISSING_CORE" Minimum="$(var.Version)" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="yes" OnlyDetect="yes" />
         </Upgrade>
     </Fragment>
     
     <Fragment>
+    <?ifdef InstallDirectoryGuidSeed ?>
         <Directory Id="TARGETDIR" Name="SourceDir">
             <Directory Id="InstallDirectory" ComponentGuidGenerationSeed="$(var.InstallDirectoryGuidSeed)" />
         </Directory>
+    <?endif ?>
     </Fragment>
     
     <!-- Top-level directories -->
index a0f1d57..67fb025 100644 (file)
@@ -5,7 +5,8 @@
         <SchemaVersion>2.0</SchemaVersion>
         <OutputName>launcher</OutputName>
         <OutputType>Package</OutputType>
-        <DefineConstants>SkipMissingCore=1;$(DefineConstants)</DefineConstants>
+        <DefineConstants>UpgradeCode=1B68A0EC-4DD3-5134-840E-73854B0863F1;$(DefineConstants)</DefineConstants>
+        <IgnoreCommonWxlTemplates>true</IgnoreCommonWxlTemplates>
     </PropertyGroup>
     <Import Project="..\msi.props" />
     <ItemGroup>
index 718b666..80e838a 100644 (file)
@@ -5,7 +5,6 @@
         <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
         
         <Property Id="Suppress_TARGETDIR_Check" Value="1" />
-        <PropertyRef Id="UpgradeTable" />
         <PropertyRef Id="ARPPRODUCTICON" />
 
         <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
             <Custom Before="SetLauncherInstallDirectoryLM" Action="SetLauncherInstallDirectoryCU">NOT Installed AND NOT ALLUSERS=1</Custom>
             <Custom Before="CostFinalize" Action="SetLauncherInstallDirectoryLM">NOT Installed AND ALLUSERS=1</Custom>
 
-            <RemoveExistingProducts After="InstallInitialize">UPGRADE or REMOVE_OLD_LAUNCHER</RemoveExistingProducts>
+            <RemoveExistingProducts After="InstallValidate">UPGRADE or REMOVE_350_LAUNCHER</RemoveExistingProducts>
         </InstallExecuteSequence>
         
-        <!-- Python 3.5.0 shipped with an incorrect UpgradeCode -->
+        <!-- Python 3.5.0 shipped with a different UpgradeCode -->
         <Upgrade Id="A71530B9-E89D-53DB-9C2D-C6D7551876D8">
-            <UpgradeVersion Maximum="$(var.Version)" Property="REMOVE_OLD_LAUNCHER" />
+            <UpgradeVersion Minimum="0.0.0.0" Property="REMOVE_350_LAUNCHER" />
         </Upgrade>
+        <!-- Python 3.6.0a1 shipped with a different UpgradeCode -->
+        <Upgrade Id="394750C0-7880-5A8F-999F-933965FBCFB4">
+            <UpgradeVersion Maximum="$(var.Version)" Property="REMOVE_360A1_LAUNCHER" />
+            <UpgradeVersion Minimum="$(var.Version)" Property="BLOCK_360A1_LAUNCHER" />
+        </Upgrade>
+        <Condition Message="!(loc.NoDowngrade)">Installed OR NOT BLOCK_360A1_LAUNCHER</Condition>
     </Product>
 </Wix>
index d961fff..e4c1aaa 100644 (file)
@@ -1,7 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
-    <String Id="Descriptor">Launcher</String>
-    <String Id="ShortDescriptor">launcher</String>
+    <String Id="LCID">1033</String>
+    <String Id="Culture">en-us</String>
+    <String Id="ProductName">Python Launcher</String>
+    <String Id="Title">Python Launcher</String>
+    <String Id="Description">Python Launcher</String>
+    <String Id="Manufacturer">Python Software Foundation</String>
+    <String Id="NoDowngrade">A newer version of the Python launcher is already installed.</String>
+    <String Id="NoTargetDir">The TARGETDIR variable must be provided when invoking this installer.</String>
     <String Id="PythonFileDescription">Python File</String>
     <String Id="PythonNoConFileDescription">Python File (no console)</String>
     <String Id="PythonCompiledFileDescription">Compiled Python File</String>
index 96fdad2..753ba0f 100644 (file)
@@ -23,6 +23,7 @@ EXCLUDE_FROM_LIBRARY = {
     'site-packages',
     'tkinter',
     'turtledemo',
+    'venv',
 }
 
 EXCLUDE_FILE_FROM_LIBRARY = {
@@ -88,7 +89,7 @@ EMBED_LAYOUT = [
     ('/', 'PCBuild/$arch', 'python*.exe', is_not_debug),
     ('/', 'PCBuild/$arch', '*.pyd', is_not_debug),
     ('/', 'PCBuild/$arch', '*.dll', is_not_debug),
-    ('python35.zip', 'Lib', '**/*', include_in_lib),
+    ('python{0.major}{0.minor}.zip'.format(sys.version_info), 'Lib', '**/*', include_in_lib),
 ]
 
 if os.getenv('DOC_FILENAME'):
index bbb8aeb..9ae6d99 100644 (file)
@@ -39,7 +39,7 @@
     
     <ItemGroup>
         <Compile Include="$(MSBuildThisFileDirectory)common.wxs" />
-        <WxlTemplate Include="$(MSBuildThisFileDirectory)\*.wxl_template" />
+        <WxlTemplate Include="$(MSBuildThisFileDirectory)\*.wxl_template" Condition="$(IgnoreCommonWxlTemplates) != 'true'" />
         <WixExtension Include="WixUtilExtension">
             <HintPath>WixUtilExtension</HintPath>
             <Name>WixUtilExtension</Name>
             <Uri>lib2to3/pickles</Uri>
         </_Uuid>
     </ItemGroup>
-    <Target Name="_GenerateGuids" AfterTargets="PrepareForBuild">
+    <Target Name="_GenerateGuids" AfterTargets="PrepareForBuild" Condition="$(TargetName) != 'launcher'">
         <PropertyGroup>
             <_Uuids>@(_Uuid->'("%(Identity)", "$(MajorVersionNumber).$(MinorVersionNumber)/%(Uri)")',',')</_Uuids>
             <_GenerateCommand>import uuid; print('\n'.join('{}={}'.format(i, uuid.uuid5(uuid.UUID('c8d9733e-a70c-43ff-ab0c-e26456f11083'), '$(ReleaseUri.Replace(`{arch}`, `$(ArchName)`))' + j)) for i,j in [$(_Uuids.Replace(`"`,`'`))]))</_GenerateCommand>
index a40d9c4..86be35b 100644 (file)
@@ -25,7 +25,7 @@
     </Target>
 
     <Target Name="_TransformWxlTemplates" AfterTargets="PrepareForBuild" Inputs="@(WxlTemplate);$(PySourcePath)include\patchlevel.h" Outputs="$(IntermediateOutputPath)%(Filename).wxl">
-        <PropertyGroup>
+        <PropertyGroup Condition="'@(WxlTemplate)' != ''">
             <_Content>$([System.IO.File]::ReadAllText(%(WxlTemplate.FullPath)).Replace(`{{ShortVersion}}`, `$(MajorVersionNumber).$(MinorVersionNumber)$(PyTestExt)`).Replace(`{{LongVersion}}`, `$(PythonVersion)$(PyTestExt)`).Replace(`{{Bitness}}`, `$(Bitness)`))</_Content>
             <_ExistingContent Condition="Exists('$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl')">$([System.IO.File]::ReadAllText($(IntermediateOutputPath)%(WxlTemplate.Filename).wxl))</_ExistingContent>
         </PropertyGroup>
@@ -35,7 +35,7 @@
                           Overwrite="true"
                           Condition="$(_Content) != $(_ExistingContent)" />
         
-        <ItemGroup>
+        <ItemGroup Condition="'@(WxlTemplate)' != ''">
             <EmbeddedResource Include="$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl" />
             <FileWrites Include="$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl" />
         </ItemGroup>
index c828577..285030e 100644 (file)
@@ -393,12 +393,21 @@ class Unparser:
 
     def _Dict(self, t):
         self.write("{")
-        def write_pair(pair):
-            (k, v) = pair
+        def write_key_value_pair(k, v):
             self.dispatch(k)
             self.write(": ")
             self.dispatch(v)
-        interleave(lambda: self.write(", "), write_pair, zip(t.keys, t.values))
+
+        def write_item(item):
+            k, v = item
+            if k is None:
+                # for dictionary unpacking operator in dicts {**{'y': 2}}
+                # see PEP 448 for details
+                self.write("**")
+                self.dispatch(v)
+            else:
+                write_key_value_pair(k, v)
+        interleave(lambda: self.write(", "), write_item, zip(t.keys, t.values))
         self.write("}")
 
     def _Tuple(self, t):
index 5f3795e..6c16b1c 100755 (executable)
@@ -32,7 +32,7 @@ except ImportError:
                          "no sophisticated Python source file search will be done.", file=sys.stderr)
 
 
-decl_re = re.compile(rb'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)')
+decl_re = re.compile(rb'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)')
 blank_re = re.compile(rb'^[ \t\f]*(?:[#\r\n]|$)')
 
 def get_declaration(line):
index 7d25fb9..1f0e6f4 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
 
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index 398f121..c892a99 100755 (executable)
--- a/configure
+++ b/configure
@@ -673,6 +673,7 @@ LLVM_PROF_FILE
 LLVM_PROF_MERGER
 PGO_PROF_USE_FLAG
 PGO_PROF_GEN_FLAG
+LTOFLAGS
 ABIFLAGS
 LN
 MKDIR_P
@@ -750,6 +751,7 @@ build_os
 build_vendor
 build_cpu
 build
+cross_compiling
 HAS_HG
 HGBRANCH
 HGTAG
@@ -801,11 +803,13 @@ with_universal_archs
 with_framework_name
 enable_framework
 with_gcc
+with_icc
 with_cxx_main
 with_suffix
 enable_shared
 enable_profiling
 with_pydebug
+with_lto
 with_hash_algorithm
 with_address_sanitizer
 with_libs
@@ -1480,11 +1484,14 @@ Optional Packages:
                           specify an alternate name of the framework built
                           with --enable-framework
   --without-gcc           never use gcc
+  --with-icc              build with icc
   --with-cxx-main=<compiler>
                           compile main() and link python executable with C++
                           compiler
   --with-suffix=.exe      set executable suffix
   --with-pydebug          build with Py_DEBUG defined
+  --with-lto              Enable Link Time Optimization in PGO builds.
+                          Disabled by default.
   --with-hash-algorithm=[fnv|siphash24]
                           select hash algorithm
   --with-address-sanitizer
@@ -2869,6 +2876,7 @@ fi
 ac_config_headers="$ac_config_headers pyconfig.h"
 
 
+
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
   if test -f "$ac_dir/install-sh"; then
@@ -3489,7 +3497,7 @@ fi
 #
 # SGI compilers allow the specification of the both the ABI and the
 # ISA on the command line.  Depending on the values of these switches,
-# different and often incompatable code will be generated.
+# different and often incompatible code will be generated.
 #
 # The SGI_ABI variable can be used to modify the CC and LDFLAGS and
 # thus supply support for various ABI/ISA combinations.  The MACHDEP
@@ -3549,6 +3557,29 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $without_gcc" >&5
 $as_echo "$without_gcc" >&6; }
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-icc" >&5
+$as_echo_n "checking for --with-icc... " >&6; }
+
+# Check whether --with-icc was given.
+if test "${with_icc+set}" = set; then :
+  withval=$with_icc;
+       case $withval in
+       no)     CC=${CC:-cc}
+               with_icc=no;;
+       yes)    CC=icc
+               CXX=icpc
+               with_icc=yes;;
+       *)      CC=$withval
+               with_icc=$withval;;
+       esac
+else
+
+       with_icc=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_icc" >&5
+$as_echo "$with_icc" >&6; }
+
 # If the user switches compilers, we can't believe the cache
 if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
 then
@@ -4941,6 +4972,104 @@ else
   CXX="$ac_cv_path_CXX"
 fi
  ;;
+        icc|*/icc)         if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}icpc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}icpc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $CXX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_CXX="$CXX" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in notfound
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+CXX=$ac_cv_path_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CXX"; then
+  ac_pt_CXX=$CXX
+  # Extract the first word of "icpc", so it can be a program name with args.
+set dummy icpc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_CXX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in notfound
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_CXX="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_CXX=$ac_cv_path_ac_pt_CXX
+if test -n "$ac_pt_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5
+$as_echo "$ac_pt_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_CXX" = x; then
+    CXX="icpc"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_pt_CXX
+  fi
+else
+  CXX="$ac_cv_path_CXX"
+fi
+ ;;
         esac
        if test "$CXX" = "notfound"
        then
@@ -6437,7 +6566,55 @@ $as_echo "no" >&6; }
 fi
 
 
+# Enable LTO flags
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-lto" >&5
+$as_echo_n "checking for --with-lto... " >&6; }
+
+# Check whether --with-lto was given.
+if test "${with_lto+set}" = set; then :
+  withval=$with_lto;
+if test "$withval" != no
+then
+  Py_LTO='true'
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };
+else
+  Py_LTO='false'
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };
+fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+if test "$Py_LTO" = 'true' ; then
+  case $CC in
+    *clang*)
+      # Any changes made here should be reflected in the GCC+Darwin case below
+      LTOFLAGS="-flto"
+      ;;
+    *gcc*)
+      case $ac_sys_system in
+        Darwin*)
+          LTOFLAGS="-flto"
+          ;;
+        *)
+          LTOFLAGS="-flto -fuse-linker-plugin -ffat-lto-objects -flto-partition=none"
+          ;;
+      esac
+      ;;
+  esac
+fi
+
 # Enable PGO flags.
+
+
+
+
+
+
 # Extract the first word of "llvm-profdata", so it can be a program name with args.
 set dummy llvm-profdata; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -6509,6 +6686,12 @@ case $CC in
         ;;
     esac
     ;;
+  *icc*)
+    PGO_PROF_GEN_FLAG="-prof-gen"
+    PGO_PROF_USE_FLAG="-prof-use"
+    LLVM_PROF_MERGER="true"
+    LLVM_PROF_FILE=""
+    ;;
 esac
 
 # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be
@@ -6655,6 +6838,13 @@ $as_echo "$ac_cv_no_strict_aliasing" >&6; }
       BASECFLAGS="$BASECFLAGS -fno-strict-aliasing"
     fi
 
+    # ICC doesn't recognize the option, but only emits a warning
+    ## XXX does it emit an unused result warning and can it be disabled?
+    case "$CC" in
+    *icc*)
+    ac_cv_disable_unused_result_warning=no
+    ;;
+    *)
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can turn off $CC unused result warning" >&5
 $as_echo_n "checking if we can turn off $CC unused result warning... " >&6; }
      ac_save_cc="$CC"
@@ -6692,6 +6882,8 @@ fi
      CC="$ac_save_cc"
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_unused_result_warning" >&5
 $as_echo "$ac_cv_disable_unused_result_warning" >&6; }
+    ;;
+    esac
 
     if test $ac_cv_disable_unused_result_warning = yes
     then
@@ -6819,15 +7011,24 @@ fi
 
      CFLAGS="$save_CFLAGS"
      CC="$ac_save_cc"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_unreachable_code_warning" >&5
-$as_echo "$ac_cv_enable_unreachable_code_warning" >&6; }
 
     # Don't enable unreachable code warning in debug mode, since it usually
     # results in non-standard code paths.
-    if test $ac_cv_enable_unreachable_code_warning = yes && test "$Py_DEBUG" != "true"
+    # Issue #24324: Unfortunately, the unreachable code warning does not work
+    # correctly on gcc and has been silently removed from the compiler.
+    # It is supported on clang but on OS X systems gcc may be an alias
+    # for clang.  Try to determine if the compiler is not really gcc and,
+    # if so, only then enable the warning.
+    if test $ac_cv_enable_unreachable_code_warning = yes && \
+        test "$Py_DEBUG" != "true" && \
+        test -z "`$CC --version 2>/dev/null | grep 'Free Software Foundation'`"
     then
       BASECFLAGS="$BASECFLAGS -Wunreachable-code"
+    else
+      ac_cv_enable_unreachable_code_warning=no
     fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_unreachable_code_warning" >&5
+$as_echo "$ac_cv_enable_unreachable_code_warning" >&6; }
 
     # if using gcc on alpha, use -mieee to get (near) full IEEE 754
     # support.  Without this, treatment of subnormals doesn't follow
@@ -6981,6 +7182,13 @@ $as_echo "$MACOSX_DEPLOYMENT_TARGET" >&6; }
     ;;
 esac
 
+# ICC needs -fp-model strict or floats behave badly
+case "$CC" in
+*icc*)
+    CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict"
+    ;;
+esac
+
 if test "$Py_DEBUG" = 'true'; then
   :
 else
@@ -7361,7 +7569,7 @@ sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
 sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \
 sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
 libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
-bluetooth/bluetooth.h linux/tipc.h spawn.h util.h alloca.h endian.h \
+bluetooth/bluetooth.h linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \
 sys/endian.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -12709,19 +12917,9 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-$as_echo "#define HAVE_ST_BLOCKS 1" >>confdefs.h
-
-else
-  case " $LIBOBJS " in
-  *" fileblocks.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS fileblocks.$ac_objext"
- ;;
-esac
-
 fi
 
 
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for time.h that defines altzone" >&5
 $as_echo_n "checking for time.h that defines altzone... " >&6; }
 if ${ac_cv_header_time_altzone+:} false; then :
@@ -14779,6 +14977,50 @@ $as_echo "#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1" >>confdefs.h
 fi
 
 
+# also in 4.0, but not in editline
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_resize_terminal in -lreadline" >&5
+$as_echo_n "checking for rl_resize_terminal in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_rl_resize_terminal+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $READLINE_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char rl_resize_terminal ();
+int
+main ()
+{
+return rl_resize_terminal ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_readline_rl_resize_terminal=yes
+else
+  ac_cv_lib_readline_rl_resize_terminal=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_resize_terminal" >&5
+$as_echo "$ac_cv_lib_readline_rl_resize_terminal" >&6; }
+if test "x$ac_cv_lib_readline_rl_resize_terminal" = xyes; then :
+
+$as_echo "#define HAVE_RL_RESIZE_TERMINAL 1" >>confdefs.h
+
+fi
+
+
 # check for readline 4.2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_matches in -lreadline" >&5
 $as_echo_n "checking for rl_completion_matches in -lreadline... " >&6; }
@@ -16082,13 +16324,15 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 
+    #include <unistd.h>
     #include <sys/syscall.h>
+    #include <linux/random.h>
 
     int main() {
         char buffer[1];
         const size_t buflen = sizeof(buffer);
-        const int flags = 0;
-        /* ignore the result, Python checks for ENOSYS at runtime */
+        const int flags = GRND_NONBLOCK;
+        /* ignore the result, Python checks for ENOSYS and EAGAIN at runtime */
         (void)syscall(SYS_getrandom, buffer, buflen, flags);
         return 0;
     }
index 694293e..1c07c05 100644 (file)
@@ -49,6 +49,7 @@ fi
 AC_CONFIG_SRCDIR([Include/object.h])
 AC_CONFIG_HEADER(pyconfig.h)
 
+AC_SUBST(cross_compiling)
 AC_CANONICAL_HOST
 AC_SUBST(build)
 AC_SUBST(host)
@@ -86,7 +87,7 @@ dnl can cause trouble.
 dnl Last slash shouldn't be stripped if prefix=/
 if test "$prefix" != "/"; then
     prefix=`echo "$prefix" | sed -e 's/\/$//g'`
-fi    
+fi
 
 dnl This is for stuff that absolutely must end up in pyconfig.h.
 dnl Please use pyport.h instead, if possible.
@@ -178,7 +179,7 @@ AC_ARG_ENABLE(universalsdk,
                fi
                ;;
        esac
-       
+
 ],[
        UNIVERSALSDK=
        enable_universalsdk=
@@ -240,7 +241,7 @@ AC_ARG_ENABLE(framework,
               AS_HELP_STRING([--enable-framework@<:@=INSTALLDIR@:>@], [Build (MacOSX|Darwin) framework]),
 [
        case $enableval in
-       yes) 
+       yes)
                enableval=/Library/Frameworks
        esac
        case $enableval in
@@ -297,7 +298,7 @@ AC_ARG_ENABLE(framework,
                        FRAMEWORKINSTALLAPPSPREFIX="${MDIR}/Applications"
 
                        if test "${prefix}" = "NONE"; then
-                               # User hasn't specified the 
+                               # User hasn't specified the
                                # --prefix option, but wants to install
                                # the framework in a non-default location,
                                # ensure that the compatibility links get
@@ -442,7 +443,7 @@ case $ac_sys_system/$ac_sys_release in
   # Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish.
   # In addition, Stefan Krah confirms that issue #1244610 exists through
   # OpenBSD 4.6, but is fixed in 4.7.
-  OpenBSD/2.* | OpenBSD/3.* | OpenBSD/4.@<:@0123456@:>@) 
+  OpenBSD/2.* | OpenBSD/3.* | OpenBSD/4.@<:@0123456@:>@)
     define_xopen_source=no
     # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is
     # also defined. This can be overridden by defining _BSD_SOURCE
@@ -480,12 +481,12 @@ case $ac_sys_system/$ac_sys_release in
   # with _XOPEN_SOURCE and __BSD_VISIBLE does not re-enable them.
   FreeBSD/4.*)
     define_xopen_source=no;;
-  # On MacOS X 10.2, a bug in ncurses.h means that it craps out if 
+  # On MacOS X 10.2, a bug in ncurses.h means that it craps out if
   # _XOPEN_EXTENDED_SOURCE is defined. Apparently, this is fixed in 10.3, which
   # identifies itself as Darwin/7.*
   # On Mac OS X 10.4, defining _POSIX_C_SOURCE or _XOPEN_SOURCE
   # disables platform specific features beyond repair.
-  # On Mac OS X 10.3, defining _POSIX_C_SOURCE or _XOPEN_SOURCE 
+  # On Mac OS X 10.3, defining _POSIX_C_SOURCE or _XOPEN_SOURCE
   # has no effect, don't bother defining them
   Darwin/@<:@6789@:>@.*)
     define_xopen_source=no;;
@@ -541,7 +542,7 @@ fi
 #
 # SGI compilers allow the specification of the both the ABI and the
 # ISA on the command line.  Depending on the values of these switches,
-# different and often incompatable code will be generated.
+# different and often incompatible code will be generated.
 #
 # The SGI_ABI variable can be used to modify the CC and LDFLAGS and
 # thus supply support for various ABI/ISA combinations.  The MACHDEP
@@ -593,6 +594,22 @@ AC_ARG_WITH(gcc,
        esac])
 AC_MSG_RESULT($without_gcc)
 
+AC_MSG_CHECKING(for --with-icc)
+AC_ARG_WITH(icc,
+            AS_HELP_STRING([--with-icc], [build with icc]),
+[
+       case $withval in
+       no)     CC=${CC:-cc}
+               with_icc=no;;
+       yes)    CC=icc
+               CXX=icpc
+               with_icc=yes;;
+       *)      CC=$withval
+               with_icc=$withval;;
+       esac], [
+       with_icc=no])
+AC_MSG_RESULT($with_icc)
+
 # If the user switches compilers, we can't believe the cache
 if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
 then
@@ -674,7 +691,7 @@ AC_ARG_WITH(cxx_main,
             AS_HELP_STRING([--with-cxx-main=<compiler>],
                            [compile main() and link python executable with C++ compiler]),
 [
-       
+
        case $withval in
        no)     with_cxx_main=no
                MAINCC='$(CC)';;
@@ -699,6 +716,7 @@ then
         gcc)    AC_PATH_TOOL(CXX, [g++], [g++], [notfound]) ;;
         cc)     AC_PATH_TOOL(CXX, [c++], [c++], [notfound]) ;;
         clang|*/clang)     AC_PATH_TOOL(CXX, [clang++], [clang++], [notfound]) ;;
+        icc|*/icc)         AC_PATH_TOOL(CXX, [icpc], [icpc], [notfound]) ;;
         esac
        if test "$CXX" = "notfound"
        then
@@ -853,7 +871,7 @@ if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then
   if test x$PLATFORM_TRIPLET != x$MULTIARCH; then
     AC_MSG_ERROR([internal configure error for the platform triplet, please file a bug report])
   fi
-fi 
+fi
 PLATDIR=plat-$MACHDEP
 AC_SUBST(PLATDIR)
 AC_SUBST(PLATFORM_TRIPLET)
@@ -942,7 +960,7 @@ AC_MSG_RESULT($LIBRARY)
 # systems without shared libraries, LDLIBRARY is the same as LIBRARY
 # (defined in the Makefiles). On Cygwin LDLIBRARY is the import library,
 # DLLLIBRARY is the shared (i.e., DLL) library.
-# 
+#
 # RUNSHARED is used to run shared python without installed libraries
 #
 # INSTSONAME is the name of the shared library that will be use to install
@@ -970,7 +988,7 @@ LDVERSION="$VERSION"
 # If CXX is set, and if it is needed to link a main function that was
 # compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable:
 # python might then depend on the C++ runtime
-# This is altered for AIX in order to build the export list before 
+# This is altered for AIX in order to build the export list before
 # linking.
 AC_SUBST(LINKCC)
 AC_MSG_CHECKING(LINKCC)
@@ -1024,7 +1042,7 @@ AC_ARG_ENABLE(shared,
               AS_HELP_STRING([--enable-shared], [disable/enable building shared python library]))
 
 if test -z "$enable_shared"
-then 
+then
   case $ac_sys_system in
   CYGWIN*)
     enable_shared="yes";;
@@ -1069,7 +1087,7 @@ then
   BLDLIBRARY=''
 else
   BLDLIBRARY='$(LDLIBRARY)'
-fi  
+fi
 
 # Other platforms follow
 if test $enable_shared = "yes"; then
@@ -1204,20 +1222,53 @@ ABIFLAGS=""
 
 # Check for --with-pydebug
 AC_MSG_CHECKING(for --with-pydebug)
-AC_ARG_WITH(pydebug, 
+AC_ARG_WITH(pydebug,
             AS_HELP_STRING([--with-pydebug], [build with Py_DEBUG defined]),
 [
 if test "$withval" != no
-then 
-  AC_DEFINE(Py_DEBUG, 1, 
-  [Define if you want to build an interpreter with many run-time checks.]) 
-  AC_MSG_RESULT(yes); 
+then
+  AC_DEFINE(Py_DEBUG, 1,
+  [Define if you want to build an interpreter with many run-time checks.])
+  AC_MSG_RESULT(yes);
   Py_DEBUG='true'
   ABIFLAGS="${ABIFLAGS}d"
 else AC_MSG_RESULT(no); Py_DEBUG='false'
 fi],
 [AC_MSG_RESULT(no)])
 
+# Enable LTO flags
+AC_SUBST(LTOFLAGS)
+AC_MSG_CHECKING(for --with-lto)
+AC_ARG_WITH(lto, AS_HELP_STRING([--with-lto], [Enable Link Time Optimization in PGO builds. Disabled by default.]),
+[
+if test "$withval" != no
+then
+  Py_LTO='true'
+  AC_MSG_RESULT(yes);
+else
+  Py_LTO='false'
+  AC_MSG_RESULT(no);
+fi],
+[AC_MSG_RESULT(no)])
+if test "$Py_LTO" = 'true' ; then
+  case $CC in
+    *clang*)
+      # Any changes made here should be reflected in the GCC+Darwin case below
+      LTOFLAGS="-flto"
+      ;;
+    *gcc*)
+      case $ac_sys_system in
+        Darwin*)
+          LTOFLAGS="-flto"
+          ;;
+        *)
+          LTOFLAGS="-flto -fuse-linker-plugin -ffat-lto-objects -flto-partition=none"
+          ;;
+      esac
+      ;;
+  esac
+fi
+
 # Enable PGO flags.
 AC_SUBST(PGO_PROF_GEN_FLAG)
 AC_SUBST(PGO_PROF_USE_FLAG)
@@ -1259,6 +1310,12 @@ case $CC in
         ;;
     esac
     ;;
+  *icc*)
+    PGO_PROF_GEN_FLAG="-prof-gen"
+    PGO_PROF_USE_FLAG="-prof-use"
+    LLVM_PROF_MERGER="true"
+    LLVM_PROF_FILE=""
+    ;;
 esac
 
 # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be
@@ -1370,6 +1427,13 @@ yes)
       BASECFLAGS="$BASECFLAGS -fno-strict-aliasing"
     fi
 
+    # ICC doesn't recognize the option, but only emits a warning
+    ## XXX does it emit an unused result warning and can it be disabled?
+    case "$CC" in
+    *icc*)
+    ac_cv_disable_unused_result_warning=no
+    ;;
+    *)
     AC_MSG_CHECKING(if we can turn off $CC unused result warning)
      ac_save_cc="$CC"
      CC="$CC -Wunused-result -Werror"
@@ -1386,6 +1450,8 @@ yes)
      CFLAGS="$save_CFLAGS"
      CC="$ac_save_cc"
     AC_MSG_RESULT($ac_cv_disable_unused_result_warning)
+    ;;
+    esac
 
     if test $ac_cv_disable_unused_result_warning = yes
     then
@@ -1451,14 +1517,23 @@ yes)
         ]))
      CFLAGS="$save_CFLAGS"
      CC="$ac_save_cc"
-    AC_MSG_RESULT($ac_cv_enable_unreachable_code_warning)
 
     # Don't enable unreachable code warning in debug mode, since it usually
     # results in non-standard code paths.
-    if test $ac_cv_enable_unreachable_code_warning = yes && test "$Py_DEBUG" != "true"
+    # Issue #24324: Unfortunately, the unreachable code warning does not work
+    # correctly on gcc and has been silently removed from the compiler.
+    # It is supported on clang but on OS X systems gcc may be an alias
+    # for clang.  Try to determine if the compiler is not really gcc and,
+    # if so, only then enable the warning.
+    if test $ac_cv_enable_unreachable_code_warning = yes && \
+        test "$Py_DEBUG" != "true" && \
+        test -z "`$CC --version 2>/dev/null | grep 'Free Software Foundation'`"
     then
       BASECFLAGS="$BASECFLAGS -Wunreachable-code"
+    else
+      ac_cv_enable_unreachable_code_warning=no
     fi
+    AC_MSG_RESULT($ac_cv_enable_unreachable_code_warning)
 
     # if using gcc on alpha, use -mieee to get (near) full IEEE 754
     # support.  Without this, treatment of subnormals doesn't follow
@@ -1608,6 +1683,13 @@ yes)
     ;;
 esac
 
+# ICC needs -fp-model strict or floats behave badly
+case "$CC" in
+*icc*)
+    CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict"
+    ;;
+esac
+
 if test "$Py_DEBUG" = 'true'; then
   :
 else
@@ -1648,7 +1730,7 @@ int main(){
 AC_MSG_RESULT($ac_cv_pthread_is_default)
 
 
-if test $ac_cv_pthread_is_default = yes 
+if test $ac_cv_pthread_is_default = yes
 then
   ac_cv_kpthread=no
 else
@@ -1747,14 +1829,14 @@ ac_save_cxx="$CXX"
 
 if test "$ac_cv_kpthread" = "yes"
 then
-  CXX="$CXX -Kpthread"  
+  CXX="$CXX -Kpthread"
   ac_cv_cxx_thread=yes
 elif test "$ac_cv_kthread" = "yes"
 then
   CXX="$CXX -Kthread"
   ac_cv_cxx_thread=yes
 elif test "$ac_cv_pthread" = "yes"
-then 
+then
   CXX="$CXX -pthread"
   ac_cv_cxx_thread=yes
 fi
@@ -1799,7 +1881,7 @@ sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
 sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \
 sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
 libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
-bluetooth/bluetooth.h linux/tipc.h spawn.h util.h alloca.h endian.h \
+bluetooth/bluetooth.h linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \
 sys/endian.h)
 AC_HEADER_DIRENT
 AC_HEADER_MAJOR
@@ -1902,11 +1984,11 @@ if test "$use_lfs" = "yes"; then
 # These may affect some typedefs
 case $ac_sys_system/$ac_sys_release in
 AIX*)
-    AC_DEFINE(_LARGE_FILES, 1, 
+    AC_DEFINE(_LARGE_FILES, 1,
     [This must be defined on AIX systems to enable large file support.])
     ;;
 esac
-AC_DEFINE(_LARGEFILE_SOURCE, 1, 
+AC_DEFINE(_LARGEFILE_SOURCE, 1,
 [This must be defined on some systems to enable large file support.])
 AC_DEFINE(_FILE_OFFSET_BITS, 64,
 [This must be set to 64 on some systems to enable large file support.])
@@ -1970,7 +2052,7 @@ AC_CHECK_SIZEOF(pid_t, 4)
 AC_MSG_CHECKING(for long long support)
 have_long_long=no
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[long long x; x = (long long)0;]])],[
-  AC_DEFINE(HAVE_LONG_LONG, 1, [Define this if you have the type long long.]) 
+  AC_DEFINE(HAVE_LONG_LONG, 1, [Define this if you have the type long long.])
   have_long_long=yes
 ],[])
 AC_MSG_RESULT($have_long_long)
@@ -1981,7 +2063,7 @@ fi
 AC_MSG_CHECKING(for long double support)
 have_long_double=no
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[long double x; x = (long double)0;]])],[
-  AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define this if you have the type long double.]) 
+  AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define this if you have the type long double.])
   have_long_double=yes
 ],[])
 AC_MSG_RESULT($have_long_double)
@@ -1993,7 +2075,7 @@ fi
 AC_MSG_CHECKING(for _Bool support)
 have_c99_bool=no
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[_Bool x; x = (_Bool)0;]])],[
-  AC_DEFINE(HAVE_C99_BOOL, 1, [Define this if you have the type _Bool.]) 
+  AC_DEFINE(HAVE_C99_BOOL, 1, [Define this if you have the type _Bool.])
   have_c99_bool=yes
 ],[])
 AC_MSG_RESULT($have_c99_bool)
@@ -2001,8 +2083,8 @@ if test "$have_c99_bool" = yes ; then
 AC_CHECK_SIZEOF(_Bool, 1)
 fi
 
-AC_CHECK_TYPES(uintptr_t, 
-   [AC_CHECK_SIZEOF(uintptr_t, 4)], 
+AC_CHECK_TYPES(uintptr_t,
+   [AC_CHECK_SIZEOF(uintptr_t, 4)],
    [], [#ifdef HAVE_STDINT_H
         #include <stdint.h>
         #endif
@@ -2021,7 +2103,7 @@ if test "$have_long_long" = yes
 then
 if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \
        "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then
-  AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, 
+  AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1,
   [Defined to enable large file support when an off_t is bigger than a long
    and long long is available and at least as big as an off_t. You may need
    to add some flags for configuration and compilation to enable this mode.
@@ -2070,7 +2152,7 @@ CC="$ac_save_cc"
 
 AC_SUBST(OTHER_LIBTOOL_OPT)
 case $ac_sys_system/$ac_sys_release in
-  Darwin/@<:@01567@:>@\..*) 
+  Darwin/@<:@01567@:>@\..*)
     OTHER_LIBTOOL_OPT="-prebind -seg1addr 0x10000000"
     ;;
   Darwin/*)
@@ -2081,7 +2163,7 @@ esac
 
 AC_SUBST(LIBTOOL_CRUFT)
 case $ac_sys_system/$ac_sys_release in
-  Darwin/@<:@01567@:>@\..*) 
+  Darwin/@<:@01567@:>@\..*)
     LIBTOOL_CRUFT="-framework System -lcc_dynamic"
     if test "${enable_universalsdk}"; then
            :
@@ -2095,7 +2177,7 @@ case $ac_sys_system/$ac_sys_release in
     if test ${gcc_version} '<' 4.0
         then
             LIBTOOL_CRUFT="-lcc_dynamic"
-        else 
+        else
             LIBTOOL_CRUFT=""
     fi
     AC_RUN_IFELSE([AC_LANG_SOURCE([[
@@ -2109,14 +2191,14 @@ case $ac_sys_system/$ac_sys_release in
       }
     }
     ]])],[ac_osx_32bit=yes],[ac_osx_32bit=no],[ac_osx_32bit=yes])
-    
+
     if test "${ac_osx_32bit}" = "yes"; then
        case `/usr/bin/arch` in
-       i386) 
-               MACOSX_DEFAULT_ARCH="i386" 
+       i386)
+               MACOSX_DEFAULT_ARCH="i386"
                ;;
-       ppc) 
-               MACOSX_DEFAULT_ARCH="ppc" 
+       ppc)
+               MACOSX_DEFAULT_ARCH="ppc"
                ;;
        *)
                AC_MSG_ERROR([Unexpected output of 'arch' on OSX])
@@ -2124,11 +2206,11 @@ case $ac_sys_system/$ac_sys_release in
        esac
     else
        case `/usr/bin/arch` in
-       i386) 
-               MACOSX_DEFAULT_ARCH="x86_64" 
+       i386)
+               MACOSX_DEFAULT_ARCH="x86_64"
                ;;
-       ppc) 
-               MACOSX_DEFAULT_ARCH="ppc64" 
+       ppc)
+               MACOSX_DEFAULT_ARCH="ppc64"
                ;;
        *)
                AC_MSG_ERROR([Unexpected output of 'arch' on OSX])
@@ -2145,9 +2227,9 @@ AC_MSG_CHECKING(for --enable-framework)
 if test "$enable_framework"
 then
        BASECFLAGS="$BASECFLAGS -fno-common -dynamic"
-       # -F. is needed to allow linking to the framework while 
+       # -F. is needed to allow linking to the framework while
        # in the build location.
-       AC_DEFINE(WITH_NEXT_FRAMEWORK, 1, 
+       AC_DEFINE(WITH_NEXT_FRAMEWORK, 1,
          [Define if you want to produce an OpenStep/Rhapsody framework
          (shared library plus accessory files).])
        AC_MSG_RESULT(yes)
@@ -2162,7 +2244,7 @@ fi
 AC_MSG_CHECKING(for dyld)
 case $ac_sys_system/$ac_sys_release in
   Darwin/*)
-       AC_DEFINE(WITH_DYLD, 1, 
+       AC_DEFINE(WITH_DYLD, 1,
         [Define if you want to use the new-style (Openstep, Rhapsody, MacOS)
          dynamic linker (dyld) instead of the old-style (NextStep) dynamic
          linker (rld). Dyld is necessary to support frameworks.])
@@ -2212,7 +2294,7 @@ then
                ;;
        IRIX/5*) LDSHARED="ld -shared";;
        IRIX*/6*) LDSHARED="ld ${SGI_ABI} -shared -all";;
-       SunOS/5*) 
+       SunOS/5*)
                if test "$GCC" = "yes" ; then
                        LDSHARED='$(CC) -shared'
                        LDCXXSHARED='$(CXX) -shared'
@@ -2388,7 +2470,7 @@ then
        BSD/OS/4*) LINKFORSHARED="-Xlinker -export-dynamic";;
        Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";;
        # -u libsys_s pulls in all symbols in libsys
-       Darwin/*) 
+       Darwin/*)
                LINKFORSHARED="$extra_undefs -framework CoreFoundation"
 
                # Issue #18075: the default maximum stack size (8MBytes) is too
@@ -2404,7 +2486,7 @@ then
        OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";;
        SCO_SV*) LINKFORSHARED="-Wl,-Bexport";;
        ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";;
-       FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) 
+       FreeBSD*|NetBSD*|OpenBSD*|DragonFly*)
                if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
                then
                        LINKFORSHARED="-Wl,--export-dynamic"
@@ -2730,7 +2812,7 @@ then
     # Defining _REENTRANT on system with POSIX threads should not hurt.
     AC_DEFINE(_REENTRANT)
     posix_threads=yes
-    THREADOBJ="Python/thread.o"    
+    THREADOBJ="Python/thread.o"
 elif test "$ac_cv_kpthread" = "yes"
 then
     CC="$CC -Kpthread"
@@ -2824,7 +2906,7 @@ pthread_create (NULL, NULL, start_routine, NULL)]])],[
     THREADOBJ="Python/thread.o"
     USE_THREAD_MODULE=""])
 
-    if test "$posix_threads" != "yes"; then     
+    if test "$posix_threads" != "yes"; then
       AC_CHECK_LIB(thread, thr_create, [AC_DEFINE(WITH_THREAD)
       LIBS="$LIBS -lthread"
       THREADOBJ="Python/thread.o"
@@ -2835,7 +2917,7 @@ fi
 if test "$posix_threads" = "yes"; then
       if test "$unistd_defines_pthreads" = "no"; then
          AC_DEFINE(_POSIX_THREADS, 1,
-         [Define if you have POSIX threads, 
+         [Define if you have POSIX threads,
           and your system does not define that.])
       fi
 
@@ -3090,9 +3172,9 @@ AC_MSG_CHECKING(for --with-tsc)
 AC_ARG_WITH(tsc,
            AS_HELP_STRING([--with(out)-tsc],[enable/disable timestamp counter profile]),[
 if test "$withval" != no
-then 
-  AC_DEFINE(WITH_TSC, 1, 
-    [Define to profile with the Pentium timestamp counter]) 
+then
+  AC_DEFINE(WITH_TSC, 1,
+    [Define to profile with the Pentium timestamp counter])
     AC_MSG_RESULT(yes)
 else AC_MSG_RESULT(no)
 fi],
@@ -3109,7 +3191,7 @@ then
 fi
 if test "$with_pymalloc" != "no"
 then
-    AC_DEFINE(WITH_PYMALLOC, 1, 
+    AC_DEFINE(WITH_PYMALLOC, 1,
      [Define if you want to compile in Python-specific mallocs])
     ABIFLAGS="${ABIFLAGS}m"
 fi
@@ -3396,12 +3478,12 @@ dnl before searching for static libraries. setup.py adds -Wl,-search_paths_first
 dnl to revert to a more traditional unix behaviour and make it possible to
 dnl override the system libz with a local static library of libz. Temporarily
 dnl add that flag to our CFLAGS as well to ensure that we check the version
-dnl of libz that will be used by setup.py. 
-dnl The -L/usr/local/lib is needed as wel to get the same compilation 
+dnl of libz that will be used by setup.py.
+dnl The -L/usr/local/lib is needed as wel to get the same compilation
 dnl environment as setup.py (and leaving it out can cause configure to use the
 dnl wrong version of the library)
 case $ac_sys_system/$ac_sys_release in
-Darwin/*) 
+Darwin/*)
        _CUR_CFLAGS="${CFLAGS}"
        _CUR_LDFLAGS="${LDFLAGS}"
        CFLAGS="${CFLAGS} -Wl,-search_paths_first"
@@ -3412,7 +3494,7 @@ esac
 AC_CHECK_LIB(z, inflateCopy, AC_DEFINE(HAVE_ZLIB_COPY, 1, [Define if the zlib library has inflateCopy]))
 
 case $ac_sys_system/$ac_sys_release in
-Darwin/*) 
+Darwin/*)
        CFLAGS="${_CUR_CFLAGS}"
        LDFLAGS="${_CUR_LDFLAGS}"
        ;;
@@ -3466,14 +3548,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 
 # check for openpty and forkpty
 
-AC_CHECK_FUNCS(openpty,, 
+AC_CHECK_FUNCS(openpty,,
    AC_CHECK_LIB(util,openpty,
      [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lutil"],
      AC_CHECK_LIB(bsd,openpty, [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lbsd"])
    )
 )
-AC_CHECK_FUNCS(forkpty,, 
-   AC_CHECK_LIB(util,forkpty, 
+AC_CHECK_FUNCS(forkpty,,
+   AC_CHECK_LIB(util,forkpty,
      [AC_DEFINE(HAVE_FORKPTY) LIBS="$LIBS -lutil"],
      AC_CHECK_LIB(bsd,forkpty, [AC_DEFINE(HAVE_FORKPTY) LIBS="$LIBS -lbsd"])
    )
@@ -3486,7 +3568,7 @@ AC_CHECK_FUNCS(memmove)
 AC_CHECK_FUNCS(fseek64 fseeko fstatvfs ftell64 ftello statvfs)
 
 AC_REPLACE_FUNCS(dup2 strdup)
-AC_CHECK_FUNCS(getpgrp, 
+AC_CHECK_FUNCS(getpgrp,
   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>]], [[getpgrp(0);]])],
     [AC_DEFINE(GETPGRP_HAVE_ARG, 1, [Define if getpgrp() must be called as getpgrp(0).])],
     [])
@@ -3496,7 +3578,7 @@ AC_CHECK_FUNCS(setpgrp,
     [AC_DEFINE(SETPGRP_HAVE_ARG, 1, [Define if setpgrp() must be called as setpgrp(0, 0).])],
     [])
 )
-AC_CHECK_FUNCS(gettimeofday, 
+AC_CHECK_FUNCS(gettimeofday,
   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/time.h>]],
                                     [[gettimeofday((struct timeval*)0,(struct timezone*)0);]])],
     [],
@@ -3541,7 +3623,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 ])
 
 # On OSF/1 V5.1, getaddrinfo is available, but a define
-# for [no]getaddrinfo in netdb.h. 
+# for [no]getaddrinfo in netdb.h.
 AC_MSG_CHECKING(for getaddrinfo)
 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <sys/types.h>
@@ -3679,7 +3761,7 @@ AC_CHECK_MEMBERS([struct stat.st_blksize])
 AC_CHECK_MEMBERS([struct stat.st_flags])
 AC_CHECK_MEMBERS([struct stat.st_gen])
 AC_CHECK_MEMBERS([struct stat.st_birthtime])
-AC_STRUCT_ST_BLOCKS
+AC_CHECK_MEMBERS([struct stat.st_blocks])
 
 AC_MSG_CHECKING(for time.h that defines altzone)
 AC_CACHE_VAL(ac_cv_header_time_altzone,[
@@ -3701,7 +3783,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 ]], [[;]])],[
   AC_DEFINE(SYS_SELECT_WITH_SYS_TIME, 1,
   [Define if  you can safely include both <sys/select.h> and <sys/time.h>
-   (which you can't on SCO ODT 3.0).]) 
+   (which you can't on SCO ODT 3.0).])
   was_it_defined=yes
 ],[])
 AC_MSG_RESULT($was_it_defined)
@@ -3752,8 +3834,8 @@ AC_MSG_RESULT($works)
 have_prototypes=no
 AC_MSG_CHECKING(for prototypes)
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(int x) { return 0; }]], [[return foo(10);]])],
-  [AC_DEFINE(HAVE_PROTOTYPES, 1, 
-     [Define if your compiler supports function prototype]) 
+  [AC_DEFINE(HAVE_PROTOTYPES, 1,
+     [Define if your compiler supports function prototype])
    have_prototypes=yes],
   []
 )
@@ -3774,7 +3856,7 @@ int foo(int x, ...) {
 ]], [[return foo(10, "", 3.14);]])],[
   AC_DEFINE(HAVE_STDARG_PROTOTYPES, 1,
    [Define if your compiler supports variable length function prototypes
-   (e.g. void fprintf(FILE *, char *, ...);) *and* <stdarg.h>]) 
+   (e.g. void fprintf(FILE *, char *, ...);) *and* <stdarg.h>])
   works=yes
 ],[])
 AC_MSG_RESULT($works)
@@ -3809,7 +3891,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 #include <varargs.h>
 #endif
 ]], [[va_list list1, list2; list1 = list2;]])],[],[
- AC_DEFINE(VA_LIST_IS_ARRAY, 1, [Define if a va_list is an array of some kind]) 
+ AC_DEFINE(VA_LIST_IS_ARRAY, 1, [Define if a va_list is an array of some kind])
  va_list_is_array=yes
 ])
 AC_MSG_RESULT($va_list_is_array)
@@ -3904,9 +3986,9 @@ AC_ARG_WITH(fpectl,
             AS_HELP_STRING([--with-fpectl], [enable SIGFPE catching]),
 [
 if test "$withval" != no
-then 
+then
   AC_DEFINE(WANT_SIGFPE_HANDLER, 1,
-  [Define if you want SIGFPE handled (see Include/pyfpe.h).]) 
+  [Define if you want SIGFPE handled (see Include/pyfpe.h).])
   AC_MSG_RESULT(yes)
 else AC_MSG_RESULT(no)
 fi],
@@ -4277,8 +4359,8 @@ AC_DEFINE_UNQUOTED(PYLONG_BITS_IN_DIGIT, $enable_big_digits, [Define as the pref
 
 # check for wchar.h
 AC_CHECK_HEADER(wchar.h, [
-  AC_DEFINE(HAVE_WCHAR_H, 1, 
-  [Define if the compiler provides a wchar.h header file.]) 
+  AC_DEFINE(HAVE_WCHAR_H, 1,
+  [Define if the compiler provides a wchar.h header file.])
   wchar_h="yes"
 ],
 wchar_h="no"
@@ -4479,6 +4561,11 @@ AC_CHECK_LIB(readline, rl_completion_display_matches_hook,
        AC_DEFINE(HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK, 1,
         [Define if you have readline 4.0]), ,$READLINE_LIBS)
 
+# also in 4.0, but not in editline
+AC_CHECK_LIB(readline, rl_resize_terminal,
+       AC_DEFINE(HAVE_RL_RESIZE_TERMINAL, 1,
+        [Define if you have readline 4.0]), ,$READLINE_LIBS)
+
 # check for readline 4.2
 AC_CHECK_LIB(readline, rl_completion_matches,
        AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1,
@@ -4556,7 +4643,7 @@ then
       [Define if poll() sets errno on invalid file descriptors.])
 fi
 
-# Before we can test tzset, we need to check if struct tm has a tm_zone 
+# Before we can test tzset, we need to check if struct tm has a tm_zone
 # (which is not required by ISO C or UNIX spec) and/or if we support
 # tzname[]
 AC_STRUCT_TIMEZONE
@@ -4582,7 +4669,7 @@ int main()
           tm->tm_zone does not exist since it is the alternative way
           of getting timezone info.
 
-          Red Hat 6.2 doesn't understand the southern hemisphere 
+          Red Hat 6.2 doesn't understand the southern hemisphere
           after New Year's Day.
        */
 
@@ -4595,7 +4682,7 @@ int main()
            exit(1);
 #if HAVE_TZNAME
        /* For UTC, tzname[1] is sometimes "", sometimes "   " */
-       if (strcmp(tzname[0], "UTC") || 
+       if (strcmp(tzname[0], "UTC") ||
                (tzname[1][0] != 0 && tzname[1][0] != ' '))
            exit(1);
 #endif
@@ -4713,7 +4800,7 @@ AC_MSG_RESULT($ac_cv_window_has_flags)
 
 if test "$ac_cv_window_has_flags" = yes
 then
-  AC_DEFINE(WINDOW_HAS_FLAGS, 1, 
+  AC_DEFINE(WINDOW_HAS_FLAGS, 1,
   [Define if WINDOW in curses.h offers a field _flags.])
 fi
 
@@ -4912,7 +4999,7 @@ AC_MSG_RESULT($ac_cv_broken_mbstowcs)
 if test "$ac_cv_broken_mbstowcs" = yes
 then
   AC_DEFINE(HAVE_BROKEN_MBSTOWCS, 1,
-  [Define if mbstowcs(NULL, "text", 0) does not return the number of 
+  [Define if mbstowcs(NULL, "text", 0) does not return the number of
    wide chars that would be converted.])
 fi
 
@@ -4923,15 +5010,15 @@ AC_ARG_WITH(computed-gotos,
                            [Use computed gotos in evaluation loop (enabled by default on supported compilers)]),
 [
 if test "$withval" = yes
-then 
+then
   AC_DEFINE(USE_COMPUTED_GOTOS, 1,
-  [Define if you want to use computed gotos in ceval.c.]) 
+  [Define if you want to use computed gotos in ceval.c.])
   AC_MSG_RESULT(yes)
 fi
 if test "$withval" = no
-then 
+then
   AC_DEFINE(USE_COMPUTED_GOTOS, 0,
-  [Define if you want to use computed gotos in ceval.c.]) 
+  [Define if you want to use computed gotos in ceval.c.])
   AC_MSG_RESULT(no)
 fi
 ],
@@ -4965,7 +5052,7 @@ case "$ac_cv_computed_gotos" in yes*)
 esac
 
 case $ac_sys_system in
-AIX*)   
+AIX*)
   AC_DEFINE(HAVE_BROKEN_PIPE_BUF, 1, [Define if the system reports an invalid PIPE_BUF value.]) ;;
 esac
 
@@ -5151,13 +5238,15 @@ AC_MSG_CHECKING(for the Linux getrandom() syscall)
 AC_LINK_IFELSE(
 [
   AC_LANG_SOURCE([[
+    #include <unistd.h>
     #include <sys/syscall.h>
+    #include <linux/random.h>
 
     int main() {
         char buffer[1];
         const size_t buflen = sizeof(buffer);
-        const int flags = 0;
-        /* ignore the result, Python checks for ENOSYS at runtime */
+        const int flags = GRND_NONBLOCK;
+        /* ignore the result, Python checks for ENOSYS and EAGAIN at runtime */
         (void)syscall(SYS_getrandom, buffer, buflen, flags);
         return 0;
     }
index b0cafb3..7895535 100644 (file)
 /* Define to 1 if you have the <linux/tipc.h> header file. */
 #undef HAVE_LINUX_TIPC_H
 
+/* Define to 1 if you have the <linux/random.h> header file. */
+#undef HAVE_LINUX_RANDOM_H
+
 /* Define to 1 if you have the `lockf' function. */
 #undef HAVE_LOCKF
 
 /* Define if you have readline 4.0 */
 #undef HAVE_RL_PRE_INPUT_HOOK
 
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_RESIZE_TERMINAL
+
 /* Define to 1 if you have the `round' function. */
 #undef HAVE_ROUND
 
 /* Define to 1 if `tm_zone' is a member of `struct tm'. */
 #undef HAVE_STRUCT_TM_TM_ZONE
 
-/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
-   `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
-#undef HAVE_ST_BLOCKS
-
 /* Define if you have the 'symlink' function. */
 #undef HAVE_SYMLINK
 
index da67731..174ce72 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -136,6 +136,22 @@ def find_library_file(compiler, libname, std_dirs, paths):
         p = p.rstrip(os.sep)
 
         if host_platform == 'darwin' and is_macosx_sdk_path(p):
+            # Note that, as of Xcode 7, Apple SDKs may contain textual stub
+            # libraries with .tbd extensions rather than the normal .dylib
+            # shared libraries installed in /.  The Apple compiler tool
+            # chain handles this transparently but it can cause problems
+            # for programs that are being built with an SDK and searching
+            # for specific libraries.  Distutils find_library_file() now
+            # knows to also search for and return .tbd files.  But callers
+            # of find_library_file need to keep in mind that the base filename
+            # of the returned SDK library file might have a different extension
+            # from that of the library file installed on the running system,
+            # for example:
+            #   /Applications/Xcode.app/Contents/Developer/Platforms/
+            #       MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/
+            #       usr/lib/libedit.tbd
+            # vs
+            #   /usr/lib/libedit.dylib
             if os.path.join(sysroot, p[1:]) == dirname:
                 return [ ]
 
@@ -464,6 +480,13 @@ class PyBuildExt(build_ext):
         finally:
             os.unlink(tmpfile)
 
+    def detect_math_libs(self):
+        # Check for MacOS X, which doesn't need libm.a at all
+        if host_platform == 'darwin':
+            return []
+        else:
+            return ['m']
+
     def detect_modules(self):
         # Ensure that /usr/local is always used, but the local build
         # directories (i.e. '.' and 'Include') must be first.  See issue
@@ -568,10 +591,7 @@ class PyBuildExt(build_ext):
                 if item.startswith('-L'):
                     lib_dirs.append(item[2:])
 
-        # Check for MacOS X, which doesn't need libm.a at all
-        math_libs = ['m']
-        if host_platform == 'darwin':
-            math_libs = []
+        math_libs = self.detect_math_libs()
 
         # XXX Omitted modules: gl, pure, dl, SGI-specific modules
 
@@ -582,13 +602,17 @@ class PyBuildExt(build_ext):
 
         # array objects
         exts.append( Extension('array', ['arraymodule.c']) )
+
+        shared_math = 'Modules/_math.o'
         # complex math library functions
-        exts.append( Extension('cmath', ['cmathmodule.c', '_math.c'],
-                               depends=['_math.h'],
+        exts.append( Extension('cmath', ['cmathmodule.c'],
+                               extra_objects=[shared_math],
+                               depends=['_math.h', shared_math],
                                libraries=math_libs) )
         # math library functions, e.g. sin()
-        exts.append( Extension('math',  ['mathmodule.c', '_math.c'],
-                               depends=['_math.h'],
+        exts.append( Extension('math',  ['mathmodule.c'],
+                               extra_objects=[shared_math],
+                               depends=['_math.h', shared_math],
                                libraries=math_libs) )
 
         # time libraries: librt may be needed for clock_gettime()
@@ -600,7 +624,10 @@ class PyBuildExt(build_ext):
         # time operations and variables
         exts.append( Extension('time', ['timemodule.c'],
                                libraries=time_libs) )
-        exts.append( Extension('_datetime', ['_datetimemodule.c']) )
+        # math_libs is needed by delta_new() that uses round() and by accum()
+        # that uses modf().
+        exts.append( Extension('_datetime', ['_datetimemodule.c'],
+                               libraries=math_libs) )
         # random number generator implemented in C
         exts.append( Extension("_random", ["_randommodule.c"]) )
         # bisect
@@ -671,11 +698,14 @@ class PyBuildExt(build_ext):
         # Multimedia modules
         # These don't work for 64-bit platforms!!!
         # These represent audio samples or images as strings:
-
+        #
         # Operations on audio samples
         # According to #993173, this one should actually work fine on
         # 64-bit platforms.
-        exts.append( Extension('audioop', ['audioop.c']) )
+        #
+        # audioop needs math_libs for floor() in multiple functions.
+        exts.append( Extension('audioop', ['audioop.c'],
+                               libraries=math_libs) )
 
         # readline
         do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
@@ -738,7 +768,7 @@ class PyBuildExt(build_ext):
                 # In every directory on the search path search for a dynamic
                 # library and then a static library, instead of first looking
                 # for dynamic libraries on the entire path.
-                # This way a staticly linked custom readline gets picked up
+                # This way a statically linked custom readline gets picked up
                 # before the (possibly broken) dynamic library in /usr/lib.
                 readline_extra_link_args = ('-Wl,-search_paths_first',)
             else:
@@ -1592,7 +1622,7 @@ class PyBuildExt(build_ext):
         #     --with-tcltk-libs="-L/path/to/tcllibs -ltclm.n \
         #                        -L/path/to/tklibs -ltkm.n"
         #
-        # These values can also be specified or overriden via make:
+        # These values can also be specified or overridden via make:
         #    make TCLTK_INCLUDES="..." TCLTK_LIBS="..."
         #
         # This can be useful for building and testing tkinter with multiple
@@ -1917,6 +1947,7 @@ class PyBuildExt(build_ext):
                    '_ctypes/stgdict.c',
                    '_ctypes/cfield.c']
         depends = ['_ctypes/ctypes.h']
+        math_libs = self.detect_math_libs()
 
         if host_platform == 'darwin':
             sources.append('_ctypes/malloc_closure.c')
@@ -1947,8 +1978,10 @@ class PyBuildExt(build_ext):
                         libraries=[],
                         sources=sources,
                         depends=depends)
+        # function my_sqrt() needs math library for sqrt()
         ext_test = Extension('_ctypes_test',
-                             sources=['_ctypes/_ctypes_test.c'])
+                     sources=['_ctypes/_ctypes_test.c'],
+                     libraries=math_libs)
         self.extensions.extend([ext, ext_test])
 
         if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"):