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>
980 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-18.2-py2.py3-none-any.whl [deleted file]
Lib/ensurepip/_bundled/setuptools-20.10.1-py2.py3-none-any.whl [new file with mode: 0644]
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 580d10241db52e261d7f22c4dcc83939512f0cf5..4f8e9f8f1417fbc2de630e2759c6e35a83735a2b 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 f01ae0e3900ec11b9bddb8862369f06d93ac9ca1..1b0a5a9a9377cbe79f6ee9adca69d6e4aabd9550 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 ed62deaec1c87c23f02adc888263bfdf010ba924..983d113f0a1bb216b6704ac4dfd1a2b75041e0d0 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 9c9356338243649c9ef5850222696aa5403195cc..10d89f297c843fbd7d7c3a60b620723cf4215292 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 3fd69ba80fa3aacfba151312dcf819d2d7972878..19cbb3bcb870284117ee04ac155c779ee566502d 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 ad9832233f74d9f9f40dc5b80f7a12d785d7e98b..17279c732ae07660b13ee7a67572187c32961fd8 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 9f6ad852260945c6ff5d0f6c5a6f0e45bb2606f5..f5e0d7ec9c79c368f90e22b20785e5e31cfa528c 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 bf1b49577e4c55d2382e4e6482294300e8bdf71f..2936f4ff33dd6ba80b94ddff95fe2631cb602c23 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 81823bf38305e472bbc841a38b3391632e1b6e15..639819ce29a1e58cc3d02b7f02ab8ef191adcacf 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 e34104708ca68c734336f3fb5ac18b8a79a8171b..fe601b605b13837f1c38ccb8dae4b19037dc6132 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 7339006b5e7157169aeeaa505dd9eac080d66895..290ef09dcecc6431e5e63ee369f406554ab04935 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 acc81e4814692fb40a0a78ca53695c234348ae18..7a2a84fe110dcf0d332f30da0cd7275acc9b4e3b 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 ef778ccaedbb1b06e3b92e423dc8a35a1668259d..904b4b1f662706ed1eba587a596a850041a4539b 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 97b45b12cbb28ff4fa8a12ee3fd067f6c96f2223..b761c808fcb7f6c50b780d25c7d59e3c39f6acfc 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 5960db9d42f961c00de30f29a34222a03dca75cb..f1825f079be47468be02f55afe60d1171fd08431 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 7f4d534a700dae4bb9e2b93f7a11fd1f8f6bea35..8de0394112e9cea705d8eb93a14702eb6254b75f 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 063f856d227be4231ab5a4ae62d6a5ea008f1f3e..5b771dd4adcefb24207a97e6ab6799c032f7c467 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 b5113aaef19d5cb94d2077ef152caf66932f4d25..ac589b87b803f79135b8ac64f40e4f73a3286b7d 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 2eeadb52c90b9cfa50d67ca017e7a998c16d59b5..a0672ca2573d4c1b40f524a7e08ea42fd64a4e70 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 f8aaf0f67ad731b5c1909593a2500243d9d5cd6d..706efdfd55d6df71c07d79c57b90a0802ded6a02 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 28dd80f8590f49bd8a11389559e68fc4e4d6ab81..d6f20ba25c48d685d1217da110f10740c1301db2 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 2b2f88700f6378461cf5a9b270b0d3f2e38d8281..22d7705846ea936e751bb78490f5445cda3aa62d 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 1774d23643ec460ae82cc0f392341bb36b201acb..82ecd2c1ef45fbef9ed98c17416830cb804de00b 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 554d2c878db4594e7dc209bb27284d94794bf105..0672253471b45b1285e374b846f0d311c1fb2214 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 8faffe6c200d8163f7a5f8cbcc5021c88274240e..51d88971a4ba4d1cb8e68a84f5f5e980e75c56c8 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 335f804d42f3ba062f8d186ce3853efca9646188..c565bcc562862490828bfb011464e2f9d488a7d1 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 163179d6836515f1dbbd066715bd598c599ae8ec..b5ccee75feff49f3435c1c068a951e101b9271e6 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 8cc41840d7c8b65297b379a5f3638709d297f9d2..523dfab70c7d5ef662253a19ee4db2c51a0586dc 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 dd43926450235527f7d668d7a9e6477fff2af645..9eec8c273af30111ce56d1e7eb6de8bbdca6a3a2 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 9fdf8cb9498178750cbbd628a6f3759c1b6d9474..1b6cd7e2413f5c84999c800db8a28c66b43f4858 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 7bb4dc2e608819e4580e114afddcad9d5f41cba7..852e35f8b54ebe770020ef3132f2e99ff86c2f87 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 2221f1492739b58f66ba807289acbd6e62a3e008..6b773dd1e98f9e540576e73c1448115fb451d777 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 5122de1c1a998479b3a4e611996867d96a1d0c0d..98a28c3c8a7a4411249352b20dcc19915b42a6a0 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 064728ff6865a68c0e19d91881e3929cf12e14dd..b5fdfa42cdb0823e5fa34eb2ab7d62dfcf8fe9c2 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 295445edc122232e511853d4a597162f98d23cff..694753e5b9acf2b5ce6629201f9efe3bf4a019cd 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 6db6637ed78d500cc9497e1e4d925faf2ed61eea..d7253436beaf61d18d63532aeeb662cbfba795dd 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 6808e7ac5d50ec8a6a798edb9e599dc41caeef80..45b794f48ef7c9eed1045170fce13bb3d04f297e 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 510d1d49dbd5f62ea0c0485e319f31ba7ce6b687..cfe98688757cd073498b9b83e9c299f82efc9300 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 d7a708630259e9aa0049af359f1daa1919515282..27e7e6f6e0d9a037bfd3cf213892ad22cb4cfb7e 100644 (file)
@@ -161,7 +161,7 @@ simple example demonstrates how. ::
 
    #define INITERROR return NULL
 
-   PyObject *
+   PyMODINIT_FUNC
    PyInit_myextension(void)
 
    #else
index 87a5cab142bfa8e1b90526cd0db72e87d5b5e670..188a5cf2231b87cff05e3de4cb8e1649cb2ed5a4 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 530f34b88f9b5b42ce02b1a261c34e85d5d2dd66..d370eb557232ea84156187ae5d5bfad7c652b3e7 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 945a240666cf42b426b7c0a28e19772fdf2e8b46..6e21f935446124507959aac502830fcf08e8e082 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 2c9d69910a6db333aa6dcd2f829a8da55a47a8be..de659505f7170538d9def3524a09e172d8b6194c 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 b979aa7d7d8389a57cfa72d88378ab2ce247b9d1..99b4cdcb5fa848d4e5d8cb9916df63ce3b35af6e 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 4ce14f98addc1b5e6992124e95f9c808793ed800..51e843048573cee238774984472f6621687d2e8b 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 a2aaf367c78afda1c70a958a41b3b50ac128be4d..c479f2264e95ecd701fcade91b8072f21bfec6d5 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 ad2c6ab7d54d7a24d75564d4290d32c136d613ed..de3f4612cc6dc61b8db1ca5f582c3e87b25d7558 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 f2e64ee98b0d322aaa34b0347c960a7422dff660..0334b2665754eed7131bb69c17b566699fdd06fa 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 ee31a9c981938c1ed15268709bb06a8b711c1d2c..50a09bac4cdec51e9ced10d8da69f333704761a3 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 e3d77142f4e4b9ab3c6ca937ad2e8fcf4bd938dd..24a415604fd137b6679a08add5d0681d6b755fa1 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 febdb7c80a23d5102308906000c4fe835a50b4f6..b22fc5958ce4c60f6ba477ad2442cf09a1a7753a 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 973c689861f55903ecdc24513caa39ee16ff687b..1ef314999ba285ceb74cfaccaf0d3efb46f27f0a 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 31f681d7e099724fbd6b3d0ebfd841959f306536..6fc28656b8f16608c80b94c787b1e3abe20f2980 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 a46993d55ed24b4b68d2e2d3c211d339d7070191..a64faf1bbe3c849f0ba5dc2e4b210558bba6d430 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 7122861c4517b8c2218f3147005a2dde35a4993a..0d2d818f5f90b00cf1e4779a61972fe066a83f53 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 7a73704bf682f8e8cafee1af6f00177c041b9997..966003bd45ada1ffb670d4480c26034fc275edd7 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 6fbcf286cf1fc06a87734d1a180ab1820779828d..23a96207d083894df38a8d5200bf79aedbe22605 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 2877437b9940fa3fa2ffd4b7175a393515845185..10789e9f883089f3b093c4b951325044f3780bbc 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 f1ab9595720b6575557f217bd31ce5d5ea7e12d1..24f3f62ae73563b90c98d2208bc217170d3269c6 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 5373acd57b0e477b17c6420bf3085561fb4d92cf..8c3b7e4ce4e5516c74afffee44d702c2d078cee2 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 794da8cced7f70b17df69bf6fb6c85ff090e09ff..ae72d26122cbb9503b93d7370dd9cef47939dbe9 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 dbe351d5f7d41f65354435ce0e5460abb08aa03c..7ec3aa106e265405c2b4da5737e9dfb10d00a006 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 b2e7d7c972275d4a58cd028a147ad974fa5c7bf7..b8f29d78ddfd30121761c1abfe3b9225ebaf6e5a 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 fffd3e8d63fb6e55fb6e353d1e4910ee088deec5..23d34d05c02fafcb4710a832d13a970931c6ee66 100644 (file)
@@ -1,8 +1,8 @@
 .. currentmodule:: asyncio
 
-+++++++++++++++++++++++++++++++++++++++++
-Transports  and protocols (low-level API)
-+++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++
+Transports  and protocols (callback based API)
+++++++++++++++++++++++++++++++++++++++++++++++
 
 .. _asyncio-transport:
 
index 171fd86276204541819e8459735c64d189eb93e2..08fe07156ae79f4edc99de7c2c713294b453343a 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 21dae54e38fbd7e08f25e841d951a4cc795ea95e..51ce4278daea641c4e62a373573585332289f724 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 ad3b523f989b9758d00f24016dc2fb43c029f35e..09093521524a89bf91394d19d4c75fe061645288 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 051ae09b8a5329523296ce673b96f32831be08c2..de6ee58e9207328c222fa62dcb7ae2fb54ad13e2 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 9b4d65e5da0fe9d57341ee4c105fa9c2300eaed2..f764c683b15659f3e75fbc4af7777047dfec3323 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 917d0448c2f0f7a232e770378d8b25afd7111ab7..61061be34e25cb9c2126ef2c0397a36bf9dfff67 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 dbdd81e6d01d57fbde2a286c0a2503016763222a..1d84d4587fd9c009c4eb207fac24476609897666 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 ce127aa06a61b1d965033c6c300d6bfdbe555d20..bad9da2ec62e565d50bfdd0ed45519251f07ae35 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 3d23dfc765df1724628a9d247e936738202292fb..080d9d77ec984ea4537f2c072cd8c1ebf79f0fef 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 e3f134b53aca4c117b2a7f6ff7625db7a2f5c989..878d8db53cd26d59a41bf960590fd4a79155fe33 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 43c78237d26248d088918d719e9c9b1ef610ada3..359ab23b2f9787d4cab952c5d706f25c07822e2e 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 13b014719074280dceeda88a9f6d6cccdbf57bb4..6bf7814b257f4abdbe48b48614635313fdbb07d7 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 2cca1d05dfbe6a67856fb97e6aad8354ac99ab0b..4b589a588dfcaf365bf0fc0660ffa0f36256a12f 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 1b8d9cffc6556063a51272fa9812796ce27ec73a..6c49d9fffe9c1187a05fe1dc865227cd082294db 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 3187c43a84ba716a26b92ba9a71b47f0766ff203..df76e3366860a68afc3c71c0a6103d1c9b17e14c 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 7e496ca3611eedb1de0f0d84d0157c65a761b2f6..0bc2c351370c4a130bc1e25b066686fc67b13409 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 6827c8eb5b5c0e8f35f3a2f108d668628bd147d0..b65a6355fe35133d42f94743893a23120678faf6 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 a90e9f808bd013c19465122ef01ae3853dac39e5..5e24df923ed21024f986d8597921f1ac6938b344 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 ab619a082aea62be65f05b1d598548d35829f2e6..62ddb6bc4877362f66f81c65588ae3e8d05eedaf 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 1ab2d7423fc4906c9dd293432eba5c8fc1c9fcaf..61ef0f674493137dca5ad7e7fd683d8f1ae88ed3 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 275201c69b9bce0f94a040ff0a24081d8a8f881b..443af699f24ff6927ad7072646b69e937790bde0 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 46d72b5e9bd971d826bf89000427187806bff064..1add30072f45816d69e12a68df18efd0a18f3e75 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 9ae4176485359ca289d20338fc6b196dce1b9c48..a52d2c62c4fea11c4340b3756304be0068809010 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 d9b93ad26273edc189e5111157e94fce761362d2..61682ccd3716491372f5612c27af29653c2a4f97 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 2ab44135d5ffbd84683e1199a808eb01c4337482..4936b3a0f8b282476ab7a91381cd2995bdb6cb03 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 225306c2d3a6b6e8ed28a00a631b0374e110c39c..c33f531cc1d000de364da95675abb62e5988b0bd 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 c5736f204399d9ec52fc3607db41a17102eb47ca..511c581ad0d282cbafcfc70df67e957cffefa4d4 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 8bb70a501589fb4d176a139d2548724181afceda..ae03f4b8f438ff8446b5afaa179c52611a9417a4 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 c9187a3441a7f54bd2a9fd40093570c0336dc34a..eeae96aab99efc6d4ab65fed1f44ca7bb7d74c08 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 9e8463df51402d788a9cdb0c3471fb625736b7ad..cf85fcd4b295697133bac1c6cce229a2edb1ff43 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 02ef0e5ee7d35bd36885575d9e5d7a6833e097a0..a8adcadbe05e2af85501130454192ae19a858fd4 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 18306c7f99f08dc13aa9bdccc36e1b92fee585b7..eeabb4c6580cd61398b352596c74bd17c8c0fffb 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 b4c90cd59232fd67eb0d3378903fa541270b1bc5..a21c1e7a75ac66ce742f4ab95e55c2f439b96af9 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 8ad24c8d4fbf73c3ac88bfcfe77b4dd7b26247b7..1eddfdc12c08c1c6cd238e94f1f6a15ed2166102 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 4fcfaef2581e0ca69d019065f4c9366fc302cfb6..7fb4fc8256aca3b5a4c301534f1864c67d33ee26 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 630d279174f5d25d0e65226c8a75db112003c465..a67579073747ebcd1f46dcbdd70a506a9fffe595 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 6bc1fb9ae3db3c46843b350e11009c52e583e1a0..f3661d9bc5bd68e6bd94d3d8b3dd8f030cd896af 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 a3c8bda63c2c1dbcb119c33a75594a7bf0f42c82..c99c37a5651bad151aea4a47808ae126ea2b22c2 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 e8dfd833e414acf141d3a37d025cfb5fa1c1032a..b12a325f37087aa997e22506b04e23f3ddbc8dd5 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 976cd4900031f5847ef32f85665828762cc4768e..9254ae8cfadbaf33348d75e2b51962f258189570 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 3f3c43d4383fba51737b821ee41537c199b7c793..6f64196a8aacecb941305bb91e92de845fc9d7d2 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 2de0ea0870c3b59d3f2bd9c323d101f2f34f61eb..528f97b1ab84491d271cabd81986e3a0c9e3b0bb 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 e7e5df63cff1c178f673819f76364563112f4ba2..59a6478d8d839e1ab59c7b12e7470a9012d06000 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 1bcb3a4a07f4be674fcbca7b0f919aee7828e30c..d2d8ac7839bbb511d02c7b0ddc79b7f7a222db84 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 e3d1314572554a66ea698c677a944b8f7de67938..62abc85ac397a4ea56be2be44c39648fddb6535b 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 9f7d12c626b2c370ee8d9d32a75b7b5d6688889d..c58f417c3127219abe843bdf06ec2b0057a30b12 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 80ef3d62ccc4b4bd07b90331f789b66e49738afa..161d86a3b70d2fb8ae81d55ad463a385fc1c4ef8 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 f53d34b34cbac5cd3ae7c7236994cbbe20f786fa..cd63728372087c298b3ce61160226c235160a1ca 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 916ba5d18a7caa53a9c82a457b87aa3ce1dd66a3..9d7f9bf5e925d5e07cf19adce8127ca7ff85c373 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 294e3edbdcf2c0532f6632367ed16ab235262320..8470783e816bfdf801199416a949f60ad645977e 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 48d41e1dc78e962968f0beb1276130eb9c871cb1..d596ed8d855580c37d2a1f105c2df3b56017cb1f 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 346d23fc8cd5f385bc2b6a7b7470b6b99f4c3a22..e94837c1c987d2175456c8b8b2a8bef08cc9cdb3 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 db3aade416fdde7926d33c79627164d5ca77e59f..0707bd858ac94920cc12c91ec1216a86193dad48 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 f92f460249822d9b5612efdcc8ce0c741177d461..f3e9e184a57c1d8cae6f56c753e868a3b31bc120 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 b91f26d12045eb4a25a79f8139290052695de5cc..91a694f3ecf7aafd952121e4440823f12b600c01 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 67d0a679549ccd740fca27ec96eca515a26b8163..8297deaf93aa160d2ab70833a5dc0195ef650781 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 177adc62e77f4d946ec4728bda72038aa68587b6..93c09ad9604654c1fda1f98faa45c344e58a3b42 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 045b11930305e8bc5ffa8308a63812f251a1036a..47f321227a4360832cab932de6634b113a48076c 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 95c0a2f4a8605d3ea26bf1f3c718b6db89ddabbe..e8bb02bff524dd76e92cf47fb87694fbd9dfaf64 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 219e2847ea2d4bf1a09dc4c7f8996ee79668120f..5cff7465dfe431e2991728afcc91adfbb71b3d1f 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 d589f1cf12f3e527e8c7a3a52ff3408a216bd3e9..6aeeabc3063aab4bb3a6c1d3bf6370dc3bf912db 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 81f97b310e9c9a4e289ca25bde1154e3ba57e6d3..60467b4acb8fe2925bf8bb7999ced756ead1ade6 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 22a5cbc4507e123d2a3f842870ff9c4ebe2ad998..1cbd51c582c0cf0340a989e34fb0c4cbec9bd77e 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 ba6122e29bc9cf58798071be74eea738578262fa..5a7193393cc3ea53ad1a1ff8fac608a10f6b4646 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 3a5badd0ffa34860122eb89e2eb992a409a24809..deedea1f26fc29f8057c3bcb916196af1453f137 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 f8bb8340ea91918ce150e6af2ed37a94f8092acc..88112f6b7e545b79892cf6f83373de15a11306db 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 06d3f21300a77163884a9b2b055edbb7ec400a88..31b9b4afab93489527f893ec0b3de5dd61951410 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 ee06830ad8e7640d22ff9fd8b1c7866d54cbf4e1..aa4c529b2a6797b6339f2ca19c88c4dff9a1b191 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 68b437f2c04148f0021ae5d4ddb03709d577fa49..85ac4849653f6b53b5e4e1eb820c80b2205d54d4 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 8e8e201ae1e79c7704cf8b0c0ada273c770dc011..6c10ac6fab50e47db0e903510ad2ea575a0b5050 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 fb15f6944506b451aec9cfaf4312c4a043991427..e4b528cf0b0b6fdd5c99585964c7e3bdb863afc7 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 d24f80ac4bdca9d357303f3c47a0e691c58a805e..b5a818e1cafa6162cb291813be6937a9566194f8 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 f06e678ecd1e420f04efcd80c8db26c54bb41d85..233e11fb5ae0bfd61d8b4d9635691329884166af 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 c8de0628b84387046a6f4631b93a6565e1a1177c..c3563f369093a1305f79d35dd2cf4b27957925d3 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 46aa88767ea93253f41bbc9e485011faff21d7cd..abdd66fb652614783150762661ed3689de6d475c 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 d11c2e128273e3c1e60e350e3d3649e7e6d418e6..4af16a9dfdb3413dc91e2d165e9ce9fb9b992a3d 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 f9a1e53e38ba5e315c4eed552e2dc7793fb42f5e..336deab28cb8a46af63d78ba119354248c767c1f 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 211563e23e56b07658cd85634dbd4944855236f4..5eb9f04a8da795332cf0d6b8ba77e42558187c09 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 514cc5a9893f1d6fd62cf1bfb5fcaff98f5d587f..ea439b527f57c6a88d1bb5f3c4f650709b4cb695 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 4c01bf6f1eeb4aae7ed58e19d6008978249d76c3..328eef30f10707d5789745c99367fc01d13fc016 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 88821406a33d690ae774321fcc920e9754208f99..a30e6229db6ad594ab3aba21a10ae09ef4f77db4 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 769f96f0176efe9d4c7f237eee2bb0d2ae96967f..30be3354af73723b909519e5d59272ef00c1742d 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 9fbbcc69049139146bf4a9b4ee198ddc0a07cee2..7e33e7481467faa9176f0a2d5f055464affc8166 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 1446da6ee653bf6bbb7dd6ac8dc5cd7742b62ded..bb44866879bc52322208aab1bf53909aad75b028 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 e10e46e2b8ddd031f3c5c0943394039a44edf463..067e1b1e5adb3e29887a21bd7ffc7848db007e71 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 824995eddceeb5afe75175060aac60f92877a696..16abb406210cfb95af04ddc743bf004512cee0df 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 d57649c4aaa6afdb05ca6e3a58e7a4ffc4fd73e7..8954648976066f64561b282c8bfda73eb20fb834 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 ca68aacc923adca5501909ed2743d0b63b93ccb9..5370601544c766bf2832bd140c3f07ec170b0df9 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 c2bb80d5d19d82c27a7074f9a1a65a9cabf766c9..4b45d4bc388a2180cf5d3a8f49e901a42b7d4071 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 b6f2c582185e8882cc31185ed24ccf9eda98913c..be661c5e8c23828eb496d1a22cab503f3fa7b1fb 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 0bde35b02a8f49d98573106368bc87537fb8c171..16c4fac9477ecabbc269f24f69759e8f2601389a 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 4384d56814e1e61ff0972c0f19c7d52b7a84639a..9ca92ceb5567d102b6e2bfd68f702170a5bf67f4 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 15b0932973dce5acff02b3691c730875fa0f5b1d..c25e7d8611f469a1f9f531223ee1a5a5dd42f9e0 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 68a6b681ef54ad0fe6ca703242641a949ca8ea58..9828ba6fe2e033ae728788bd9d57c058772b09b1 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 da6135345394d38ea511bac0f073aafbb4da9147..3302446b40d70d7a08a017e159c0615180a13ceb 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 23e559cabc2d105fec2513e2d39f07ca33613e94..b28d0f98856f3f8b76f74a00498de09918e1f1dd 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 cb3e9edf11dd4f8ad3c5a6c1e2020509d2503d20..23df18f8e7b2d3a7bdb309dadcc359bcb67da189 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 90fcc748e761d052b81a88f838295c737dd3e9bb..23526b6c4227f61811463fa467ccfed1b3bad150 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 8c7592d17e9ee81b73b6d375f7e61a94223215fa..dfc1ddc2d78ee3b1fb1b1762e083822f4b425ef5 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 d62f14be60e3eda48a777d38260b8d1af11487d9..174e73411511595fe2ef1ab19399d1492db02243 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 3f14885b0641527955323475a2b2b4dbe70f5b92..ae3de9fc0a74d6aae28210163417383991cda546 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 61b79faf328e678faef8fa7720ab3e1cfd30cd61..5aaf4a398f744147c75a21badf66f2907e2789eb 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 fd6a47778fce243ba7eddbf36cc9f6601f7437b4..e196724b826529665b5231a836ea41ccb1e54db9 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 0edc942caa9db05590cdacee214cbf688f28c5c5..855adabf86965dc3e5b1333bb3b9fb6423240174 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 bf821abac16cf70fcc771cd11352f5b3bb42bcfa..72da385d72972f8fc700194204b4a3053fbc9ccb 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 054600530bcd54d6c0b075cd4c0f89ca2c07ee17..f99c495ce9975b3a8f658680ec9e8fc341528344 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 b7a5d89239dc437d67e1fc5dbe641bce981eb2f2..b08bbe08093dab800c48cd611d1f248e28f1043b 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 d29902dc855561e1e0edb1405f5d0901cbc36937..81244c2ed02bd308c2e633be311ef3b4c6a1641a 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 8115e42603eac5e03f36fe9ced99231322e1f120..896afd1d7306286c05c3274b75e0f13fa10904a4 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 af43944b2c9235ee9564c9544928e6d586560166..1ffc6effc7142d9fce1b8ae6b0b42c8b461c8bcc 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 244663eda9a9119ca168a706956b966aa94c31b2..3fdea18cfd94d2f096b6428b69af306c2f2e380d 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 8739ea3dcd2675dc820777aeabf5666abb1f8635..464248c3ea7990c8dbcca1c666feb6d91afc9545 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 b74a8231ea929a900952bb9b3835ec796f7b15b9..8f538339aa09e6f4de20fcc3abd15960aceec80e 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 e84a4964a07e48fc5f4a963061dd27a50049c070..7b39ce7d1aae5d5fc1e9d2c77c34cc063e0d56e3 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 4145c8e7cc0461eff7010efe82d932c917e229e1..0a420329748cb306b802e016db298195ad8ae28c 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 fadaf05a09f00c9cb67edbae71a1605ab0b144a1..b334eeb314dd7c289ec282484cc765abc21d0bb7 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 8575fb50cd4e78c000248ad9e2b952a73183b8f3..c5c092c1cee0ce1228df50f4ad56bdde9482b855 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 23ffed69eb512d98dc6102760f08f29ae4e426fc..cdc2616368df35d5c36b75419636ac13fb21259f 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 ade2a7aad01a4cfd9586652ab47d523016537550..10c67cbb81b2f057470ff6f039f37da10336f3a2 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 9fb1b4594d0523a6cfd5b98975244872965eefd5..9790e3a0b249671e923be4e75d42bf3141850bcc 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 8ab07d0b93d9be02e37ea4d094bb21627a7c308f..1b594952ead7241dacf8fa751bd3e7a014ba15a4 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 c01e63b77a993382f6e820956321d4f49f997812..8121b480cb65743110fd92f8969591341665c32a 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 160c29d3b53fc9a0f5ba92d55b67ef17ec76da84..9a4ba4e6ed2fa07759be4d9dcd2810b90d66fc8a 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 4b4e0b42d3b4f699e2ccb4f98ecf03d1571686a2..bf0dface7e9fd202b491ef049c9248e65de14631 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 0cc9d9c1d3ec61ab00a7f7af5ad2766570f272b6..743efb691a23f3a98cf7c6abf0ef55b9af134c7e 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 c60d596506c217d4409106e7c3c71991bd6b429b..ec40c0b93abf7be646a24e9e8f4119e127d79f72 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 43721b26884a01c3bee3086555970ade2e44bee0..ee1ce50b6bd5e11a72827db24797d239c227a51c 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 3e1e31bc791e4b731fa845be627dfe90f426611d..c3b699a360247c130f953ad6a5839045552e76be 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 2f0654440d08519fd375bdba822dc8384431ec34..f803fb6274648bd82270491e14834277e1b426ac 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 c144db6c1aca461da976d5e5df606d5f94654074..4520a9b6f3954994b4cef0859721989eaea834c0 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 7e09b03cc6649dc3ac6679eb127c61e830b17ad8..0d64191d79dd2e1117ba1bd7dcc8cd985a218c07 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 69e891db29feec9822c2ce1d017a28775a7f2873..0a22da1f555bc285906f54250954f11ebf3af95d 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 5d3295db7ef8c0efb1df222887edce11aadd6511..26c5ac066b4a1f6797d1909fc3f945be164d5149 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 e679317f06f3201e27e797bfbc61775d2a291f5b..eea0abbae4d41eb968ca508a7ac553eb6df2c6c9 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 2c1f3dd79e1b2c9991560c5a1f53f5455f605f76..9ba226607d1feee2156ffa54adf729e699f56edf 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 8468f4c49885c0d48616b15a0aeff56271089567..ffabc32b6eeb5d293f55125905c514bde8c43130 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 06bab04aaafb3d282650daa513d4e164fc0e695a..9cbc5505aee6f3b2fbdd028f7ae2acd05107016b 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 0b44dc865ee0bf1cf4b554225fd48e5a250340fb..65d94fe386c817eda9931c454d464edfd72161f9 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 b8a3897ab8f76dc5e22087ca749ec846fabd98b5..0ab766065d6e817b19bcfaf6ecc911a16b981117 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 2c17d9e03641e08cabc4e0db2b8f595d1dda6b27..03ebb02e4e5136ffda973dae3d651af513c65927 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 97f2b20d2a47603b71c9a00e7c9cdeea3caa6877..65f76b8bb805b3689deb24e5ead12491f8901649 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 13eaabf594700236b215eab3c44b9607185e0a45..32842717bc6fad93a6e187e9fe34cdb93be8e07b 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 b5e3233619cd3bf8ccd5a3ddf6007636d27a972a..f1bfab9a3b12740efded74ba6194c260ba4dd81e 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 620ffb1cd4cb4a5287de04c6dbe56046440d09d5..29c9f347d252fee0aa09e7151c2b2a421dfbbcc8 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 3a74cf8511b796dae55907328485e52fa868a453..3c3112543594bb8450927a5fc34cf3916e1987fb 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 f8b772749f48147d030ae319ef5da8988279cf1b..df502a0aff0dbb9062cc88557522cd399a4e13a5 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 a9f81616845a8aaf8ab9dd3fa547ad340f380917..18d5596794f6d65becfca6248c480a8eef1e6727 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 b3d765c5ef267984257011263e4c18339cf5640e..e17e69c1835a22c5b08914ea794b38cadc63a57a 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 ee9a10d37e3687a73d2a23b0c067878799edca6b..0905b982cd830a2f9de448da9c6dba2f93d3bddb 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 a7b229e98aaba9094648b7ba768620909d18b96d..b213793a2c64375502326fe3ce9f273fbbedeb10 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 9ed01c71468a5c80506987842c6e7d333f778e9f..40b09ce897880edd450c99fef939d8f5fed55028 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 7293f159e09ad69e0eea176391d0bda95360c5aa..af35e81a2d4523996250adb4f54de031a5a7b168 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 26f59c556c0708bd347c3dac8544c186d1da4ac4..4d4a6161057cc5cec1d2133459c51982012b6273 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 a62dc844e4f39aafbf34d46abccdc596072b9224..6cec9f764bf647c0408b608000e161e78ed646bf 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 56cfc6bdb76951d46a3bb8ecd0cc6937069940c9..44b27f31c1257325c805dafac6dee9e1d3784b46 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 22e202dace1a84d3de1cad7e969691804f8c6883..1ec158ee7e3141cf4265ae97e79cb05d8066e4db 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 e40a10daa5d2290251be2c44d25e9171de77e020..e81f9822bb91eb9d78865961340df424aeb0ea05 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 904627f431b13c2dd8b76689eaad5da5eb45883a..e9ba4e6219a9ba9dcbd951c88cd79abe99780da2 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 8f814df8bcf823c2a759dae7f7a3158b36a8d2b2..61252ce4e807ec55794b9b5de479d8d15ab783b4 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 43daf790b77cb094c426c675c2c51fa80796ce85..0a73f5abc66fe2476948bd75d7acdc6b51489953 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 8cbd20d45e16083f2b22fdb5fa845a52c2d76626..bdf3805106df3be150de90fa657d6e6e7ea7379b 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 f8b5d8b2460ccbc42cd86e54752e436db28780a6..6bfa9a9fd210bef3fee5aaffa7c2054853d7175c 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 a0817562a73ae29b77bfb3ed1cadfc7a0ca5a861..48311c5820a996585f30b77e245afff9320a7a9d 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 18be936b08ebc611aa960917f1a74fc01db1e88f..98d2c4670181ccabfb6d46316891f426c83f92ae 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 58be78f0175916c900fb153c79c6e41521ab0340..fd3c9adee427f85feb43ab381e947f3c85715dee 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 b14ea722ffa287833bdaa1a1bd810548deb47f74..3bba9355626b5bf7954b0e2aae1c65551715a5a1 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 fbb9b286bebafc0d76642afe1f9563b924194cbe..5792d0d407ba224bc4b42c78af613630f341ff51 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 845b2ef7dabaf6cc19cafb0115175bd2c5b171e2..b256312d91a806f87bb397056269589e0a068a4d 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 0c9d88c8de3f91eebd6f3c6e4a3832a5cd53be1c..ea3d7dab0f17375a16a2620d563a2d4d65a3858b 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 71fc3b5002782125f326613ad863dc331ac6923a..e8a488eb1bfa0c516642b1c97103e05577058d50 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 2bd8dfdc960a33e8b40c8e8840f4953b7c889d0d..d5d24301b6d73d9d17bf94a2d72e1b6f7cc8f5fc 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 fc890cb2326ab8c5a0d42d0b3f45d9602e13d98f..e7fae5631d87f6a121002cbe26aef781256a9777 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 12d4fbcd52bc4c8e5b2bc97d1971065ce2f74d46..ae2e38fdc0fef721eac28b641f3718d8affe6eca 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 adf99ec3623ff49ee83fa771d89afeb26bd1496d..f469107cbabd699ff1eecc03da1ae85ac0f09313 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 bd37ee29cc7a097335c99ef3af6ee8f09b7678d5..d0fd0a3cc7f8e90eba7ec62f14e1142b7193f828 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 ef9ef1e129b637f2e832c9e1cda1b681456fd70d..44996936e2d28f85535ebd61b57e15d515ea6d18 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 f6325cc8c1e6d993f046b459e451857bb5c1047e..9f70a13aa9e8a32cd89cace82d9ba8e5a3f6b94b 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 535ac54b3c02cfd24e51febaf353316aee2b6b05..0b0df9b375beb42805c3f8c1106472eddfbf60b2 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 6e90dc05d942438ea300b11665dc358e15555214..af3fb9b57f7300bbb030b2a074b82eba772cf741 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 4f3e705cab62a3ac3e102cc9e5580553064dce4c..1edb0fbabb202359966d0897d6bc15c095bf800c 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 adacb0ab3c9e43cf29d85bc2e2fbd18bfa24b825..32d69bf3ca03c3f0485e05ebe42ed32c5509d816 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 4040f72ee8665deb679738430d8863ed696c9e38..b950e41dc19784c45e5b2204557ddfc66bb83efb 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 19e1e7faaf1b7332e00084483530c7b5ff1c301e..665261ffb21f943faae303af5a60f19fb10c741e 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 a90a825be44ecc1527dc58cf9f4e58eed539fafb..ad6a9f7c972dae03d39a69d3ef2535dbf5fc2566 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 85cab3b22790cba2802f917d8bfe6dc753692ca9..2ea9c27e49f6d87d5d67f5d5aa11c4d708ead532 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 9fe7a3589a7ba1618442c729a671aa6307785e30..438007d0028d86eb28cfddb91ae2dd6c14a1503d 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 c56d70734238556cdc163ca4de6c1ab73c7a1b0a..3066496fa459b903ccfb2ca5dfa887e002048da7 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 3d335c88674fb99db05df669f47d9e4f88843f65..e6626f262df48a0d5692e811fd01627c6b860115 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 d1051f688c9a5177dee63d28236468282af6ca36..57a4834c90eec8d26917e4099bf08e8a81ca8a0f 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 8b738c3481f4364056d1af5182ce9bf55c728625..130aafe8b98b9176bf725cd864eb5181e3f85131 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 520970f168bf6fd8762297ff4971155c497c2149..138720e4785f6ba5c637d1771cd5c4f83cc355c9 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 9de73ade421ea868182a59bbfeb81f9b6a79a9b4..41f20ddf4ea0d82eae1678d6b21d398bbef65351 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 4601171b5968b8f95a975ea5386c689cbe54447c..dbb5bd25052722cf792ebc4518baff071703484b 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 88fb38bc1dd1aedf2c6f0a6492be058457132f8b..116efca71547395c49d3fb1d452cb40b41102c41 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 c9cb51896ee90a395a57b1dfdc65ff953a17ac6a..ff55aacbd44c5b50e4c8afeff3b7ff2559b051b2 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 8d216d07e396bc248f3e12996c41c446db6511f4..6ec9ada530cae26a1bc50fd9f9db46629d3ab7e9 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 861be37089736b2a04d5ec272c16e6fdf998186d..3a0b1e0797205a7d556f09bd326983b69dc226e6 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 d13c6f92d306ababcbbf369a8e211474133b9a65..b30bc3c7ac42e9d960925ef06dad3682a429124e 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 30dd6eff2d599c71beb5865c1b7aa2e87dc45e28..e4a82eaada79381abf6a79c648985c1d59cf83ab 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 eb27846aab2c2026fd85a7fc69d79cfdc0070084..118bc4c29d85e7dc358a9fccb503aafac0e0405f 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 0fe11671373f3360d43698985f684613b6e40f7c..731e2eca16114d1d978a4e601ef7d0d2231078d8 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 1430d9b4033a84f90bea171f7e7bff893c4c4a2b..6cd8132f8a9870f499b7f37ccb856eb1ca54eb05 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 055abe0de1ce4e8aa4a64a7d4eb82e69fe3369b4..05f33740d7527a9a784eadfa7bc0ae5362ba178a 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 9a51194b8ac5021f6d9f9175cd1a71df7c77e9e1..5c9177a9c8791220e1ad0fb22e0106e7db289595 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 ff9cc22d13b56591cf1b65dec35d43739d1e45d2..0fc02c4dbe2f7fbbef8256038eb6b48b63f8a98e 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 f7f0c9739d8c93a44bb60f5b38aa50f3ecf05e70..5517b04f5ddf7145eea06e63d895740698f7bb8a 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 40098d04966f373cce37383cf2d7c6da97f6d112..c6de2303c6c8cfce70bc91b972dd30a82a20407e 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 8755155153041479d625a02faec3cff3b8c7cc25..1338906b646e3fd669a5b3b6258166e12455840e 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 f179de2f9263da6303e765a134b54e2033e4ebd2..ba701c3b6897a2ab995133beecc9e36e7daf97a4 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 8e308bc589ac746a986f063cfae7cc1f539a3384..624e164625556a88586001dc0ed37034b30e555a 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 d61c178831aa0732d31eb76e56c79f9d40dcf57b..33fb36d0b8cea54a890cd670702d9c84c7eb1c2e 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 7dc46acd058ad53e1555fd84dd373c3c8bfe9526..53cbd6c7706e4047bb9349d5a66ac7ea7734bf0c 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 e9ede8b415f993820fdcdfb0c6b7f1b7d2504abb..af4a6d1ab409400026207252d41acab808fc8fdf 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 8a538adb9b0282641a4360c96336f572af29d318..5212131764de638026dcb546d7f2d0a6bfa378e5 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 ab64978cfde38db44eab650f4ebff9ece16a2b2a..71443797848609312f978bb70b7a05a90ff52168 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 2e16077b8a6ad8173257a68f3dd5ad591719da8f..0470bd113a634021dc59c46ff4efce8a38cb0f78 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 aa5e4ad15d7692f867a8cbe935ba3f7c74acb4eb..85d36367221295bee1227d1ec553c2b1d09a2a26 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 6c920b4882d5721a82f4cd91fc958335079d8ff9..52d591ad759b47ea09e933c8082a3d190cc7ab61 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 61f34cddc1d99b15d3c442ca96a7aea0add8c512..d2c421047ed07b3b83d848c82aba67ed15afbb68 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 8c091f6bc08046482432101a908d9936fb90ba94..aad27a88c99ec8d66f561dc2169d2092b8ae7cdf 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 5c7dfa454b428ef36c41a3614eb3c86abbff5913..42a03a46754d03f0012f1660226eca4ffb863f5f 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 6762e9177fe43fe807f697b13b22150cc0ac9889..e1042e7eea604528d7f419174577de62c84ab4dc 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 a3b8bc166a01a366d63ff6cc59b0c0886ecb1ec7..c3339edd54a2daf39464bd69b0caf6667f93edcc 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 a432202ec0e93c1d2f23cc9114c81e2fc1d0eddc..b037ff6b828764199347cd48feeb667eb24d1b8e 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 dc0274eb0bfe431ab7a154399d5a351758aed717..99d7e8b7cebe14143cae941ef898892804f87725 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 01882190920194a423f71035f75564cc752ba425..3c2fc89d509ff2383b0a42f39b03acdb5d37f321 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 0fb3341c61e4bd83dba88d26e3723689b755ced5..ae0877ca90db07b7dff8a38c8a408b6bbe3cd229 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 31ca260f7ce7f2fd28eacee9752df9a9b213460f..c368fc2e5ae7750a19197f91efaa8df805b8155a 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 55f97999defe165046ffc4c98ec75329cf8ff6d8..78d6633e098ba55cd1262ec9c9db704f7dfbb943 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 14cf07839b5dfcf725d3268d67d8034b48a99a7c..538b7980bd70d2a90181c9d3ea565b5ec2d74f9e 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 e199931b55bd6f993aef1f9b93d2714b51c124b1..e7916d2bff5895b143a95cb3f05555099cb3bfa5 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 37d1393eff0362818fcc17f5042415dca985c13c..ad1e81203b5c6b870df2ed1172676579cc5459d1 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 b4484c87d03070295459d913bc2f625ceb18d110..7c7767f0d43a4933279d2ded4482c317f404f74c 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 d40315eaf8997f0b594684c776fa13958b793160..b421ea58feda02e06b20af0ea4f6f353f2cf2c52 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 8a5d5d19dfed81015c307c2cf675400357f96663..0a0f17547f1ded4dda6b79768a2f51af05a80ac4 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 58fc31b095289ceb5f90cd89ca2eff2cbd555294..1de7baee54733db7a857600e19214fe7333066a1 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 53a1c4d57ec499736473cd87ae4264263110e5a6..8843116a14fdd40525ea3a20ad2813f74056f284 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 01cfd6dbd2564a15c0ca5da3ef9d9c1a424a8789..24694225659d33bac1fae7a4d8ebb3518ebd7341 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 764c4916d8764dd62816e5bf2e4118e17b22ab1e..71d695f96f4de30bed3604fe1bed6839e77951fa 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 99fa037bf6e4748f46021c5883f91f3f48584b42..f508eaad7cdfd458ee9f1e26fb337effecbeabcc 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 d549b2674e85ab25ad91693cf763552ed2ccb808..2144c1fa35600546e2f3a38e5e00d43d9dcb57c7 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 5633ae3eb1cf39f32172741c087127d1452c3ce9..bb7e3906dba6072a83bbeeda437de40dba2d06b0 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 8ad975f71f02ea510530730e536d59b51ddccbbb..71964d71e67de593e3748e30217d85099e031728 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 5f605408b7dd766085a1ebd757ff2cae571b78a0..d403c4d546edc16854c6c06c9d02d329636f34db 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 d44b052540da92ec3fc7764bb1441a6f4829f2c7..63112830ba02eb9308cf92bc00c67c78b29bbb47 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 50835bb92ca6d5dd21cd833773857033186e6cf5..e24043f02debd75c88a0ca44f1ffaffd1d8c112e 100644 (file)
@@ -176,3 +176,8 @@ div.footer a:hover {
 .stableabi {
     color: #229;
 }
+
+.highlight {
+    background: none !important;
+}
+
index 7dccf72f99cb56627fd8940374a3db7ad1f31e94..de78041f77c9ee1853e0793a8e7f48e1074ae0c8 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 5d82c672beefcc7b2b03720e94a897518f55d11c..716c9e472f4bebe97e3bb7ec8dd230aa574b7967 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 2a95fca3135f4736fafe36a77e3ec0327a1e00f9..dba93bf3a72b3e8a066484aafc38df1ad23bc43e 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 969099a00697aa83c0cbe0b74709527c9ae80279..1076c1f51b7d194b72293e1969b972f39a5dbbf7 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 78e9c4f99ef076925bb9698e5bf2195a2c091803..bb449ef1cd30a602584f082de9f6b6f42a22ad9d 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 5abff1b3989f06260793ecc804c680aa89f270f0..1887b85b607366951216b9032fe225a994da4d98 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 e04459b2d990dc4504ff3db29edcdb19f284d9de..ffd16aa97a15fae9f3733bec2ef080363063fd8a 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 7e014eff38f367b1a748c1ea3de482ddce1c4910..2489d75b16097bf59c4006f4683ab0b58107e92b 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 813c8285f8505071089d06bfba78e1e902754e16..ddc08552ed70c67186fe09f7382c6afb62914e3f 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 0d51480177d882f9519a0d578c324fdd72fe0921..b39bdf4dfb288be92a6bb5120596dc681221295e 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 351ee52b4ef485f11d90187033317ded481f31f7..4195c7e892f1f5f8ed6a67cbe1913134a74a93b9 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 9c3c1435c374c4a52b636d7ca85a261260419aa2..d440e535182850d07aea7a701a75fa6ac3a17155 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 c157f22e6c3edef3baf441668d2c3029d3cce852..dd9c7cd7315d6ef6934254f29dcdfb06a97fe5db 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 abf30f020dea0060e6fa5a4a7d31ae36e3351732..d73cfeb34f194682260c54e13c62c10f89414201 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 c5c13438439c8a198435c0bad245232b45541a65..214032917b477d82d9e4598454ac5f94a5c02381 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 9ae64b0cf7e26df146d38b5f867a3b0c443de7a4..261a3f36577b99ff0051b88650d17d3589cc42f1 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 0954ebae065230d24ef94c68382dd5eccc8327af..52ffdbe0630318bbee61e8dbfe416556fd140aaa 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 f7d2a0ac2aa59a955c26575bcd6977a985c2d48f..3714384eb66c8075459fd7ca01c09f0e8a28af8e 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 479542c17298fc4f31a54b70122067bf2e5645e6..1ea22ae5cdccaeb24b34929320edd64bae995287 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 c7210a01346b35b02c23e460931422073015f4ef..ec744a351d69e23004a1923a1de88aae5ba47475 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 ef091e52754708bfaeb65349e6d05dd31b7dec97..05c91bba59479a7050677b43f7067ff7d77b6063 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 5da1f233466a02cf0b2a66631f49fcc5a599775a..4449d4f4d4d72cd7c64cf6d5035d1b3d19b43927 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 02bcbeeb7f2bc228253338f5dcd7bcd0d30713c4..c5294786c219249a1eacfa0bd9a178f0b55533ac 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 2116c106dea31edb97b31279d20309b21d53ed55..7520d6084638e8fb65e83aa0ee7cec9746f43128 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 10bb29ee8a0e603d6f43d60d10d395928238dbf3..87462f3f84b9a5bcb368f4fd50f3343ae8ea30a1 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 6de5bf57b3a2efa553d29d92fb13ce6accfa36af..e55eaace26afcd2e61e12c89f02ffdd07b169273 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 f3c4a91346931273055dc729b647a1efda52c05e..885fd60355b3dbde375401be8b0007f8b1703995 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 9d99074f227662701094574b28be1901ec940492..b8cdcf1f52347675983571eacdb7145b4e36b345 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 569e5e925fa98d665de424ecb88937c0c3b48728..fb4558b8d086dc944e799482f26de3de9aa83391 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 cb92e08d6f840d7da411dd775964020a86908762..093189e8ee0aae8f56147ecb7e7436a888a2f8f2 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 e7632652693bf0b02eb4be7a2c0954cb4755347f..4ab16563e8ae0b1d0bb66c4d87e2687a3e861413 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 3966cb43236535095e3ae8120594ab98a60580b2..702aeb4c312d5740ed76585b14769fa010fe5292 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 99411305a59f5c8b41d0fde886706447e1d9a775..044d7beea6cd9ca75567ddbebd4c8b33495268a2 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 582250450d7c546cb2c5def1d5a424d0ec8c6977..baaf797e31d5458a536627966f4a94f55cf882bc 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 094eff87dbdb8f61710244cc06d557d69a245156..2096b0b634e35d8359f0223ce5d3eec09491c056 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 7d9bc0d8af0d7edda147b0502f23e2f904f48541..1e5c9d1fbdcf476a0e5a1d86e4cb58b70fe5321b 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 73c851dc93e0ce5b8b081c83d09087eacbd8964e..8fc2f6cfd4ee78acc835222ea32bc110d5a4cce2 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 6afba0992b136f474758268cfd61baa6afdbaf30..4ff79f29281fc1d9a4012fe0b49a67d9642ba363 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 e379bace37e8d2a6f03e1e6aa0f5a8f4f2dc17a1..6c1e0c3aacc8544863f605387a1362403c56d1f3 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 56e6ec18afea2696063392354b446c520ce01c85..8ecf38a324121145cbc0a2f912e3154e5b6f3476 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 80bd33029491804665c9bff2100f00d59427fb14..ba90aaf676c55cfb47786642f84424096b8b9f88 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 966ff1f6e6e38c3c5c552bb22cecb6d468693e93..00c50933dc98f980dc14b878b049ff10b270d4f4 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 4c71861723213657e67be170667fd3c7dd6c2dac..1ff32a8eafac2ab5bbd76553d0402c9af74eaf24 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 daa513f1514b92a2279f64379eb7b8f9f2a9a694..31843b5db08c1ac0563ac40b7d4964d3b3aeb63c 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 4d286efe34deb29d27224e0e64246dbab20ec564..50d9747cf95fdfed932887664b2d4eb2a7f54be7 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 bca4b3f8071cd9cc1a8548f239338ada621201df..60851c1eea9c9865e106bcb48c0114d67e1f9b0b 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 892a217d34896ebcbfc0d048fb231fd66c391feb..89028ef378e23edfa3a73e896301e0de95e7fefb 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 24e7b8dac61ce52c5e248f01d363bb928e243f73..0c28f5c06d1fed0f27f895fd474c1ff41858f950 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 6000b81ae4600e3f5d80c7e3943490c98137cfe5..0499a74280d0fa3d71a5d45c002be4a9d5850036 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 f92148da0707c209295eacf87112049960c91ec7..9c2e813ad0704be91b7c43ce254a4fac24c20626 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 891000c8fe27eca88e55d4e92a40d6a303013c7a..c3ecbe296f900f7516287fe77788269350f86f0f 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 09c9b21800a3134b6c12b7c30e221988985a7ee0..533dd75d2c7902a8dc3d1561a0deffd04daa4f7b 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 88251f5b6e8b060a7d790af262a84fea6bd59096..84a3337c2e5289fb8e50e5ef6d8ac2ac78be70b2 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 f89bb6f04b5b1f7cbf2d0555d0d6e4a34221f48f..fc9c9f1cc14eee1f7399c1a3c7599c139cebbd32 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 6e39d4aee3e8b29fe4acd30c51ac7196d7c0d6da..c0e0443cf2330f9cb0d9ee358f3592eaac3960f3 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 b07e75d0e8cbefdfdade409e4f04cb09eab70523..13fcd8b8d25b3e04ff58ed807522c16372d7c67b 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 05ba4eeee3a5de44ebf3c0366059303e44ffe6e8..c719424472e534fa7f8fedefe467ec3b61338c8d 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 37157d53ab4858b1ebdc68dd3e561d43d38dc92d..0d98b744768a1c2796b71ca1561c0a989f176d87 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 374923dd135135bff28087ee6c2df1c2a6a2203c..f84227be4927020b38ea9d7716fcb79aa7068685 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 c5ffad408078f36cedd6fb09985c06bde0b27d61..172a463ef807716f993409547f0beb2ab648e5a2 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 73425d9bbcc9640b923ce7960a0412400cbf0224..8fc253c18eb981d1d6079ce374bfdafffed21261 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 660b7e7e6c9a9631f1480971ea2d59f06128c24f..4790bb4a35f02df055c0c3b5b2631145b3cc6540 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 3a92c7d7552219a08c74e35939f20f5de85c6264..71bc6fb2eab34fdaadcc6c140473540756b23aad 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 176a846698448d31f8c9a921707c7d1d0db2b7cd..c48c5bed736026301cd64e26a88c3b178ac0a491 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 4dcb6546be000941e15dd9ab1ddd3ab99d27ebb1..1feba4d370070d83068acca374b66cd269bfcadb 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 34f6bc16ad87b69743d0918bfc5e779d25d2bdc7..741aaf27c5ee65b5e8d775cf3e6a80195e690ccc 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 7eac41eec028129d90668f3ebf845cb5ea8bf179..3ac314c0cc667d4b8ed82141e1fbf5a482173f73 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 e3a1d5ed60e3b8686ce9fce40c7f12f2a585d517..c453f02d8cf89973b39d6a46f332eeead621e4dc 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 a05f81cd9de6557755bb55bae664a8baac69df87..9564d01dfa66f77595ff1ba98ac6a7a52ea531fe 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 dde980b68f835e73e53e2c10cbe8f126946aea53..f58b5ac50235dc925fad2f77c5a94b216b6d115d 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 6b5e96aea2c9caa559393f015ff1124a7eb41b0b..c88a87cd0967c87f22bab48d5b24e6306df661e1 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 ead4039b2f7db92d8d287ffe8b95061f986cc108..b2f5304f772121de9c60691a9cc5499cfd07a168 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 e6389d82bdb46ea98871b95e67aeabc908d1263f..0cca8e36a59b546f301a3088c77bbd07ad60afe7 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 8170533188c370436646530bf825e8a99a07cc89..396e6aed5673c4c6323ae7f8e091c0ff9ab0e3a9 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 7747ff41bb8812ffc038c442384155bfcf779b37..d712749ee59cdcbbee0519851f8d324b42802dd3 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 922594f17243310fe5c4e1560e9fa797c6da2395..668fe1451b65ac034021e08671402f789393c911 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 640f787c73165c2d405f1ad457a2260836107d20..adaec1de61bf423f332c8c5df714ee06ded596b3 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 26d25444080def3ad38323288eb46ff40c2dae2f..189c6d5b4a0aec1ae85a6edb244803c004279399 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 e8312a9088ffdb215b7a4bb43fe30a81f618895d..ebe8ee7a838a38d9692bb919167cd2194a5d7bb8 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 64c0a9abdb67b11d865a7327f8cececa3ac0e767..0cc0c1d530e03a64ad50ebbb89c54251759c14d3 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 3a45fdf49b23788eea55051f9e35c55a3643f4e0..972b94ab491f158703e1277254d78c17a9e3b0f6 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 4cb6d0de27104b8dfb7e3208d626d4393f41e158..0d860784bc87d11ce9593a5dc8372ffa03fb41c3 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 4e10cbe41144f0bdb55df3e9e61713f0e3b199b2..2866e9f349288a4059e7bacee8f0ad9ed886d068 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 8ca77e0f308a40d4e0fa4199b286cfa91a43b763..4ed566b48e67e8824a6cb1a62bdb7eb2309a97c3 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 225b9d1928be43e5a6623f3c754d68dbda0f61a8..751f85fd11f59a36af6ae728648770d0d1579450 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 9551e7ae9f679024d2697a5ad71ea2b362396dc8..5a3a47f96819fbd87208b83fe1b2512c66d3406b 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 9e74ccdbcf40d720957c82188aa2c338876eee64..8ff4aff0ca517e1f88139d1bd4c634ccac05da69 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 b9719cbb48df0cadb665263a01e71739a20dcac0..2f9421829e573d6baeb4c5334dd4ea094e54ef9d 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 af37cdf0c67e4e45c6c68c02ef31149ff3ef65cd..f7e3c7f8d7c98d93db6310659e20ea9ba3f0728c 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 10a9ffda24a2b72490d1fd50b9f8d498e3326c83..d0ba7d6d1efc0061d34e92f9695da6e88e53e463 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 82fd7d5c4da20cc7bc31aedcf89633f145c6ea81..b71d1d39bcda87227165df1c33c925146d6d5807 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 d4cb11e6dbd78ab3f95e1e6dcc7b9dd2e9a9d715..f03a4e31d8d7e2216597239e8fcffc20b5c44638 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 b49f86fe5814240641db8a5ab54e209a7eb709ef..86343c8017bf0a891d4fbdb449dbd4a5c971576e 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 1c4fc48a12935993f747e08cfef583a14085fcb7..0afcbf233e7c96b22c75f52e75146e80c10bd9e1 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 7a5e78d52bcc5db0be1baff6cdad41e172a5b81f..22299543a97ffc1525a3b1c778cb158d6c6430ad 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 cc43296b677a5b995899bb60bbe0e632163e64ae..0dac1103d98db0af1e9027c41fe921136c5f6396 100644 (file)
Binary files a/Lib/distutils/command/wininst-14.0.exe and b/Lib/distutils/command/wininst-14.0.exe differ
index 382aca8fc12e610ab5c58dad76c8e19ee96aaadb..f0c73731713a449ae048da5f8c1b51ab7feabbca 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 da4b21d22a9aaa7516dd0df3997a0c063253fad5..0b1fd19ff64a4d42f80cf3247e7b2fac1b9c7d21 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 366ffbec9f814085595219d0a096d42b7c824079..8f62b1a848b909c7964b375c9dba993b4dd8934c 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 6180133994f8e583d12a5bdc4497e9cf7b9c632a..01acf2375f63bf0972da16b9a180bfa6b21d5d50 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 3d14e12aa9f6d671e43966fb546d0adba0bbaa32..e171ee9c4dce4f9a3ad31d539d0aa52b705e9a90 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 dccaf77e3e1806304ad9c4afc3f073eb4667c2ee..964aac7e80013fcf3e1b3ba0bc094beceb122cb8 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 094a2f0bd0174951e7d763f2bfd7907b1a297918..92d14dfee72de1c6f1b3882ec3f2bd6be3785f7a 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 409472384d6aa991804d4814933a67c7502fec39..38fdd80b4a495df179454cd2a020e63e1e56b549 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 f264191dc4a4452404e2d38bfa11bfdfd6b9c5c3..2226e137e1a1c0e9594edb46ccd60e956bc6d841 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 468ca9e3a0685f0c37d4d15add1e9011ab8b1724..0fc2231e5cbd2949033523b101bfd493ed440537 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 a892012c3fcc015e665d249161c3e79bc4338ec3..aefaf57d00e0d2ec251c706e91a4803c721bf98b 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 8c9bc9e44e24a75a85d9f16b874d3ed875fe5fc9..555b17256061942e9fe29c5ffa87303e18bc4e52 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 5080d81909bb900a13b57a4af3c997227a126dbd..a759d23308d3026d485a46b315b796ea1a719f89 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 2334208812712af7cf1a5076bc14e00bc5ee8ce1..58de1033c13b76048f543617c2b6901e7848005b 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 809bc9ab3687a2ea1a49b143b66b13126e72ca8b..c61248242be8c7a2157df12d6f62ce824d31939c 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 c0529285f60511dd9cfef62560c92b1266e2b3f4..cdf84d14129a6233a774ab12bf8f08fb67036b14 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 12588335d943761579db89ecbc3761dee48859de..08aedf970587ccdf428e96f11362c1c15b1267c4 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
diff --git a/Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl
deleted file mode 100644 (file)
index f4288d6..0000000
Binary files a/Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl and /dev/null differ
diff --git a/Lib/ensurepip/_bundled/setuptools-20.10.1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-20.10.1-py2.py3-none-any.whl
new file mode 100644 (file)
index 0000000..9d1319a
Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-20.10.1-py2.py3-none-any.whl differ
index c28f3452a75372a5a61c068e975ebd44ddd4540f..b8787d19b884862265991e7a694b00f93f7b71e9 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 c41b94abff72553d0ca0f0ced6c192f78f4bab07..d2b52066d920f6d45c14937a237360d4be9a3a93 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__()
@@ -289,6 +276,10 @@ class FileInput:
         finally:
             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()
@@ -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 45152e440d52d176c9902af71e81ce777a1ae12c..da4479e9d0d015114f8e02b080092deda47953cf 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 07af37e717e47f3a619d16ea4711ac9f0ba13e3d..0b3e89a3a97f057afbd9eb137ff6cadf244d1b94 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 43e6411b735c2177d5cde5cdbde018720c6618c5..b781c63f33a78a7ff6358daf9f6a8a40d09b7900 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 80c80cf576e75d31ddc21ed79251eb8fa20c57ed..350313e87b32e275ac2f296b563f6f75845c6073 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 ac5e667dba77680e2c6bbd337dfda73090dc10ab..265ccf99f285374b64724c399ebdcd992c023dcd 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 fda02b7016bc8f510c7141cc947a6832f470cc73..a73fe387f8d335cf32cf63bd1a8ea4dba773c803 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 e1b71abf37420665f5c36a2df9c1f1e160616aa0..00620d1f853fafa764631f22d000a59b3eb06ba7 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 b20512dfa0f3ed87e8b8f4c12709fb89d620e55b..ff085d5c70bc74a4a7d4be4fbb8df57ba0bff244 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 5ff599dee1abfbefb827d2e38571db4f246e27f8..3a50eb8e7f2ac3d3af638f65b2bb298978ff1869 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 90e02f6400ecc98080e6aca17d4cb4db8d824520..0c36664512b1289c6f594a6ee5f8cbb7bed2be35 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 9f313496040aeeca2161b575ae7be98cc9308ab7..02eac470683162ebf644dcca99ede34b2eb112c4 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 250422edbb1517427918847e0ae1e8f8f0880ebf..d5e217dde9b78e20d9426eedb1cc13f0dd9bf225 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 c4765163f8062a41c6e08d90667bbf203171ddbe..dc2a1aaeeab74eedf6a677da1b5c44a088714bb0 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 b5868be3fb839c1c96df13112ef37a4f8822d87e..9944da3e7084c7d766c75c4bfedc291bc4f15d90 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 5ec9d546fdf67f748c75145a712b3752f0b56088..84f39a2fee8e55d4aed872d0b066fe05d4157735 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 251a84d083f60616d5cf4e8364349220bced5767..8462854921e9c9c4fe2d4dc1c081b8301045a1ba 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 0eb939b34cdd266ca798afd762bcada53c112e70..00d5005b05cb11dde2970b5b6cb2c7f7f40d34d0 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 9e9331940f7246386018c9f133e2d7298a6f93dd..b8be2aa746b6b52c030e991870877848c1d1c2f3 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 1bcc9b68143f6a7ee93dffa77d4915e32dfe89fc..5dec68e58088b7af42e4009b2f3c4999e44a78ab 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 b5663c25cfeb66240373835857e37c128b518d88..7bf74c0fc4ad3edb8306e8d725cf335e987cbfde 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 2665a1c630bf6e732be7442ae124652ba05c5302..f2ea22e7f7098f761b463248802d4d85c1b0ebe7 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 77ef7b9a82c382f4c772f1e95162f1f60c2d2144..765d53fe92c831bdcb1763f247a71391e9756301 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 04c1cf5a273887c3f09723d35a5a5271fece9786..1c2502d81822e1c1023b198505c713d2159b8c2f 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 67d7f61e623b4289bf55de2c641affd63b60e681..b66be9e721a51595b5f021e0e4bbe78a61e41e34 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 d876a97115aecbd9a711e4cf4674eaec71006ba2..0457c4398923b5a89aa1cec3050020c4e6dd2f72 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 9b16459d546f8857445626a66ff6bb75143b8b9b..b7022537e61c76a1d39462549f7ac14e577b7008 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 531efb4b3e7bb4047bc66f4ec2c22b39d4539fa1..8ac1f6097a84957d48c8e33da700abe7c53b6bd1 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 242b08db56addbf9f30c465c135fdefaf07d78ea..cde8118fe6b9d7a487971caa3405541414ac0d5a 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 2189fd4cf0cc8c95ccbea72af82c5295d72d91a2..6f739c42ab3d077f517fd1580675e7c20e9698e4 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 b31596c2eb60bf1b70f4d237d17702726f9d1536..d0c59c5fcf9d5349f94b019155ab9036306042ea 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 2339926ef337c889b6d3a31292db3f0e6c58f541..dc7a28697c19882eb8ec4bfa8269ed07a695599c 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 1bc953643e1376b079464f52dccd072960cd644e..845c92d372a013a6c46f4fcad549410ff589f0b5 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 3e24518a0f7008211745381b161af0cda3c0c9d7..58e62cb4e23e226c25cbfcbf6d52a965d525b410 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 86fe84884fbafeb4806e1f6914fd055195863f84..6e351297d75db92e85d075988c9ad073416de0d3 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 3a2192e8afce49d6fbcb22b57be7da47ea3daf97..e4493d1205889aa86a87c3d4d279fa7a447653d8 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 7ca941ec29024cab9ea288547a34d730f8ee12b5..d2a3156dcad747988411dfc8264da34449da936b 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 68831236b76bd93a1047c6854ab2c1fb3c1dc037..b063601b2709326d330851be7f1389b380d6501c 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 b8ae5eeefe338c088b20fd34e84dbe10384588f7..1f0baa9c0df6af6752fc0a829e465d40452fc5bc 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 f6039e6ab4b86b66a5e25a12ac362adbdb9137c6..e5561d84a65e853fce68838fd137c6475eddde45 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 9aba4bec9366b7b093e9c108e0f1440c48ac0ce7..95cc22cf68c493c97d0f1f7a5825c90359089f80 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 68e5b82ad912ad9231d80fa819dbbbf7b82a4a46..02d1472240ee0c4e3c5db667786bd2fe06374814 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 54ac993e881e148a0ffad6606009708c041cbb1c..18627ddd23102aab8890b18e5166df1325bd2ce2 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 64405615a0c97dee251a207bb57c4e7d069f84a4..c68dfcc412413f01057aa8ef037dfaa86dbe13dc 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 aa33041e7b3edb1148848138471ed5ba2c04f069..48105f2aa1bd0b4fa953722031f271d60cddfb5f 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 6f62bb35fef0ebb71e0fa9edc931e8bd6381ab74..9eecbfe967230f743a4bf2558a3fe6c5a4c3991b 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 616b17f89a82d198c43acceb2dc88e6b9010b9ff..97888286880a05d91d647c90944e54063b7761e5 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 11af22dab9ba7ee3955535e6a787dc12445bafb8..daff681e69689f4884bb2f9d95a94777d80d309e 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 1dbff2605eaed031fc5cbb149d37bc8ec84f7fbd..4525b3f78e46a17e5ea60a9f46e626a8431afeff 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 b65bec7adf677e0b7f0c4222f4f4ca7c1f851bb9..e830eb64cad8bd08fa996639c6fd5213ca0a4c4b 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 7469a9d6ddfac14eb3029a2a362e2a13dcf21aef..1f900583826a80088ba9f72686b0cbdfac574208 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))
@@ -1311,6 +1311,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 26e9eb2bc69255a400a3c48686a1f821cab562db..d596489f42d3856db96f507e1f04d410d154b58e 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 339750edbaacd4c6e3cb6e369f87489c9d0cb442..ff76ba340470729f7e44ec2ce19afc7cc1ca931a 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 b1760561996ed1d8fada89afaacfd66eeaa2d090..1ce62fec1573aabaceb061b33f9a8f60891e4e2b 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 f3f87085706f9a405d7366993d0443054dcf8493..46c7aaf1e374ffc225ad0b1fcfe95994da6a336a 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 2012ec4855f14a66ce6262352f538dff9fb82a84..06a4b9dd230e36fec3ec6c188064a2e8d1c4045f 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 1ff1c61ee2250a8114be4fb8e09d05134552baf7..d14db60f7da89ea4d63e9a1af1c30e70ac4aeb1b 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 adf999684beaeacce53e09d881c3d6dce770e9cd..0728083652da3aec25527bdb3711886e404f4d64 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 c6359bf18a1b34df183954eef962f1b5c3473df0..2e7e9781d42995e4708b0c9248ab8835fff1f80f 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 ceaa6d8ff720fdbdfb076d9497f50e8e9028f081..6d59cd8bab7dfeceafffd8235d1bf9eeedfda76a 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 104b0be8d07c2f433851c83d5f7ffb4a87ae304b..a7bd890e3cc6d2ca95485aa2064a35341494ca1e 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 b810fa9c58394724c1960e28c3efdbcc1f97e097..c9f8217b06b4a937d3177c39bee0b6ace8bbf1bc 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 89528b60ce7c9d8e0385a30d288c22f707ed85c2..7dff1c319a6c251f27c302ce9ee8aa3440ffc714 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 24d4aec8a48ff377ba89f7d809071a5108da196f..0270e25b0088eca9ff52f023be3435555f6bf380 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 d64726b80fbb54bee172a4dea8b24ae1e7b72bb4..0be76ad4f754c8abab0328fb4016c37ef7207600 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 50f2462da01fa7819eb99f8ff3fcfddf9dc0d613..8103502404d3bddfcc8064b11d26142fdf0db907 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 873560d09b26ea38f274d9d3cb0f74615ecaa280..6d0a28f876ae7441e893f146bb02bf7099fcd2ad 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 70fe138b7c225c3f3379c5de3b3d4c9787a8297d..eeb3ecd27ab6583c1bae7b842eac39380b11dbcc 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 4c32237f14cc5b1dba12d137629fd39dde4b8723..d0a1b86b13ef1279fc428efe5e0f4026e56871a7 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 b27cba52e003d7bcd36c370d953046e782ee6607..ad01ede0e06f8cea7541a2d378204b796c172aee 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 776656ea176a2a6868eb4b66273ea6840f589a3d..c559b55a3fde03efeef88b766c7261fd8a60b65d 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 68959bf9f435a90f77e85b91a6fc6c8b0d09420c..bca8b7a0047070f054f3bd6ecfb256e709e20e5c 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 336e47990f83ea155f3d4796a5246a2438a30f69..4d769516cd936f09bc95c0aa69a4adaa103c4e25 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 ea5443d632203c1ee9e61ad35e34ae4af4752522..1a2c0db40b9cc6ed7f6e01dde9e60ea4c4a7280d 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 a75faade1469de8d00becd0933d950b4960c7dbb..28cd0992dd4785bb86c009e50fe05ae4e553d7f4 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 9cc5ca738d4a54fbb9f90180e8e479d1f27e3f60..af6a7091f9ab9df7fc3b15e8feee5a9e5e75a85b 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 432a2eb9b66bd2735859d3d44ba40c5951f591b8..74b3b36995353f27d417f606da2a1bf02ee17c91 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 2b89b93d6397289f4b27050c3e04fffc59cdbfb7..b4c651d24d23908c055af8a93b3a74caba755ca7 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 1b5d2a9025a0621b4a45c237bd2abc7cd456430e..1480e2fc71aaac4b9c54b862c6cfb945f249ea08 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 4cba8a0c7482c52a4eb875e1aeb13dc00f522a32..b11ac0abd1682e3833fca0f489486e6595a2c1fa 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 45fd383e06705ea807d71ff6d99bdf26e478884c..7760425e76d631af828de543c0a2d8dac2646669 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 155bd5b4ab34520839fd84ce8c597cb852a7ec48..16ae7d56b9c1f0e0aec459e9555b24c7fe278d33 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 fc4a074f5b8700ee98f788c71cc2513aa6366e63..97726a9dd0e8b3e4551493a31d69504f6d918880 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 f3d2c423875a53c024dd00759da2f69097be8467..d58494c5d9a765c0de109fb3c78ce61a4f0493e0 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 b9946fd313af0d67fddb74c1d0022f803f518ad6..b66639ca9e59ea18a2cd1e19f9cbd8bbf4268144 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 09b889796849bd71bf622f92c7b76ba6832c422a..7bb4d5957b09391cf161092ad82d3403db11c9b4 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 87649b48cdfab47f93203d7864d11e70a8a11364..bcf2eedebe6b546a9cab0442d68a8e4b3ae57195 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 dd58ada0aa5200038c77fe9f289e04839ffce8b1..4d40b87f164ecc33baeb4db755a513318f4f7c06 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 a9c04f0728f77f0471c525674da89a7603b22aa4..3ca08c9b589e4b497cab6ed658967e4b6914985d 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 250bfd331e1209218fe2f8ad3aaea91bcc8a8a40..d6f136635a9923d7f53910f99f44ebaf6fc0942b 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 1f5be45a4b6d16d02dc458da7f1b99ffb42fba67..5950735e3ee54934ae5a5ba59a6a05b79d451933 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 ecbd2cc47228b90fbb0e00f6a9e968d86c1cbee6..40d991fa3648eaf9ba2614eb03b5bfadb4446956 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 be8aee0f7e904f336e01bb294cbeed9cef07071a..401a62617985ddc0b547aa86577934aa331a09d6 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 1c5729da35585fc0ac5fee7a8842861030b96eb7..af6205db49d494bd226b048144d59adab433c7b8 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 6d569c30adff871c2346fb05d6ef0359432f7c54..d8769e35411523f0fd0b9fadd31dca0d7d77cbf2 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 3f4b6bf663ffbbde199aa5377637ba7ceb0066a7..37124a0c9867969ad118d56b85074226a552d8d5 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 3a8d1c3728379435adcd942a7bf9eaa27498e597..3f78ef5b88a20df50b4c6dfb03fa40131de2dfae 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 47569738f0d6a00a10a28886b730b8fbfa57c173..dfbf5f93249895f1ceeb04d3066e000400233b54 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 ed1b10a2549079a441bf8179c28b58948f5a4435..ac2e3dd0fa737e451a72819591b922aaac68fa19 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 0ce8e8106581e468c58eb332a8177247473b93c9..88088130ee4e998b1b683982c700fa0fc9ce0127 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 eaaaa2c528eb05234bad702a657d504a7f035139..11adb300d8fd4fbfc4e0f6e36cefab7da53e7aee 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 69e2ec2991c9d0886da6efb6cc7bfc9f63851f68..8a4bbab85caa7395b3f45a0ac5b82886571ab2b4 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 f6a88517dfc3b5a4e34501d9175c0a48bcff2478..4ff50d1006a607356349b75f738230cdef58415e 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 ab7a49b5763f85b1e28f47da56016fbe4d01eebd..3f5c3c4d07aab37f450e45488e7db4eadd467927 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 9203cf1082f37ec66d2d23f6ac655e770a4e19af..4f5c1c164a22f672e49a39f51c68bf8dfbac158f 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 62e8f2f059b4ac1f86b71dc843bd9fa79c2f2e8f..89287c4c0adecb5781b50b13b4a0127d81e725b0 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 bbf50ce760e7235685101316c3551e29c6cc93b9..d8d6ab22747c01c9dda199d80ad1b7a5f5cc351c 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 137932ef784688ede8938f1ce9cf8d24945cee67..9c34be0a07e2f16f6e9e50a13d4fbb9423343f28 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 ca45126ff1318935c2d19a1641a479cbf46ea102..721f9d7f9180316cbb1c90ea23135b3785adfec9 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 d381a25dd19c2ed21d2a2012603d2636b3bcfcd2..ad687b9a03d36669170bcd4a3d574965f15e69d2 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 e9120abe5d9cc6e45031441cab1f720f64b9f2b2..11a6310a76e32ae39dbf68a937d0af3609a52815 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 58b4209f5543bcb19a2d9d90102e283282936a4d..347d60337d763b5fe1da073eef269a52d5f55b6e 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 19a420a9a5c11a32022af42446c7cad71c204149..1646de8e654adf32d6bec2e2b24be20f0319faf7 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 6365c605791f12e2898a5c2c0b87078423a725c0..f5222c7e48b7663fbb7ab18a73fb4a949bef75cb 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 e3c36f9ce3688eb9e85189613c128d6379c0cf62..9931a5515bfa5f944cf58d925525aacd9b1ab42f 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 1adfc75b77a0e90091bb49db065f0d0ec4b8a229..f20fdc0a5f0aa76e15f47148e928acd1a2990836 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 afd68736832451c235038c565aa83f9df60bfc92..a64aa18cd3aaae45b83b479a060fe8e1435c6edc 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 6d971aa273bbb4505a05368e080f9f007d7c3b7b..f252a0a10f3344d97fc67c772e44a1f57e6ab590 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 431042eec15fea75827869bf7d6efff6583112cf..fecfd0967a27bf62831b8496fcec5cf611daeddd 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 9a80073a5ba0124a63175b4d25b12f54e2f29d0c..b6d259bcb236807ffb396b9ef0bc83e1c6ed0bcd 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 24162494dd6123001081c01b2aa5572a022896ef..72f4845a973e94b91986d675c09bf27633a8cbeb 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 e086994b0b64ed951040948e5eff5a51e4ad2b1a..cd3ee48a92bb7d3b6dc7516cee8c0369f121884a 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 dfb4c25416c744ca481fa75f8044e2b306f50dfe..e124fab610cb3697c78f9bbafe00a6a41c95768d 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 584b0e8eefa60c1398f785d442618381f2ce8eb1..9c2e9ebdfbad252ff45c2e2651cb032c2a63983a 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 d95d3a4e0baa0083d7e701f907e962e1c2bebfbd..58f2f04fcdf935fee486ff50619703b1f7a0bca9 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 f48e85c8faba72da703b85caf0f2b73054a45ca1..f9ee398899feb0eaec495dd7d04edda59bf190ea 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 10d99462fd8701491065c7cc1008938f5ab45c2b..482526eec1e08017c973120fe464f995adabf8c6 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 072fe2f93e7f11d240f3368f5de5a27e798dc00c..0807dfbf4c04bd84155efce2ca1bec73a4db74d9 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 141fde74e6bd1f910c4bfa20523de507b9807ae6..d0777758a7d99fdb674d5e7ed5bb31d452f21ca4 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
@@ -1363,6 +1366,41 @@ class EventLoopTestsMixin:
         # extra info is available
         self.assertIsNotNone(proto.transport.get_extra_info('pipe'))
 
+    @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
@@ -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 55fdff3f8d5e27817e53d4fbc26e6a7503b66e40..c38c1f29e7fe9f35925e517eacc0718e787ba84e 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 cdf5d9d3b6352606c2b870d198d0429a17e424c3..d3bdc513851b74044b4f3de36cf672dc1733a058 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 404a7489aec9122847a368ff795cfb3e9f7b7ee5..29aba817ec468b7e29e0d7976e4f9358359f8f1c 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 5a0f0881e4c65c2f6c0545982bb49c85aee812f2..5a92b1e34a583ffd6ee06b0cf11b09931ad7e025 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 135b5abf1013f864e8c708e10df15b4bed2141ce..5dc6ff8e66d6bab3be4df05d6033b3ac22370f37 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 a72967ea0714d245ab5a2fa3514164331e84dbc5..e4121a018440d6ab1df85b1290f310ea2d589dac 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 6f657ad5f801ef3dee45013a8179b9bf560a7b03..1783d5f6306ade668840d6aa44f36ff8aaaa1f55 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 e90f17dda63a798cb56fb3c817151dc83a71a75b..58f7253b4f36ceb0970c7998e7d9ad76edfa7ecd 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 04d19ac63b2f9c660b84123c006348085ff29424..e7fb774fcae14f9ff9319a683ac04a3545412055 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 a0f548d295faf94e68dcd7243b25d42270188e65..4f86aaa0c0eb49930483f4ff3ba741b48023703c 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 0e545950ee704ed8c8a5184b67647a523b839d17..40ac9bff2f6693ca1e58ff22cebe787e3880d5d5 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 823740c4449ffa38b4cc7e5030c9d94d9b802d59..e9dbddcd9305f1cc3999958e026f66da27774547 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 250743949bf57f30f0d5dc4b51f8230b86c458e4..d30a3b9c0f24b2b5a6a9f25f21df886507f2cc91 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 5deeb72b449c91c0fb3391625760c5e599b4c4ae..8cc1b0074bb152e2ce4811722f8201810fc3ad5f 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 53a80f4b47365afe44c5450886fcb98321e465ec..65c00d7a5f35d048703f6e47a9c14629f743dd87 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 eae3addcb182a4a4445b9a018fdff9deb7ba486d..1eadd2249e17293e8f55efd81b123eb6b7b1f7f2 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 0feb63fd4e0956780936dac2a5bc329e07316fda..dce418b65cbf48ae575086522122a7c1bd07c692 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 fda3e62bd6a1d4e6e91c8c65b2a39c690e9f198a..b2be9b1b709258e1fd3b1920dc89e77bd003620a 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 b93e0ab0e2b66fd041910d2a3e1ffa8dd193b226..04795427454b05edb22c9197956bc5d650366d03 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 b9fdf79463905ef24731f36504ecafa73448989d..4c32e094f9e318ce32935b005577aa47bd5e5fc7 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)
@@ -1620,695 +1622,14 @@ class TestCounter(unittest.TestCase):
         self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 })
 
 
-################################################################################
-### 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 8935c651cccedab89d56665ce43d246eac28f5b4..e0fdee3349893e7bba6d078e68467810b7766277 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 ef2b669356823685d35768cbf816f64338b57113..2ce8a61e394fcbf6c8297e638402403f891a1070 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 b99740b47db7cbb796817e8025022c6d283fea9e..cdb93088a268e619fa114f16ff8f6eba08e5572e 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 b9eadddbf2682f2ed70bb908d9c81e981cb65d70..0e1f670bf0a87daf24a643a5c79da6da461a9d7c 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 07c1cdf8483c08a928f9cf5ceb32d13a42fe89a3..4f725aeab2bf451227d0c512b4a35b8fb8558de1 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)
@@ -1311,15 +1478,65 @@ class CoroutineTest(unittest.TestCase):
         class AI:
             async def __aiter__(self):
                 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 624d702f99e5f0140024de7c2a7acc914117d65e..e4f58979c13567276a4f7da23237ab1b8e5e42ce 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 8e9c2b479a7873050432b8fda85f8c6b3a5e32f5..77c315edb1a271b0e1528aaa42b5e3539940c7e7 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 274704152007d01b383422f72916528ea198cabc..8411cdb0f25346853297116a6b5380406c633ea1 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 137aaa537e2da6bcd781121d08a354fe7545faad..c0d21b1c80fefe6e7aaa0d0586e4f59744568b01 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 87187161ab30d84bbc2febf7cfa31bec431bd339..f525429a171ffb4512b1781b1f40547a3e6c0f6d 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 d096390110282bdc8f488579d803abcc38e68e1a..a130cecb89e34444953dc9acc6ed33864b837fb5 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 3b4241422596ea2fc49095f17b6b2d427ae4a53f..6d68e761c64ebb9b43da3ceeaa5e614d2dc2d176 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 787ef20c47df2d58f3076b2443397c56bc0aacbc..ab23ca1cf778b572bcf62c8dcabbc708fd0d8c71 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 421bbad6c60471f23bb5d6602a469927723048e9..0fd134802764610b7a85795da82dd2b3a307c845 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 73b4452cd8bcad0e42a7f17e2ad11b28060005ba..29426a318531933a1380fd888041d82f64f732ac 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 2fafe1df8568fd585cc8d002d7a78b12ad8a88f6..a6a2856511937694e98d0e7d625e1613605347ff 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 d028f7440beac8147e76d7e7e4a56ab1840336a4..f7ac0e3dedcc243c988d7413126104fe9fcf74a1 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 089269f54480e83e21db47e81a56e86a9a7e4049..f9cd7d9b4ec1f8b282b4296b6a4fc6befd7309c5 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 cdb04e45ed2dd6f060bd22b5aed70b88b678f3e8..169058eac83da31014b3baaf6b0b1146cd3a3a8c 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 9bb32f0c48a4f5e73df097eaf102635633156725..70ac4db8b04da781f9c324d9d9cea5856b33c2c6 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 19cf64f0c7a2768cf3f1411a23d16b43b3b41652..e72a146eca8b01514b9f8477ba579d7fe22100db 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 4b5d0d07bc09f1e7c6a2b570efd0d2a6dbcc7e6a..e970a264d71e4c5e42c0a797d55ccc38b2fae63b 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 8a4904559490a4597f23c3bb3e36e66b052a6919..458ddc1ed82f901a852197e21e16bf7b22a668c1 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 654258eb240c856a98fa60969c9722f2f77b1d36..d526b5f1924c17c4ebeea27e34b38d2f1cd697f2 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 0d86cb5da819fc99ed402cb8fa80e57cb6e25287..1562eecbd65811b307ae74ba8df4b507b8da86ff 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 4765a056f6a4ffb029a66e3ea65fc30a89145d47..784bc92d23c80d6dfc8b550228fcbdfb8e5cbd7d 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 723beb37623588e0b0f987aecb250f93e013bc4a..cb1f6db8fc76279a1954af4b233f37c940ed5f79 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 eeba306f452ce912b1ad5e29471b73462ac29ba3..da46fe565dcc10efa3dc483b067371a9d285f7ea 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 d822b2de4578926d6c5ab48aa7c217e96dab6e46..9abe9843309936522c9a237dc97a8af1e0fb1255 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 6c4a34894011f67372124f4f3d093f72fb445d90..cd7d2925f47c31cd58c820f1a4a63f373c3a2259 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 b92d5ceeb96bd2a472b39e1ff2cf1b853afde6d0..3f82462478d5e1873e3904208a02c8ff45aeb3b5 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 6ba55df8c405f9676ced59fcb25c5d1da784974e..86fc2de75301e14d13cf45824b934eb5d4f5e08d 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 71472cd163cb18d8d9fc9325c9d09f92a287f5be..984aac7d91c2dbba58b6580c7c7fa3689a41742b 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 ec3d7833f7ea5cedcc94b2248afb44e92fd5dc7b..154e3b608cb49c9b626ca7f6e855e2bb965a6b61 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 85ec2f96dbac940290268796d7a1ee3c579e683f..c9b113e6ef1b4ea914f1ebc5d99cceb584a99b5d 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 50260ffe5cef4e8e803b4b2d4954e0033b79ff32..585838bd6c19033015e64fa9f3513fbdff124266 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 d3e06a452dec2fe30b56778fde61dc1ba5edd85e..2432e0bf53405708964070dfbe098b19d104ef8d 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 d809414b6370c85c5984c018525214107d891f77..329f0685fc280cf919d40a746b8fc9ad652f355c 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 d4c8eabd42205b04d005d0d5fe6759a55044dd2b..72e6e0888027febc78efb2b6ca01012e903ee374 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 14a688de1c6a7605e1ac08d4eaeb2336adfed353..1e33274b873f263a3cfd96fb12642bc5694ba1c9 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 28bb6f7c0c91a370b01047428fe47f0e0c4d72b9..3bb819f906d1f5e0f80e57917f305e2f74e6eee8 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 b604afb5ec882dbf6ac34f98a6e7e81f678bc2cd..1e0771b19debce6521a947e8c8a7e578cbe312d7 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 2e191bbf5cab952fc4281a90d0eaafdc7c56cbbf..774b7a4564119ad48db9ab468d47c6f0ebb17e56 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 69ddb514d61e58829fdd45c3e5c6c0319753469f..671e05a7b5b73b988c2d5ec85c44f711bc08ae49 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 3e4b4fc2fdc11cab4ab5f059c4d8b8aac520993f..b66c5d6709b1c59a46cd543f443d8c4779480eba 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 28f440d91ad29f569c11fb92011c65a2a38e4c13..000b525003be7525b15c2352605a9fbced56b6af 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 39eb9a136890b046dff668e6ba4cc16ab66b98e9..be62fadf0d9140c7bebed745fe7e5f4635a720cd 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 abc408f86935de1048481a40e531fd6171f2c152..a91670b4a11fba6902b13747d73bec906815782f 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 5b3ba7e2970547d752ca6c3b9b8c3d781cf5d5ae..f940852ce1b2b8e839147a234e85b742a4731737 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 21ef738932596b5e73a645e659bda9d6785506f7..47e2eddfb14d6bf8639faad7564088e616a14695 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 ae1be6e30de84d88bc449f9483b8a9b67b32bce4..8f82ab5297b7b72356cfc05da5f0cd55e8129108 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 95575bf56a63be10382c9684f56f2a7688bbad2d..84fd8b57c73be0fc40368a75977f72b23b74e9fb 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 62e69a9ed78d14269f0c675265ff823195c4a8be..b2d008b1013594e12b23d8fb82263d4f937a42e2 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 2d39099f910a7acda03a496507e9b82f494fa6c6..6c698e2f0e1163bd61a2511ab2c315b06d44550d 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 44d66c388f1574542278dabf9512ccdb2e141765..55b693e564710c9511ef980b282b1c2783ad8f1c 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 d2bab381042efe8ec41c5e361d94f1930438006f..ddd5b9a8e2f25052d8aae06ee7e44cf1a1d5483e 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 e8ca497144cce3d848ae2fb7b0e673bb65ce6ee0..ee8c04160ab706539da45d8545c78d041fc73988 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 0f25742c486d2c0863118f53e0e72f1812430126..b365d848652941ac06b37c16baf1d2ca5c4fe4f1 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 48ab0b492815d13766674a4c4922ebd70644a738..ea6e89733b2bbe439f8333f72b5a3a4bc75e40fd 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 4c49e9aeafcd91ee3661fdb1e28e4bcb338485f3..e4df2a90d4a4d0ddc01ff60882cb87c3948d380a 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 2929f988a8e58e6f9bd38b539676135910ddfa9d..8d7a213c168958a8f765985264f9971f5459ebd5 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 ae3618ffbca75f057bde6257cbe15980ea8ef933..994532b61ee128192c0faaa27daa46bfb25e2455 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 da9c8ef34f772280c58ad06c013b28f8b52caaad..b5ba97625ffc0676836242026ceddc25cdc46339 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 618c18abedd390864ab0a5f84a0a375a311ffd94..874f9e4c909879cf8528c243c62e506e693efd99 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 1c53ab78ea4e11b1a705567bb80ae0d28afc6174..fa96d9f882c9e2baa61fb73dbc34acb584ad3ac7 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 35044ad2a13c33ba7dbfe2acd0484598ef2c1a67..45ba5a96853b9576c7d80b4b8c3bb592323af807 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 8d560cd35b5acd26305c3f07e7f4c8e27456da77..7b0d4654252d756cf9e1d390858118b678ed3abc 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 0429941d87d188f962df8fc8e660560c2c8733da..ee7a667d0614f2975c44e8f17dc0dd4ac99beda6 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 57ebf1fd7fa630060706818b5c15aa2081714d94..9d2035464c81ca92cda483941b56a7aa564d0df9 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 3ea71f1fd96d66b9be4ef27fc41d7ff0a818355b..ed18773326a7ea52cb38e16dd46c6834a2ef1468 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 fef9f3997237e1b5dd9275cefe028e9da7452161..16114f9f6f3e4d6dd715697a418b2642d038d672 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 9d204715916d6ce0ecbd71c5231849d7d77ce6e2..acf110204cf547867a354ad4e6213032dfb22fe8 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 5addd363ed4f4e74a2d2ef1571c3592d999b52d3..26b7d5283a2220b729b91cd237ec4a9c9d260c4f 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 cab430b4bd39add63a444f7ca68326822cfc10eb..6ffbbbda27061af0600f99557157a2998395ca31 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 8ad5706a840d0e29bf2873ded13854f573d95f4f..59aa7151ee1cf26d8564ca76060667967bfa3f25 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 550aebf06658beac5d738b517146e50836d2f984..0b68bfa6fe08c174ec646a54dc323d41d9dac634 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 4b5232fe21d4aa44069778c458e98750f5659af9..5393431ff65f7cda6ebe5f3dbc3957e3986ee397 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 a51c4d7523f633ac2aa9a755cb1d058dd54279e1..4bf91945ea4f4ae3ea8c31ec07a35ca97fcd16c1 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 2022ed6e118f8ea49261af9582b6ed250d412e37..853e77330aa0fe0f4cc7bd64fea516be1d7ead54 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 4bae949d21f50754c89cf6acafc9eef4a41fcc58..87c83ecfaed81cafb3630ca0ef23893cdd68e2a2 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 54de508a832de4f6c7fb7be3df0b91c8470a92bc..1a49edf23110ab02e76014afeda238205f75dd34 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 62036ddb651ded63f3eae2ed976de363a209553a..13b30b90cdb3e08e0c2aca12a4388c4fdd15ee79 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 6615080c46ebbbce2682591816038043cdc40b76..da20a3d21a936f964eb2772447e3f7925bba1e69 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 8c4e670c9d416fc8f6e1abcdf96059c4a31ab185..4ae4142c60c8a878ba5ae104def96d7f005b947c 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 1e355ea8fe285ef5163572efdff8cf4103cefd13..c151a50dcb7a8ba0f357584638392737592da603 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 1ea66a6aa33e757d5f78745a4f25cf0271bbc632..0d0f86fca45717b90caafb8707d6255b62fb93b2 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 39a7c56019ba6a34785cdb00452a784ef21327eb..38734009c0085248de1b92841d787b79715415b6 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 548feebb82aeae7fcfb7d1e113b88f2bd68dd595..d2fc36d84ea0d67dfd8c35c80e1b5c478d67812f 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 758a481fe7ed73f823634effb0ffed8607d94d7c..0089ae8dc60b00d2d48a5856670e1dfd1fa4b2eb 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 0cd2b86217956c09a3f2284c467d0298e3df2638..70439f85c89555ef08dca3d7c566f896f2b967cb 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 346e2c63f8c7dd5878ddbaf15cceb3d5aef21163..85126e6e53a7d1a1aa94e05e88c44a101946b785 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 e06beed3dd5b4dcb0069ea8f7e9fbf4d6a90372a..4704d49062efc58d139587623f6c844832eb49ee 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 dc3a15f8356572f41f63a14ef4beb9ed78c3acf7..b84863fe53c6ec5e13f6625acdbe0dd39df13c98 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 a22cebb828b3d40975bf07f093360a7f8f01a137..057441c83c0f7109a3d7565efb4359836533dbd5 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 2d9565328c20cd89480acd51bb7da35ac8b9a6fa..a5318795525e70ce7283a23f0661663cc6662dbd 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,14 +711,31 @@ 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'
@@ -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 bb71acd8566632a5c13142a7ef667b2d9bba2d7f..a3e1d31fbebe94982c06dcc569409b245cb0cfed 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 ae8f845ee1bdab1dbc29370636e3c6186163a995..509bc3e505dea7a60bcd70b38e5a899a9932ac73 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 0917c3e260b1e91d9e38bc66043c04dd81bdff89..a23bf06af8fc88b916abb63a986c6001fe69f903 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 1412cae1114f38d2a1eb09708b11e95399f894ee..abfb34dfb812d810eba3f116764801c25ea11c99 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 25f6edecf5fc8694fd51a15a2692d097e707895d..8ffd1853147e49dfa93ca61d53aba4cd2f9eada0 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 524bba37b363a5f51e7d7097bef1e8589358a519..8e219f4217e7e4f92db7236dfcf621f4a293be1e 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 4a077cc4ca11038ad0bd7f7b78446c7f1efa3b69..51df1ecd7d18e63e0f927cde322087f007d3eee5 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 3b11bf65080b6709def9819d229e0dd5def92ef2..b49a9615f093d3cd9f191a59a11ae9c64db69c4a 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 c7f394cf60b3bc47a0507a71e45ac59744351ef0..4092cf33d3da526a2021665cf250f4ab5b18d306 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 845a2a8cfa90ee51db5a16f9039db10f506bb472..0c294ec0c446ea61b0e244144d023cf87fe74fa3 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 976a6c59ae10ba61f4f5270d482e6901a615bae6..734bbc215ad2c631a7e9f81a87b3db53d656490a 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 f65e36118c2202533311f82d1a1f03804d78f486..da89a9a87159358097642b389cdf202559844faa 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 fb113ab29aacd9f8b7dfe85a5eb13d0850820ad3..5d1fcf68a8800d4fe6ffe36a2aaf8441bcece67d 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 060119a134ebe9692fb1c8474e4e44a3775369de..a7f8dd50061d35e878d14ee2bf094d4a0173a8ee 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 d7f37c59556b477cc4c5680c4350edf76a20069a..a38e7b16104676112e644d10ec142e564b6c9ab1 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 57eeeaa6978c745b857509a890af096d86ecb365..5d05f8d7d26d66041be7c39070adb165939b476b 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 a5281d864c01650626ea37319754c7114e74d4dd..eda7cccc6035a6b5d3742de67a521fb70895f4dc 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 0650aa2744311d0a24bf81c04fc572722f6c68a5..c8b37eecea7ddd86a3ed565a56b5ed8cfa908d80 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 42ebb6e60b5e83eb31a4c4469019ca10064fcb46..b811930bbc7554824553896f2954746b7970fc77 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 0552f90594a3c3b29cc8e51a969398cc0e795293..829997fd6a20564b630041c25e214bbbea171a8c 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 12889438a9947a3ef7ddeae4873fc9a42359b4f9..8357f8bcd18c65ce6c849723c94a36104a4d65d2 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 4a304df70d46feb95b6b00eea9621734042ca8a5..f92e4d385e21adff808f4432ebb11ab90e719b56 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 fcb84540c12aaed67ff4d467b4405ca3e3971e2b..e34d8e625768704c7dda938f4c179bf6888ab24b 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 9207a685ab83eec0fca3b89b63e3f793bd894d4c..d2c986e71e25d986c9500b77a5166bbcdf51f01b 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 43869be33f8756d2b5c2c1c7f0686fd55e6f086a..3e6a79df463cb47669fcc492eef8c9e49a0dca5d 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 cea9c574abfabf5f1f89ab704449521e4afae071..72fcc73661038c728f03600b6f2de13b6a063aaa 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 d6ea2ce1046e9444ae55232dc6537c3b5ba15db0..32daec1140454aa29371d16bc7a51f7cf6bdbc1c 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 f37f1e9e245bde629f4f988872ff62e26e1b7dbd..f49cb7e591fac28522beac32b66c61e12f28c301 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 7afb24b045b38e69728d23b09ed820ecab65faa1..2a78388b2ff0b48e41b5cfa88f0a92f1f4dc1621 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 8cca595ab1ecaf5e44b6edc84014996a95bdd002..61a750c6221282acdba0294449f0cbf02ab81438 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 47c4de62e056a3fefa3e958a98bcc4dd9d15dc74..3b03dfc53995a5bb9b98e636611ab71c69475e32 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 d09b969ecab88893e02180162d0806bcfdc46c9c..44e3142dc91f856a901fcc099335cced2bd501ed 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 d0df38d3e68cd061cbe4000b3a92e61156ed8b07..96b446e32ead61327374ed04948425edd135c5c0 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 9880f4abd05f33d604137eba229d78a8c4403ae3..02d9f5c650c6f3b5d47c2a21fa208365f4a0c5ea 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 97343802a51451b4aa4cff3509041276add954b6..d8d44375bdd222b57ad457b44ab367aa7e98f4c5 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 2c10821a0cda3a67476c2df764ab1e547d76fc2b..d278e06a453be3afd2a4a26e431170fb45ef7b60 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 7dea8a32120a629fc21de34c505f651f0df699ce..c29bd8d2ec987cdaf41d279ee8ba08c1762e292a 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 a97a7784bd09d61f4e1860b5dc5a419b9a3bd0da..0da5906f2833519615c53d5c097d2af3398cd908 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 88c415bc4eb26c518db25216e0668439835fc101..78ecade950a0939d2f5dceb47e97317e695fb5e1 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 2f53718dace5abbd06f7e80d69a21de97210bd74..dc7c5f060a59d8421faad48effa2daaeb9dd95d7 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 828019d44161bd3b3cfd1a81a002c49d3e36b274..c9f8cb64eea044ddcbd146c3a261995278bbbca8 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 12085a9bd788a1261a52bb420cb548df523968ca..aa646dc8edce0f28a853554fcf3e672491a01916 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 55f0776ce9ad6fba3879f427e23c11f72db3fffd..e0971a26adde51d2abf2ace33453a890e7b740e6 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 e42b1be56a8fda05c625cbbc1e1e8a4483d90719..c645d430079a524abefe5d2ae71b1015d924b82c 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 7171667cc8a8272d75502dd3e264a450dd5247f1..c924d559372ae0b588cef067c8f53a7e7aac4217 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 c9dcf975f820f4362a1b029ccc2a40be1069819e..c68a650559e91edd5c5bdb44ce419e8bc0111b21 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 afd3230c1dc1e4d767e63c3fe4a93cfb5413ee5c..c031351fedaa1904723e60649bd6321683026a26 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',
     )
@@ -275,138 +276,11 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
             cbtn.tk.globalgetvar(cbtn['variable']))
 
 
-@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',
@@ -534,6 +408,132 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
         self.assertEqual(self.entry.state(), ())
 
 
+@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 = (
@@ -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 779538d2e0c3a1e73813491cb56b5ba42e22189e..75a068fbbf26b6a8b337597fc71430530276d068 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 c1cdfa7c0337c844e182dc191b96994c5ed8e847..f667933a1ed5ad15839a3ea0e74618453b02352e 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 244fb3dd7439d442abca6084e6665e502ab4cdc2..8f9369b060607a27df40a6350e6e5d2bc02eab08 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 65d06e53f3bdc370b22234aea5a72532035ba124..b1d0c8326361939a45f62ba147c9214ae685470c 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 9b69da0e8ae3c735bf72feb1d7aab80da7425b51..a2eb539c02587a104aea5be25171be491466f5cc 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 106d058808993a7580d4fd1c794932dd94d7ae37..711d0abf2e7b6fa39c4c289dbf51eae54dd9b0a2 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 1757f138220e513749646cd35ff5d58ed579b031..4cac66cd13e802801aa399a9586e9aebcb57924f 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 f6d7ae278ba17dab415e7cd9ca6367cbe173a118..7f61a80ff4ac0bc32deb61e617784c85c4f85159 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 ac8d67ddd1920b3ad3e26a81fe2be27addcb4a28..524a7b1050469737a9942d4f3561d66a5eedc649 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 c776f16c30613bd15c8d13c8bb300da49643c017..eb447d7ab6d9c2bd7d1901f78db3419a794a39cc 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 99ce1e2bf45ce6ff0082eea5f9efbcb630e8b3f1..86a5a3dfebd8f425b22b4cae26f0f66f311dec01 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 a18f11bf5d01eecbdc96bf1b1b28870dbd76942e..c7e3206d749bd3425f99f55cb8bb8962231bd87b 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 76c472514e3f28d14e9e9546193d62a6a45d5b84..353d4a17b963895f85eb8141fbeefd9325b833cf 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 ada733b1ffb45482b7e9b4763d2bf6f3a0bca318..1fb95dce2f9ca0d951659bd379aad4a59af900fa 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 55921febf58a648876ad30c4b66d97ab8a4653fb..bb196e6997af3229213af5448f778f0cad00c4f4 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 68f1036111881b0318d7ee2f232b2560a96a2f71..4b97882d65d7952fe76e687a80f0ea2e33e30597 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 9cbc26041ff5ec8df8bce53d0a1d9233702ca8c3..ddc498c230cc2863f26fedafa95456b0eff60a63 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 2a6069f66a4045d62b768afc55b1caceea7503e0..5f82b8296610e172009f96de48462171975091c7 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 28fe86b0de99d5bd4fa7743df6db5776d6193ba4..dfce3696d6ab26970af3e37b94f1a8069c2ea390 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 01c9e587fbcaeee2334c11e44a47889f8c161102..4d7fcec94b19e067641dfe0665fc3054c4cb07b4 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 a7fd017e1065afdb83947486316e2df45789897b..1731fe3df10bc112f72c0cbd29908deaa64f73d7 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 4fbb0cb995ff24878a185cb231855359a872e9d3..8b69fd985ee5f76c74c9785c44c16a1152adfdb8 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 5b24e2c29eceb36caf5261f4868bce50977b9862..e96e7e034cc5e5a28f78f6abf8acad39d854327d 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 3d606ef89c32c8985764e45481e865da3ade3070..74245abbb2a83348efe9d503cdefd45de8a6945e 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 45391aa01c9d50f30afef81daa9ea9048ae461c8..fb7f5c0db959794377de50a076ae65c4c1d513b9 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 1d4fb208f831c8ec92472114e5127bfbf09c0554..c6631fcbf4758da73033b3fe080b2ccc27f3e597 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 63d5993eca00f408382945f77e4fa243cf52b716..f4300b831a44e40e41966d1d5c578566b4bb805e 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 7e670b3caf1c3db716330507d292e7be13972512..fab851c5a44430d6cecdade6cd6438a1b471808d 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 378b316bbd457c977f50fb4a6cfff43f90191033..7fddbe822c96e2891895a33b819243a4b773fe78 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 1244500259d1a6812aec23f8040c46784160700f..5d6fae9a2575bf502999b3c59aeecb7b93a37385 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 bb32a8f03be9e3cff78d0371dbd075c647e67f4c..6d1b0ab864ccc4c1912cc8e3b242020db58e045f 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 25e684f05ba41d1a6ba94c3b830babde94a81e45..bbf9ee63f7672834fc42644127961b29a506d581 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 304e218c008e63173770b9544855f208fa2c4e8a..5b5bf7c405e6f5c075a15306d6841cab6e051f83 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 c8380bfeca5e1d4b809a2d1c7a9c19611b483ab6..eceb91de1aa455e4f20542ecaaf0aa0b88780ee0 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 2bd1007e2a2ba2b7b2c57119fd5aabb270ed272a..56a2479fb3850a4e4dac10da15b3eebb1c17614f 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 e8a1126908c8adc87b763bd485d35d6f8dabd467..d09da2f2f335c43801d26793bd92a4a4890d7a7b 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 86a0f2f4d5f2392a97d62b9cf89bdceca57eaa04..96a88413c8c9878478a6c728178bec7f127aefde 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 fff4d5b97e5255892a97cb34d841bdc749e1e49d..20982a46cc36a918791bd703562c417de685a638 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 36d0a3e40e4bb33f4a1c890f4542e134d8ef099e..0a62e327f51b389aa0c27fdd96291bbe1fd14f24 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 9538c069809e15d242ea57e0654dd1069f9fc589..f7c3b35a40da830b7785b5027aff2741a0bb46b7 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 b4ade1dd233afca7feafa36e5bf4aba53484dc19..4a5eeb5ff5d98636db0fb58e7a92613869c20679 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 d9622a612cbf417e55778ba6d69a887145c19b22..07f09fa83665283806647f37a2a2191a41d024e5 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 cb7e8d74855cff32ac0c37030b8c6f52a9fc7dd4..a0bb971046ea05123f28caed9f811d82bd6d33ea 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 a97cc1fd7e91757d5bf5604484f9e56dfcadae5e..fcba7d9a88463b924cff13ec1878dcb7d9a92980 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 823def3cd28dfecf63de97563821374dde8b04ea..87528a094dae608aba9b684420f9f1c366f2ec9b 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 1102ff3ba689476075be271aeefab2a09e030258..632c85ccdd28ce22003ae27a62c51ca1ab12f8b7 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 5e5bc60520fd6ab801009b84d266690eb3f08f46..67823337b7ce61a66ebdf266f8fe57213683e047 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 0addd80a4bae48d3216170ee8fcecd3694749937..4ad25511bb6d890f3c2b0461faa6fbe911375dab 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 6dbdba9e5fe1043911ac69fcfae27e63e61d6249..3d530d759020f28f702ccccee8ae5b61d5e9db5d 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 7dfd3072dc2682690ccca2a0a68295f4de9eef54..e3e0eb1f23d17e6b91d1c389189d67f42d838931 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 214872b393f37d0d0a18972a9511b724fadb720b..10fbcfe6b9bb99711ee49ef1ac4db3b014b2b6ab 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 af901e2d3ec0250683ebc69cf8c24aee2ade1a47..101f449d066b3a3d80e51ba1ea2ea885b11ad577 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 00eb700f84aa43290408daadc734f1ba3e48c165..2e01323b437b7b280483d98ede8241e5a4b87b9e 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 3c7a52a6d9ed4833c9c541d3fd50466686c7c0aa..8cb6d663e73303e540a9579a093f6c3c0eda19dd 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 d8bf904be20419f1d20def6986f82ce555276855..54cdde9a4fdb02450bbc4d7b81b2dfcf778772c9 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 4bc6b22c80fc3ebca845d66e6d7f6e8cc2e6686f..d9cc77b84033fbef1196ec858c85969b17fc7a48 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 87b9c0516f4add59697bb9a521aeb59e0941eb0a..228f4971ac372d445c40ea2e39e3bee6684f1906 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 e3de537a8d12bcb965ddf11ed648e203af253587..f419cb22ef81d1e7994154a5e8fd52ae70380e6d 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 169914c2f749a76a96401270cc5b865feee5fcf8..112b44fda7b5846428e11ce54c35697869ad726d 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 911b5ac5a9a9fc1e613b91856d2b2038103b2e9d..0f1d6a1faa40c89e607c5c3dac0b44158677f0f0 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 fadc0a9c2057681aff2c799ba4a7efa2c276db15..1aa457162d778a78468932121fdfd9f20ccde4ba 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 c343862b8cc1fb43956d30edab7e89a1848189a3..136abf59859b1601c94a020174a5d2d1ec392f4f 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 29e000bde4a6ff0d2561594b3aa5787e3e6955a5..6d67751c7d6b08b85e7309ae86dde786190954dd 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 31cc1f79a16dccaf81d147df9de5798017040854..9e5d78b1662812c6d8262faa67f3763fb393d38a 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 1ab1d65a653ddf5526d31b80c1efb84fc8a6dc7e..5f2abb03a7099b4110125a703a54ebcec43d0283 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 4a1205e933b77a809b3e07a73b57c0fe4fcf2bad..10420082acb045da3d504869dc275d5c2d5d4478 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 3cea079d4545a903e33ce63832113be4cea8591e..9762f11222deada530797665c2c9e9da5656e175 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 12e37bbbbe1e938e2d98c959f97ee5c31a2c50c4..919cf502dca4ac1df8ff8b0b15ffab4483dfeabc 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 025007e40dc2b5fba3b8f5030f8947e2d275cb6a..212b0ddcfc571eab37619dbea0a9d48677b16405 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 73018a539071b032ea3a8beda966776228532d2e..06b414457833f651b299d250bcf822502d3f5d43 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 b232b0242e515c27159298fe66eabe53235847c9..063caa6067f6751c5a286223c5b3cdfeaa9bbdcd 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 f63d758348d3681a792daf0ef82a9c089c1dc74f..f82af347cbb3e98adcb3ca1384b9c56c37cda7a1 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 != '"')
@@ -1444,39 +1442,10 @@ _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 7e4e2dfa8e9e04b3739a624373faddb5779f8f24..846dc0e8ece445602810e3e88954d5891ee6a4ae 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 735affcdbb610e2ddb5386a6ca7916baa6c6c457..eb4f3a34edbf64085c6f6fba4ddb9c9409b99bc3 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 5f385000b972baf9c3345fcd1ec8963e98532d16..e52da37dd3bb9af4154bddd83e4dbb2dc1033e04 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 2cdc38176beeb6993a7e1a8a1f372035e2c5ac0b..8bedab5c27a7855b40bf20dd0b20026b9a0fbcd7 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 a08ebfe8c47447f64461d73cf58d23c8258c5468..7570624e04e704419ee366d94b042d25bfa7cdbe 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 c1599c02df0a197ade980dafb7b5b507b808c5c6..300da2878e482297f8c71ff14e00bbddef4ebf25 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 957ccbc7fff56e2463ccab450a8de96c16a5eb71..150229dfbb6c8fb95a959869c84f499eeafa2f5f 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 67402fe0a4c72c814e84547c3fef16802861e03d..1117b5561c67d72f7e9c957d588029056193bd1b 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 068c5d1e1d83853ce7b23781c53304c047158954..f965541a5bbd710975a1963adbc63a81be3f59ea 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 9a0364826eebb5b9d033c01b2d3c1053bd0518ef..3810e944ce487317ab4a38755212fd6c9f47ae23 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)
@@ -1082,13 +1196,79 @@ test_k_code(PyObject *self)
     return Py_None;
 }
 
+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 bcb3aeeb22a032d13c8fcb7d50f6d8712ed76ae1..968181cd8a8c83f35ea2cbec68f0353fc1283171 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 41ad5f91f7e6abff75e71fd687641915321ea2bb..cf56fa836ac2bbaaea54d88b4bbc37501f497377 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 226a473b4c74e862f124391ae4a6a27720744906..796ac0fa33914c404b20b1b37d08c1456cc0d1e8 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 a3ccf9344ff3f507fcfe069b667cd0af3e182ef5..f73c5993658593e51ddab1f596f8c90bf8043e7a 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 3b05aec06a7ab6ce4b61e8b139d00430180cfacf..306937e404c31facf52205b04b964fe2b7a37ff5 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 23642df9aff9e818713d38c49af679af07d2c039..b72a3f00283b3879193e54d501c7c1f7a9549b65 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 e4547f75c99123920cf0941b5cf31ba714f8df3a..e1cdb2c4959312011da89660501354a7f07773ea 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 a9f0c42441f59da9cf2629ec6f97d0cada13bca0..ab4d20562094a5c5db1c4ca72d23c22ced02e909 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 5e3b1c06f69a19b132ad5cfbf71324055755c06f..d9a151797e510b67322fe2181dfe13f01f84a879 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 c5cdf427b55cd9c49848a843b77d68db58ab4f2b..602ae1df827fab11b00b029bea0b70dddf07e3ca 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 7f6c2c9df4f738450e6fb59ecd50be0de1d86a5f..82ea589e738d18771718e90afaaf8f43901f098d 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 06b5de0f44627bdf5e6dcac12cad0accbe343cfa..e8eefddc6d847444dcba30eaa347ee133b8d7a98 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 0ac0317b8e142e69cc6f5678de2d31ab2f09352c..412838794d703b18a02f8526699ec4e5cf1c81d9 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 fd6bf7a3d18dab9a1c70e5cdefe073c327b59be0..205c07eb8480675999cf1245ef8ded35b5a220f7 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 530ddc7efd670f937e5f3c9516188795b6ede67d..f1fda481fc61bf6548448985c6d57943adb0c654 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 97ff07c12e98362948f1c3e523f97e4eef3e4392..4e6eb727801311d357f35447c3bce1282f492d1e 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 e2a2edf82d3c91b19b12f9e7d5a528d6e7181078..d8167eaf7cdf8121d33fffd15886108cd62a3903 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 03d292c18b5989f42781c90e0d5100a505a68896..18deb60dfa1d786ad99bf663c998d8e2d12762ab 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 dfafeab5203153e00bb6a7f8cb69481b7e312f8e..409922a64388287f21cc8872481e909669cc9439 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 961532bb918db6577ac5657e618ddccaa87c53e7..add6b3efabcd172efd8682a7380f9332f1beb630 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 2a9ea2882c28eab835cfbe7380a1f42e6eb581d7..e4c955e011db25368b92c0b8fe9c8d3dbc8490ba 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 9359eb2b3a0f6ad71c663b128b48c9a0edb854fc..7ebf8e84c2d651ea0e20eb1c079984178e30b725 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 daab52b3880b23c879583119aa41af0f810c0c80..bb98a9942757b2fab3adb1982d4be82ffbcc1303 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 ef77c8875aa39ec69fbfa47eb05259ae53e8f7dd..f85e5bc73641fb3c6341073a743552dc9a605815 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 8023558fd15181b4ebc9755ea4b42cad9ea41abc..6471b8ee997fcf8ea1f6d5aed201edf82b823985 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 854a7491c5f712cda940384ed7e85cdb9aa8fc61..e5f58ab06b4bfcc448b540c7cffe82ce5b01bb1c 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 a6581b0b728e58e9ea84d0216ad41566bee5c8ef..8c00decd2570a69cc4aa0d8f74a4b2f46fcf7691 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 b3ac8073a916cc30a4354b8b90d5401728a1d1b0..00324a51bf9fa4a4625eadd942eccef8c2360d87 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 8c4def05726013717af5a0af11013cbc6f486b8e..70c2b5b507e6082bfe1c4feb21ef75dc3c8ba71a 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 8237d867f4aa28b15ef23c106e0f922b49666b40..76942aa7132808468057edf9a5d9be86adad5b39 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 70f305214988327cf672f9191533cb21a9e8901f..da454de8d9ae428a36f5d2f8210f601b54ec1885 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 bae9634ef2b01ecbef0fd412522b6265e99ecae3..8f571a2eb4b57921d0be8a9216f1c48143750765 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 06abb312b35f3b771a76547190cc1a69e0b42582..e840271bfd67c6be3f6478c3b26c03eb8f3b22b7 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 37307be39dd30575835d6d0c2c25e88d7af282ed..16cc17886bfad345fea65ef712513d13d5a784fb 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 5647b57a52fa58ea23c2f9484e449466ec04be8a..277be59ad8c7696153d0faffdcb4c163d4dcae1c 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 08275ad5ada1b6eb785cd6ead402f11b71bf322c..c2aa65c3bc53bc5130c308201ce81cc430ce6245 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 eb5ad98e6840b347ec729c45c2c46c23b35a9d4b..9f4eddb846835c3b32b76622cb78e63076e0115e 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 353f414a38486b8ab319d8fdd07934ba5b4b54d5..964ae62146ba2b7ea3f563271509547fa38578d0 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 9ffbca72eda6bd7b545ac628ed97aaedd0e19a08..da68e3be26786541953d95b592b7d122abb614ad 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 624ae9b88858adcb5139427dbe78c1f3c677a169..d7745860e47a8f0d576d6b931f71c6d4361095c9 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 f5a1a2b27853a3a111fd5ccb33793d670acdf414..aaff0bc63d9ae7b5b26c0c2c1331ae811784f502 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 b8d6f2b52e063f7294d0366c333a3e6a25dd273d..d92bec35b5f8819270bd9152ad11cbd8bdc1b6dd 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 172f2cb61b87d11fd8a7bee866c96e863f4876de..9aadd61019e0abb7f290fff26a801e81de4f739c 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 b04393415a79d7e4cf71ef83ddadfb25564ae1e4..e6c327d22f85df9921df8856c01389c347de04d4 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 00ebbf1cf8dc11ff71f2f4f4c21823a1547f4315..b3e0a46e8b3581f26d7466f8b7a626cfcfa7d1ac 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 2fb0c8832a970af717f83aa617a7d88f0634a4f2..ab29ff81a9595b26c446d5d75bb72314f5d33bb2 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 45e54ce31d201f0cefc9700d55a5ce31e513b6c2..d688179d6b4d12340f8b6155c3c123409ee0cb7d 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 5f224557d1f7d6c42829ebab72016ff9e93a4829..f68d15e615208872616985dd088da770f2708c0a 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 7b41b0b6c474f33659a9cdc9a43eb8e6ff1060ee..a4cdc206c12a69045ede2db7a338063940256cc9 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 6fc4df16397aac74ce02b440425c844e7130ab3c..802488900851d34b813b87b436bfa49b8e46e577 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 5ad88bcacc5cb5958ac4e99874bdf6c46e059fe2..1abdd02cdfa540fa3bc049bb9a8db884ad33e70a 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 da1d703b3a0dce0d99b27fcaf4d7fba744fc1965..0e9eb20154b7a0cf8d961263c6e02888d54a7632 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 704d7e2b2a76ec2db079eb275592a76f69886937..4ef692db33203129a69a324ed285c89fc533cac8 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 104952333a5ae3ed3214c1b9dbf67b25a206fe82..2f32355cd25b3c35b0af72a74161a86661c467ec 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 aec221acff9d43dee1d0f99b2ff39fd38c49c83c..be09b5f6fa78b61e08f52ff028d9929da35b0550 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 7efa1a6776a00ee3eb0062dd92632030c220bf45..7920fec2bd86e8854f110afe8818e85737a66fc6 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 f87d58fed210b477ae545a69efb6dfd169c63845..317334f739a5a21dc777a8fc41d7e97ef4be3a1f 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 0b78301f23625d3477d86d0603b58f3522cda836..f11a0825262b8df7dd1c43b13ef8cfc42437ddad 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 d4d52e60aea8e9ab18c50f6f84e1831a5def8fea..7e6f36458bc693cffeee1e329196e0af0da9e52d 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 2ab474e439673c7151803ea2b3f04d73d5eb2e4c..4dc5009b58e6ac539cda6e5a1e218bacd3b1acc3 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 f39b3819dc088596c571d19aef46e65c14c17e5e..cb037ff2c603b6714017d01be27e513f52e30804 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 22b332fbf2a76ef98ed1dedfa4142a7e8bb8b774..338e33d39ab9c33d84cfd399740e6fa257ffe16b 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 25b328b260c10bb8f76c866b08eb91a9d089ca2b..c7ddf1ea6b33eb6d55457eab82f9802a2512b0cd 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 fada4c9c16ad570617f9f1146dc2de2d1d2827ba..db5226e46653d33a03c2bd10ce51a209b8093a26 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 d44173ae9a6ddc03459accfbee0cfb6bb8541711..ac4f8f25e064a9c295653eb7b290e91fe86e5f7a 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 827e9be52831df521d21189593b124a53d2ae03e..f95e755bb8bd786c641ba8e9107218ff78b43cb0 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 3313202bc43c83d5b4683f67b2fe5a21edae26a8..d1c3f39525b5c24723e8a1f18067b9eb6fdc5535 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 64c3dcde14fa8ce7dd795eb600722d788e5d57d2..9efb0d9a792d6c543d1f166e94de851c9f1c4daa 100644 (file)
@@ -83,6 +83,9 @@
     <ClInclude Include="$(bz2Dir)\bzlib.h" />
     <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>
index 68b8e2971d1b65bad727b251b1b51c59fc60e57c..70bea457d2a9fe5f2b1056d76e57f2a34a1ae232 100644 (file)
@@ -96,6 +96,9 @@
       <Outputs>$(IntDir)win64.obj;%(Outputs)</Outputs>
     </CustomBuild>
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
index c1260b53f3ecbcfdb7a8c58b38991360e3c059ee..b62407fadf062809ec4b600ef1823561d5501c16 100644 (file)
@@ -66,6 +66,9 @@
   <ItemGroup>
     <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>
index 943bfb0990345caef975dff8cf95aa20960295ae..9c9c19abbe334a90f322dac505261edcf08bb2a7 100644 (file)
       <Outputs>$(IntDir)vcdiv64.obj;%(Outputs)</Outputs>
     </CustomBuild>
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\PC\python_nt.rc" />
+  </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="pythoncore.vcxproj">
       <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
index 414bd8bebb8216f1de97d5814a7f60fddfdc7754..725b5a967bebc962bd602847c211dd8af0c64afe 100644 (file)
@@ -91,6 +91,9 @@
     <ClCompile Include="..\Modules\expat\xmlrole.c" />
     <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>
index d82b266902a93c931a28c363cb62bcaaaf88fc0f..b1300cb8c9d55e89301c0b6b0654e3f13985dc19 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>
@@ -70,6 +70,9 @@
   <ItemGroup>
     <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>
@@ -87,4 +90,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index af50494ebde69fa8fa9e619fab09f0230436d805..1f0696da82ecd5537c470e809f754a57e358fbc3 100644 (file)
@@ -73,6 +73,9 @@
   <ItemGroup>
     <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>
index f5ba7bff7627493cfa8dcbe5dd4b2144d0ee2371..3895d450f35d0ebeeb487fac5dada084a996d8f9 100644 (file)
@@ -68,6 +68,9 @@
   <ItemGroup>
     <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>
index 1eb92b67dc241d603d3140a0cc9884656ad3a981..bb2bb4114c985b002ad3677e4a354745e0ad5acb 100644 (file)
@@ -72,6 +72,9 @@
     <ClCompile Include="..\Modules\_multiprocessing\multiprocessing.c" />
     <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>
index 55301ea9dc2958b99e08da4951400580323adcef..8cf8a8677bb378e286ab8299aefcb1fff8583a09 100644 (file)
@@ -68,6 +68,9 @@
   <ItemGroup>
     <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>
index 03b6f7558eb4304116f730b22194e4ddb65064b1..d5c4d1b5b6f5d99254846fa724c83101ce7851b5 100644 (file)
@@ -71,6 +71,9 @@
   <ItemGroup>
     <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>
index 5e889d0de00f4494bac31cbdae1ecfa9313a635a..5456bb5b238513ab61023893d8f85a2040b50cee 100644 (file)
@@ -90,6 +90,9 @@
     <ClCompile Include="..\Modules\_sqlite\statement.c" />
     <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>
index 8594a06966022e2eea070c28d18b6356f353dad4..d75ebd656a7f08e30d8dd7991a24c339115e35b7 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>
@@ -70,6 +70,9 @@
   <ItemGroup>
     <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>
@@ -91,4 +94,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index 8cbf1251c365eb1c893bf69b982c7a71063819f3..1f45b298102641185b265305dcf6f89810a0030a 100644 (file)
@@ -68,6 +68,9 @@
   <ItemGroup>
     <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>
index dbf44e6e94146219bb5968df5932c1f346a7112a..365b07c5c5c8e52a9ce6bc3080f693960b51ac7b 100644 (file)
@@ -68,6 +68,9 @@
   <ItemGroup>
     <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>
index f0e4d9f87465aef57c4bf16645fc7b95627092f2..14a926e9456d9f27cfc16924327230d06212b105 100644 (file)
@@ -65,6 +65,9 @@
   <ItemGroup>
     <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>
index cec042c202c65065e7cbfabae77fbc6caaffbe5d..37c1a64ac8ccbedd37c19f9caee5d56a1716746d 100644 (file)
@@ -68,6 +68,9 @@
   <ItemGroup>
     <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>
index 647b38029de95faf1cd3cbcd6d9c14529906619f..106927c67b94372e091785ca145fce0ef2e84781 100644 (file)
@@ -68,6 +68,9 @@
   <ItemGroup>
     <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>
index f3185eb28b8cb511a4c11c165573e7c70280d4fd..67931067d3bcf73b0171689b84f1c189768f22d0 100644 (file)
@@ -73,6 +73,9 @@
     <ClCompile Include="..\Modules\_tkinter.c" />
     <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>
index cfbc4a29377755c9373cffd5d39a18d837329dfe..88b1f060ab1f0470ed836f2f70770f7f6c7df310 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 79ec2670b043653398e6a8bcd1c33cdc847fbff5..872c3822ecb21954c0c0228c7520f75ed5386a45 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 0b3c08b66e360f5400ef16a103457e02f31cc242..9b2a084bc2f8d9bfef44cbef07e74df6a72d62fb 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 d094e59ba8c2d0e3afc90f58155e274a336147ff..e35c0d9f527137d96386a25661fb3f53cd1b0479 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 c08a9f3474f3e30fe67ecffa8093cabb03f7c085..1be73e6c365c677035eff6f526656592faa8f45f 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 4203dab2f8edf18870c122d0061e8ddbab7bfa1a..f6170f58083eb2dbb6ca8c8fc919e083a7c9f96f 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 4e7621ec926b3ff4397b86c26bd9452214cf45dc..99c7286b2bdfde1e1862c87e84a52d36ba727910 100644 (file)
@@ -72,6 +72,9 @@
     <ClCompile Include="..\Modules\expat\xmlrole.c" />
     <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>
index 6a2178583e1e2eead361ef97567f99c06bbb428e..2d4b5f6445c014c5151ad84bc073f14f7254e996 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 25cdfcc926b52db0f1eb3fe8a1e93ee38d5e865b..c56292ab5eea4f81e9549eff27e44cbbfd099c14 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 862f04103c3278c669fc3a24ed386dadc9f5cc08..843771d3f0090d89bcfc298694464b900f6aa916 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 0ae4882ad16aca9bc5de0a3e6bf11016db3c4ad9..60116df271d93d7565c16a94701e7852324b99c6 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 18ff4a83e912f23239b117621a0d373e8aa4b2c1..cbb618f283c5c937941ccd0744785000338aacf1 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 9cbe8b9384c08046aa4f7a03cc0354b25a73c87b..3a1b5ba8bee4d9912226b68900019b84f0459a71 100644 (file)
@@ -48,7 +48,6 @@
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <PropertyGroup>
-    <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
     <KillPython>true</KillPython>
   </PropertyGroup>
   <ImportGroup Label="PropertySheets">
index b0a209af42f5e4c9dd3e4051d891d4eb6a0de421..caed1e8dcfaa42b2c7bd6782932fd44ef0e44296 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 882f1c4d24bddf073fa4b02469737d0f35038946..eabf883a4a95967c1dfc166d7d4e72f05f09eb86 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 09a996f34c00400796f5d3fb84eb3497fec29780..d45eb271f820b8dd10b8a35f10cbe4a8e2dfafe3 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 3cd0694baa5f3062611dc58d948c70a98ea4718b..d6112ab6fe3f06a53aba379fb0c00dd697443806 100644 (file)
@@ -67,6 +67,9 @@
   <ItemGroup>
     <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>
index b6246fa78c546af8136581d65bac6c347fe10b48..c841c5a8eab84a01b2509ed1e1a9df6f4d02ed72 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 5e794e553759d1b5190482d215c040cf6f3a747a..11dbffbdbfa32acc9cdb479db6a6799c536d2c93 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 a3071fbf8eea29429425d6a5eea771d6146f8663..317c1a8a56d4243ed9b2f64e39eb098c272ba724 100644 (file)
@@ -71,6 +71,9 @@
   <ItemGroup>
     <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>
index 540235af22e2914513b52eca6ac85a22bcfa3427..12913efdeff1dae42df1e23bcb04fbdfe9f5b483 100644 (file)
@@ -67,6 +67,9 @@
   <ItemGroup>
     <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>
index 6a528db6d78b2db50c17eb3f0de03928c468e073..184ffe7a7d824c5c8a1943e4a2b8d30a989ac68f 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 39ff0977c8fdbf7ae39c97d24b82ed08324301f8..ab6a8c75073ca99039872e7b9fa9382d96d5ef00 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 2e5e4e368f0e8d668c481fa9873561a68976954e..37b10b837e8845c65cab1094161a3c0cb419dc27 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 9ca83145c94cb60aafe0d672265e25314922df66..978bad135c146bb52044bd24a54f7050729bdbd0 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 a06ef610c660ac09c6c74b688801654ef3aea138..f3d0c9a87015a5b35c93b0804f225156453cda91 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 beabfebc1c7e205fcaab186330bf5d7025b4410e..3d690384448cb5213bb602f41e938aaee74a498c 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 aafcbc2bc9c5f1a9119716f52650f9b761593de5..8d38ee9dfc8482ef34e107657aa3fbaa30510f68 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 7369148b23a9ec8bd2b06b7ff4a61e8d65b45e35..90995e5ac7b06592fd8ac89566d109dd0de1a8d9 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 d90bf7374d49faf424f08f77f8722c2b5121b735..fe57d0dc42d42d974deff748ffee30020f1cdcbf 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 4befaa78fc936740912b28886c8b3fc5be93cb0a..1e720eab0d0e909ff86f95286bb7f2e05f6fe72b 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 aed2bdc12d6b1734b58c8e8f86cc96ccae3b84c2..e151cab17cb56be1a38b9d5af46fa86adcf7083d 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 079918c4a302e1735f0da6946842ad02768c6ee7..23eed71321853d97a220f5b1d2656591e62de455 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 056bb76902597e8b959fa53dcd58386102b10c99..8e9c502754c76572d603b17390eddbaa3d7d8ba2 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 c365fc25a39dca3b7004a8984b3f4acca4f5e7bf..8aab067865b81b91dd51b44af463b67ffbb0ac27 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 2ad2848aa80bb93f7e8ecaf49d46ff1164c141aa..c3f1e89599587e425a4495a52f0da83962dfeba8 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 edf030d87ae9d359947a767c15aa0ed265525a39..0b843dafd3df21d2d04877e77d0b9de0025931b3 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 a4daf621e24c524764eea015e2e31a96a400c7a6..7f6b753baf482dc6788e7abcf6b22bc1b161a267 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 b20ce1756d0f041f198c21590a03994370465271..47f5c625fc8ebabb5eb2b66b9de6b88d6d5b1fd0 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 f89cd04b6553c11d2252a58d3a0d1d3ef4b4dee0..5b8de9919217846fc508f76d406c4b4ab66df9c0 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 6c938ddd797e549260f2318d582f1a1421439b7d..0d093711f5f0965cf1b9329c737134fb18fa5b5c 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 59ad3b762f8bf6eacd301159591198cf45d0b133..4e657fa176eda1f153d32e229b5bd84177545d4d 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 4f5efc963c7722b2be204c328a06bc9d47adb11b..ce52990496931ca13937dbfd3e7f8c1defec070e 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 7e0267ae1d04743226fd6eabccad934a6b5cdc83..6d1c6d0a1fae1656399c92a0df703a6bb3e82007 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);
@@ -488,11 +495,17 @@ _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 ebedd123f39516a159a196915eb4ba612c8399db..7fbf06e68a1faba77b3f6929a13fff85bc3385c3 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 772bfef0e87606e99459c9d0d2f45bafae18168d..07dacfe188e8fb433c30bff70083f30907c88b85 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 64910d8a558b776408b057389ebe4df259ddd8ac..1591a20f502415f61ea4f47ba18bb11b3579b1f1 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 334f5d0c8e95f0cb6e1c2cabae8c7fba3eaae869..8d7e05a465a1569f7e875d665eed01a37c5b9797 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 84452cdac4eccb410c1f1b9658ae154ae525af2d..b29b1b6e3ff6d7f60678022c754227f115c3ed4b 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 84aaef908bffca75c0cb79553383772abb50b099..9a07bfdc562928cacaeaa06a79c6d94260e87dc4 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 3ce3587db51bd5d57c433dd7a8ab429c535d6d53..1d851da956105f20125d541f4c3634f49d5ac9ea 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 cd21000c050c371791e74af5f82f5fed2409cda7..ac0640c66cd6b0a161be567df3f2fec63aaffd47 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 32e804c551e7544f0a8db66c3aa279fdd8a0148a..fa43fafe1e5c986eab0c098a7e89bd369cdb635e 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 32341e7794d377d224fb2ffd5d0223817b0f847b..75f1ccbd442d8d90616ed2e63148baaa5df8b604 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 fc7cb9fdc1f999fc4efb7649ac4b50408a0cac90..2eae07ad4a7dfe492d95b90e9b04fd64aa049b11 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 8ff4c3b9f3e9646438e96d5866880fd7874d9e0b..4d9c97a194cd267deb5f94e40a45f7c5bf8f9b95 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 1f3e77c59d39beb3f3713b0c8001e64986773f24..697066b2e1bff1c7dce062736c74990a1ab5d30f 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 9d94e3b46f6eb6587bb04e09449a8da88b9c1fdb..1462d7b67ee11fa8e01d4f1bcaa279f5da5be227 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 978efc0a21740776a09275498b6d8308ba2ea2b4..38307e063cb5bbd2d7d61bedcd8a309db8581d1c 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 4b03fd29b625aeb5642e95fcd364f8645b5c2ccf..4444f45a980070201b335aa2fbf84cdbc93c11dc 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 b90787208928c9f0ddaece1c7f7e4ac787973da1..4efad6562a37b6c3a8e7ef0264c412bada497e32 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 a0f1d574fca0bb540cd8eb5cb2785164a792cf2d..67fb0255deef320ed41cd6b0cb2eb45904928d35 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 718b666a5c74b1268a3bca8b7ab5e1d7b99f063c..80e838afad4777d219e8447eebec693e9b01ceb8 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 d961fff3c68d72d5820df4195fab4cb770db9d0f..e4c1aaa9fa25f9d1863d62f29039bc8580de5d48 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 96fdad2197b366335574726fadc3d4e41aad8269..753ba0f78766d77fa6a99133efc3bebdba7d2a10 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 bbb8aeb4e21b15b46bbd9bd5a870d5f9ea83b8c6..9ae6d9988e1083dd4e4f2b4fd4d1fed05d829f15 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 a40d9c4f926689afa892ccd81110d9c18ec6423f..86be35badb7be0f954cfb7eabcbd37d474a64df5 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 c82857710b06e9ca8c875efde842358d234da20b..285030e792f466dda857529a9ca0b023770fafa3 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 5f3795e65754dbcfbf70c2a0028532628b5b75f8..6c16b1ce151852da1a54e7aedb515c0e5c898290 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 7d25fb925389cb0c916ba0f7a6b9a812c91a8beb..1f0e6f485c9beac14bdeebd8653ce1bac22a48c4 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 398f12160fc8cb8e9bdd9e061dfc33750d16e78e..c892a99f9d36d7616a23d95e9c65dd187c0904f8 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
@@ -4934,6 +4965,104 @@ 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
+ ;;
+        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
@@ -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 694293e8be83f2d6a780378748ee0abfa8816dd3..1c07c0569db523ebc68d4d0a9f703b80952300f5 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 b0cafb318574c9ddf2ff1e296fbeabde90e76353..78955355323f23c0480fbb3a9c1ee7577954d606 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 da67731aa19f51c0725fb5fcece21ba3e976cef8..174ce720c8029b3d3ea1f1eab79978c0c146e783 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"):