From 8a22e672e8b426fa5456589b17d181b4dd63c26f Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 16 Oct 2017 20:03:49 +0900 Subject: [PATCH] Imported Upstream version 3.6.1 Change-Id: I9e03aba4159efe86bdf19df8a277e6d79af53c4f Signed-off-by: DongHun Kwak --- .gitignore | 96 ++ Doc/Makefile | 6 +- Doc/{README.txt => README.rst} | 21 +- Doc/c-api/exceptions.rst | 2 +- Doc/c-api/structures.rst | 7 +- Doc/c-api/typeobj.rst | 12 +- Doc/c-api/unicode.rst | 24 - Doc/c-api/veryhigh.rst | 5 +- Doc/conf.py | 32 +- Doc/distutils/packageindex.rst | 2 +- Doc/faq/general.rst | 6 +- Doc/faq/gui.rst | 10 + Doc/faq/windows.rst | 7 +- Doc/howto/clinic.rst | 63 +- Doc/howto/logging-cookbook.rst | 4 +- Doc/howto/pyporting.rst | 114 +- Doc/howto/urllib2.rst | 2 +- Doc/includes/setup.py | 1 + Doc/includes/shoddy.c | 2 +- Doc/library/argparse.rst | 4 +- Doc/library/asyncio-protocol.rst | 6 +- Doc/library/asyncio-task.rst | 36 +- Doc/library/base64.rst | 17 +- Doc/library/binascii.rst | 6 +- Doc/library/collections.rst | 9 +- Doc/library/configparser.rst | 32 +- Doc/library/crypto.rst | 1 - Doc/library/csv.rst | 12 +- Doc/library/datetime.rst | 2 +- Doc/library/dis.rst | 55 +- Doc/library/doctest.rst | 24 +- Doc/library/email.compat32-message.rst | 10 +- Doc/library/email.message.rst | 2 +- Doc/library/enum.rst | 6 +- Doc/library/hashlib-blake2.rst | 444 ----- Doc/library/hashlib.rst | 436 ++++- Doc/library/idle.rst | 2 +- Doc/library/inspect.rst | 12 +- Doc/library/json.rst | 27 +- Doc/library/logging.config.rst | 4 +- Doc/library/logging.handlers.rst | 23 +- Doc/library/lzma.rst | 4 +- Doc/library/os.rst | 4 +- Doc/library/pkgutil.rst | 4 +- Doc/library/profile.rst | 7 +- Doc/library/quopri.rst | 4 +- Doc/library/re.rst | 10 +- Doc/library/shlex.rst | 30 +- Doc/library/shutil.rst | 48 +- Doc/library/smtpd.rst | 6 + Doc/library/socket.rst | 8 +- Doc/library/sqlite3.rst | 11 +- Doc/library/ssl.rst | 24 +- Doc/library/stdtypes.rst | 49 +- Doc/library/subprocess.rst | 10 +- Doc/library/threading.rst | 2 +- Doc/library/time.rst | 42 +- Doc/library/timeit.rst | 22 +- Doc/library/trace.rst | 6 + Doc/library/tracemalloc.rst | 26 +- Doc/library/typing.rst | 72 +- Doc/library/unittest.mock.rst | 14 +- Doc/library/unittest.rst | 18 +- Doc/library/urllib.request.rst | 78 +- Doc/library/uuid.rst | 9 +- Doc/library/weakref.rst | 10 +- Doc/library/zipfile.rst | 2 +- Doc/license.rst | 2 +- Doc/make.bat | 4 +- Doc/reference/datamodel.rst | 22 +- Doc/reference/expressions.rst | 10 +- Doc/reference/import.rst | 9 +- Doc/tools/extensions/patchlevel.py | 6 +- Doc/tools/extensions/pyspecific.py | 8 +- Doc/tools/susp-ignored.csv | 8 +- Doc/tools/templates/customsourcelink.html | 7 +- Doc/tools/templates/indexcontent.html | 11 +- Doc/tools/templates/layout.html | 1 + Doc/tutorial/classes.rst | 5 +- Doc/tutorial/controlflow.rst | 11 +- Doc/tutorial/datastructures.rst | 8 +- Doc/tutorial/interpreter.rst | 21 +- Doc/tutorial/introduction.rst | 2 +- Doc/tutorial/modules.rst | 2 +- Doc/using/cmdline.rst | 12 +- Doc/using/unix.rst | 19 +- Doc/whatsnew/2.0.rst | 8 +- Doc/whatsnew/2.1.rst | 16 +- Doc/whatsnew/2.2.rst | 8 +- Doc/whatsnew/2.3.rst | 12 +- Doc/whatsnew/2.4.rst | 32 +- Doc/whatsnew/2.5.rst | 24 +- Doc/whatsnew/2.6.rst | 4 +- Doc/whatsnew/3.5.rst | 11 +- Doc/whatsnew/3.6.rst | 27 +- Grammar/Grammar | 7 - Include/abstract.h | 4 + Include/bytesobject.h | 2 + Include/codecs.h | 4 + Include/dictobject.h | 3 + Include/fileobject.h | 2 + Include/fileutils.h | 2 + Include/import.h | 10 +- Include/memoryobject.h | 2 + Include/modsupport.h | 12 +- Include/moduleobject.h | 4 + Include/object.h | 2 + Include/objimpl.h | 2 + Include/odictobject.h | 9 +- Include/osmodule.h | 2 + Include/patchlevel.h | 4 +- Include/pyerrors.h | 21 +- Include/pylifecycle.h | 4 +- Include/pymem.h | 2 + Include/pyport.h | 4 +- Include/pythonrun.h | 2 + Include/pythread.h | 2 + Include/sliceobject.h | 17 +- Include/unicodeobject.h | 22 +- Include/warnings.h | 2 + LICENSE | 2 +- Lib/_pyio.py | 2 +- Lib/aifc.py | 37 +- Lib/argparse.py | 2 +- Lib/asyncio/events.py | 9 +- Lib/asyncio/subprocess.py | 17 +- Lib/asyncio/tasks.py | 3 +- Lib/asyncio/test_utils.py | 5 +- Lib/base64.py | 6 +- Lib/collections/__init__.py | 7 +- Lib/configparser.py | 5 +- Lib/contextlib.py | 2 +- Lib/ctypes/__init__.py | 4 + Lib/ctypes/test/test_callbacks.py | 11 + Lib/ctypes/test/test_structures.py | 23 + Lib/curses/ascii.py | 18 +- Lib/curses/textpad.py | 31 +- Lib/datetime.py | 2 +- Lib/dbm/dumb.py | 7 +- Lib/distutils/command/wininst-14.0-amd64.exe | Bin 589824 -> 587776 bytes Lib/distutils/command/wininst-14.0.exe | Bin 460288 -> 458240 bytes Lib/distutils/tests/test_bdist_rpm.py | 2 +- Lib/enum.py | 17 +- Lib/functools.py | 14 +- Lib/getpass.py | 1 - Lib/idlelib/colorizer.py | 13 +- Lib/idlelib/help.html | 2 +- Lib/idlelib/pyshell.py | 6 +- Lib/imaplib.py | 2 +- Lib/importlib/_bootstrap_external.py | 2 - Lib/inspect.py | 1 - Lib/logging/__init__.py | 11 +- Lib/mailbox.py | 21 +- Lib/multiprocessing/context.py | 2 +- Lib/multiprocessing/spawn.py | 2 +- Lib/pathlib.py | 6 +- Lib/platform.py | 6 +- Lib/pstats.py | 13 +- Lib/pydoc_data/topics.py | 337 ++-- Lib/random.py | 2 +- Lib/secrets.py | 2 + Lib/shlex.py | 10 +- Lib/shutil.py | 82 +- Lib/site-packages/README | 2 - Lib/sqlite3/test/transactions.py | 9 + Lib/sqlite3/test/types.py | 3 +- Lib/subprocess.py | 11 +- Lib/tarfile.py | 31 +- Lib/test/_test_multiprocessing.py | 13 + Lib/test/datetimetester.py | 41 + Lib/test/eintrdata/eintr_tester.py | 4 + Lib/test/libregrtest/cmdline.py | 4 +- Lib/test/mod_generics_cache.py | 14 + Lib/test/mp_preload.py | 18 + Lib/test/regrtest.py | 0 Lib/test/support/__init__.py | 44 +- Lib/test/support/script_helper.py | 25 +- Lib/test/test___all__.py | 11 - Lib/test/test_aifc.py | 18 +- Lib/test/test_argparse.py | 17 + Lib/test/test_asyncio/test_events.py | 22 + Lib/test/test_asyncio/test_futures.py | 29 + Lib/test/test_asyncio/test_subprocess.py | 24 + Lib/test/test_asyncio/test_tasks.py | 17 + Lib/test/test_asyncore.py | 7 +- Lib/test/test_base64.py | 8 + Lib/test/test_builtin.py | 10 + Lib/test/test_bytes.py | 13 + Lib/test/test_cmd_line.py | 9 +- Lib/test/test_cmd_line_script.py | 100 ++ Lib/test/test_compile.py | 3 + Lib/test/test_complex.py | 23 + Lib/test/test_configparser.py | 12 +- Lib/test/test_coroutines.py | 38 + Lib/test/test_curses.py | 32 +- Lib/test/test_dbm_dumb.py | 16 + Lib/test/test_descr.py | 90 ++ Lib/test/test_email/test_email.py | 12 + Lib/test/test_enum.py | 90 +- Lib/test/test_fileio.py | 20 +- Lib/test/test_format.py | 67 +- Lib/test/test_fstring.py | 20 +- Lib/test/test_functools.py | 49 +- Lib/test/test_future.py | 63 +- Lib/test/test_genericpath.py | 3 + Lib/test/test_global.py | 6 +- Lib/test/test_imaplib.py | 330 ++++ Lib/test/test_importlib/test_locks.py | 2 +- Lib/test/test_inspect.py | 5 + Lib/test/test_locale.py | 4 +- Lib/test/test_logging.py | 94 +- Lib/test/test_mailbox.py | 4 +- Lib/test/test_nntplib.py | 2 + Lib/test/test_ordered_dict.py | 8 + Lib/test/test_pathlib.py | 18 +- Lib/test/test_platform.py | 12 +- Lib/test/test_posix.py | 6 + Lib/test/test_pow.py | 3 - Lib/test/test_pwd.py | 26 +- Lib/test/test_re.py | 12 +- Lib/test/test_regrtest.py | 2 + Lib/test/test_resource.py | 14 + Lib/test/test_secrets.py | 1 + Lib/test/test_shlex.py | 8 + Lib/test/test_shutil.py | 99 +- Lib/test/test_site.py | 40 +- Lib/test/test_socket.py | 29 +- Lib/test/test_stat.py | 3 +- Lib/test/test_struct.py | 4 + Lib/test/test_subprocess.py | 56 + Lib/test/test_support.py | 2 +- Lib/test/test_symtable.py | 8 +- Lib/test/test_syntax.py | 9 +- Lib/test/test_sysconfig.py | 11 +- Lib/test/test_threading.py | 5 +- Lib/test/test_typing.py | 419 ++++- Lib/test/test_unicode.py | 18 +- Lib/test/test_urllib.py | 3 +- Lib/test/test_uuid.py | 4 + Lib/test/test_venv.py | 22 +- Lib/test/test_weakref.py | 53 + Lib/test/test_winconsoleio.py | 46 +- Lib/test/test_winreg.py | 14 +- Lib/test/test_xml_etree_c.py | 10 + Lib/threading.py | 4 + Lib/timeit.py | 2 +- Lib/tkinter/tix.py | 4 - Lib/typing.py | 281 +++- Lib/unittest/loader.py | 8 +- Lib/unittest/mock.py | 15 +- Lib/unittest/test/test_loader.py | 8 +- Lib/unittest/test/testmock/testhelpers.py | 5 + Lib/unittest/test/testmock/testmock.py | 17 +- Lib/urllib/request.py | 1 + Lib/venv/__init__.py | 19 +- Lib/venv/scripts/{posix => common}/activate | 0 Lib/venv/scripts/nt/Activate.ps1 | 18 +- Lib/weakref.py | 49 +- Lib/zipfile.py | 5 +- Mac/BuildScript/build-installer.py | 19 +- Mac/BuildScript/openssl_sdk_makedepend.patch | 2 +- Mac/IDLE/IDLE.app/Contents/Info.plist | 2 +- Mac/PythonLauncher/Info.plist.in | 2 +- Mac/Resources/app/Info.plist.in | 2 +- Mac/Resources/framework/Info.plist.in | 4 +- Makefile.pre.in | 16 +- Misc/ACKS | 12 +- Misc/HISTORY | 2246 +++++++++++++++++++++++++- Misc/NEWS | 1983 +++++++++++++++++++++-- Modules/_asynciomodule.c | 37 +- Modules/_collectionsmodule.c | 2 +- Modules/_ctypes/_ctypes_test.c | 13 + Modules/_ctypes/libffi_msvc/ffi.c | 10 + Modules/_datetimemodule.c | 71 +- Modules/_decimal/_decimal.c | 14 +- Modules/_elementtree.c | 2 + Modules/_functoolsmodule.c | 112 +- Modules/_io/_iomodule.c | 2 +- Modules/_io/fileio.c | 34 +- Modules/_io/textio.c | 2 +- Modules/_io/winconsoleio.c | 73 +- Modules/_json.c | 15 +- Modules/_pickle.c | 18 +- Modules/_randommodule.c | 8 +- Modules/_sqlite/cursor.c | 9 +- Modules/_sqlite/statement.c | 12 +- Modules/_sqlite/statement.h | 2 +- Modules/_sre.c | 9 +- Modules/_ssl.c | 4 +- Modules/_testbuffer.c | 3 +- Modules/_weakref.c | 41 + Modules/binascii.c | 4 +- Modules/clinic/_asynciomodule.c.h | 6 +- Modules/clinic/_weakref.c.h | 32 +- Modules/clinic/binascii.c.h | 4 +- Modules/clinic/posixmodule.c.h | 5 +- Modules/getbuildinfo.c | 46 +- Modules/main.c | 67 +- Modules/makesetup | 2 +- Modules/posixmodule.c | 121 +- Modules/resource.c | 64 +- Modules/timemodule.c | 2 +- Modules/xxlimited.c | 2 +- Modules/zlib/ChangeLog | 55 +- Modules/zlib/Makefile.in | 232 ++- Modules/zlib/README | 6 +- Modules/zlib/adler32.c | 21 +- Modules/zlib/compress.c | 42 +- Modules/zlib/configure | 134 +- Modules/zlib/crc32.c | 41 +- Modules/zlib/deflate.c | 802 +++++---- Modules/zlib/deflate.h | 35 +- Modules/zlib/gzguts.h | 23 +- Modules/zlib/gzlib.c | 31 +- Modules/zlib/gzread.c | 156 +- Modules/zlib/gzwrite.c | 332 ++-- Modules/zlib/infback.c | 4 +- Modules/zlib/inffast.c | 85 +- Modules/zlib/inflate.c | 123 +- Modules/zlib/inflate.h | 11 +- Modules/zlib/inftrees.c | 26 +- Modules/zlib/trees.c | 99 +- Modules/zlib/uncompr.c | 98 +- Modules/zlib/zconf.h | 41 +- Modules/zlib/zconf.h.cmakein | 41 +- Modules/zlib/zconf.h.in | 41 +- Modules/zlib/zlib.3 | 72 +- Modules/zlib/zlib.h | 452 ++++-- Modules/zlib/zlib.map | 177 +- Modules/zlib/zutil.c | 49 +- Modules/zlib/zutil.h | 52 +- Objects/abstract.c | 2 +- Objects/bytearrayobject.c | 22 +- Objects/bytesobject.c | 25 +- Objects/codeobject.c | 30 +- Objects/complexobject.c | 6 +- Objects/dictobject.c | 159 +- Objects/memoryobject.c | 2 +- Objects/odictobject.c | 2 +- Objects/sliceobject.c | 78 +- Objects/unicodeobject.c | 27 +- Objects/weakrefobject.c | 2 + PC/bdist_wininst/install.c | 2 +- PC/getpathp.c | 2 +- PC/msvcrtmodule.c | 47 +- PC/python3.def | 136 +- PC/winreg.c | 13 +- PCbuild/_freeze_importlib.vcxproj | 37 +- PCbuild/build.bat | 8 +- PCbuild/get_externals.bat | 2 +- PCbuild/pcbuild.proj | 10 +- PCbuild/python.props | 2 +- PCbuild/pythoncore.vcxproj | 24 +- PCbuild/readme.txt | 2 +- Parser/tokenizer.c | 2 +- Python/ast.c | 11 +- Python/bltinmodule.c | 5 +- Python/ceval.c | 36 +- Python/compile.c | 5 +- Python/errors.c | 17 +- Python/fileutils.c | 10 +- Python/getcopyright.c | 2 +- Python/importlib.h | 2 +- Python/importlib_external.h | 111 +- Python/pythonrun.c | 2 +- Python/random.c | 276 +++- Python/sysmodule.c | 6 +- README | 233 --- README.rst | 247 +++ Tools/README | 2 +- Tools/gdb/libpython.py | 20 +- Tools/importbench/README | 2 +- Tools/msi/buildrelease.bat | 4 +- Tools/msi/exe/exe_files.wxs | 3 - Tools/msi/make_zip.proj | 9 +- Tools/msi/make_zip.py | 13 +- Tools/msi/uploadrelease.bat | 31 +- Tools/msi/uploadrelease.proj | 34 +- Tools/nuget/make_pkg.proj | 8 +- configure | 175 +- configure.ac | 111 +- pyconfig.h.in | 7 +- setup.py | 12 +- 383 files changed, 12401 insertions(+), 4252 deletions(-) create mode 100644 .gitignore rename Doc/{README.txt => README.rst} (83%) delete mode 100644 Doc/library/hashlib-blake2.rst delete mode 100644 Lib/site-packages/README create mode 100644 Lib/test/mod_generics_cache.py create mode 100644 Lib/test/mp_preload.py mode change 100644 => 100755 Lib/test/regrtest.py mode change 100644 => 100755 Lib/timeit.py rename Lib/venv/scripts/{posix => common}/activate (100%) delete mode 100644 README create mode 100644 README.rst diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed4ebfb --- /dev/null +++ b/.gitignore @@ -0,0 +1,96 @@ +# Two-trick pony for OSX and other case insensitive file systems: +# Ignore ./python binary on Unix but still look into ./Python/ directory. +/python +!/Python/ +*.cover +*.o +*.orig +*.pyc +*.pyd +*.pyo +*.rej +*.swp +*~ +*.gc?? +*.profclang? +*.profraw +*.dyn +.gdb_history +Doc/build/ +Doc/venv/ +Lib/distutils/command/*.pdb +Lib/lib2to3/*.pickle +Lib/test/data/* +Makefile +Makefile.pre +Misc/python.pc +Misc/python-config.sh +Modules/Setup +Modules/Setup.config +Modules/Setup.local +Modules/config.c +Modules/ld_so_aix +Programs/_freeze_importlib +Programs/_testembed +PC/python_nt*.h +PC/pythonnt_rc*.h +PC/*/*.exe +PC/*/*.exp +PC/*/*.lib +PC/*/*.bsc +PC/*/*.dll +PC/*/*.pdb +PC/*/*.user +PC/*/*.ncb +PC/*/*.suo +PC/*/Win32-temp-* +PC/*/x64-temp-* +PC/*/amd64 +PCbuild/*.user +PCbuild/*.suo +PCbuild/*.*sdf +PCbuild/*-pgi +PCbuild/*-pgo +PCbuild/.vs/ +PCbuild/amd64/ +PCbuild/obj/ +PCBuild/win32/ +.purify +Parser/pgen +__pycache__ +autom4te.cache +build/ +buildno +config.cache +config.log +config.status +config.status.lineno +core +db_home +.hg/ +ipch/ +libpython*.a +libpython*.so* +libpython*.dylib +platform +pybuilddir.txt +pyconfig.h +python-config +python-config.py +python.bat +python.exe +python-gdb.py +python.exe-gdb.py +reflog.txt +.svn/ +tags +TAGS +.coverage +coverage/ +externals/ +htmlcov/ +Tools/msi/obj +Tools/ssl/amd64 +Tools/ssl/win32 +.vs/ +.vscode/ diff --git a/Doc/Makefile b/Doc/Makefile index 91f937f..94697f9 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -4,13 +4,13 @@ # # You can set these variables from the command line. -PYTHON = python +PYTHON = python3 SPHINXBUILD = sphinx-build PAPER = SOURCES = DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py) -ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_paper_size=$(PAPER) \ +ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_elements.papersize=$(PAPER) \ $(SPHINXOPTS) . build/$(BUILDER) $(SOURCES) .PHONY: help build html htmlhelp latex text changes linkcheck \ @@ -153,7 +153,7 @@ dist: cp -pPR build/epub/Python.epub dist/python-$(DISTVERSION)-docs.epub check: - $(PYTHON) tools/rstlint.py -i tools -i venv + $(PYTHON) tools/rstlint.py -i tools -i venv -i README.rst serve: ../Tools/scripts/serve.py build/html diff --git a/Doc/README.txt b/Doc/README.rst similarity index 83% rename from Doc/README.txt rename to Doc/README.rst index 4f8e9f8..dcd3d6e 100644 --- a/Doc/README.txt +++ b/Doc/README.rst @@ -2,20 +2,21 @@ Python Documentation README ~~~~~~~~~~~~~~~~~~~~~~~~~~~ This directory contains the reStructuredText (reST) sources to the Python -documentation. You don't need to build them yourself, prebuilt versions are -available at . +documentation. You don't need to build them yourself, `prebuilt versions are +available `_. Documentation on authoring Python documentation, including information about -both style and markup, is available in the "Documenting Python" chapter of the -developers guide . +both style and markup, is available in the "`Documenting Python +`_" chapter of the +developers guide. Building the docs ================= -You need to have Sphinx installed; it is the toolset +You need to have `Sphinx `_ installed; it is the toolset used to build the docs. It is not included in this tree, but maintained -separately and available from PyPI . +separately and `available from PyPI `_. Using make @@ -108,11 +109,11 @@ see the make targets above). Contributing ============ -Bugs in the content should be reported to the Python bug tracker at -https://bugs.python.org. +Bugs in the content should be reported to the +`Python bug tracker `_. -Bugs in the toolset should be reported in the Sphinx bug tracker at -https://www.bitbucket.org/birkenfeld/sphinx/issues/. +Bugs in the toolset should be reported in the +`Sphinx bug tracker `_. You can also send a mail to the Python Documentation Team at docs@python.org, and we will process your request as soon as possible. diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index ee51791..037b85c 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -396,7 +396,7 @@ Querying the error indicator by code that needs to save and restore the error indicator temporarily, e.g.:: { - PyObject **type, **value, **traceback; + PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); /* ... code that might produce other errors ... */ diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 837ac7d..f481193 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -150,9 +150,8 @@ specific C type of the *self* object. The :attr:`ml_flags` field is a bitfield which can include the following flags. The individual flags indicate either a calling convention or a binding convention. Of the calling convention flags, only :const:`METH_VARARGS` and -:const:`METH_KEYWORDS` can be combined (but note that :const:`METH_KEYWORDS` -alone is equivalent to ``METH_VARARGS | METH_KEYWORDS``). Any of the calling -convention flags can be combined with a binding flag. +:const:`METH_KEYWORDS` can be combined. Any of the calling convention flags +can be combined with a binding flag. .. data:: METH_VARARGS @@ -169,7 +168,7 @@ convention flags can be combined with a binding flag. Methods with these flags must be of type :c:type:`PyCFunctionWithKeywords`. The function expects three parameters: *self*, *args*, and a dictionary of - all the keyword arguments. The flag is typically combined with + all the keyword arguments. The flag must be combined with :const:`METH_VARARGS`, and the parameters are typically processed using :c:func:`PyArg_ParseTupleAndKeywords`. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 323f017..ac6fd0b 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -199,8 +199,9 @@ type objects) *must* have the :attr:`ob_size` field. This field is deprecated. When it is defined, it should point to a function that acts the same as the :c:member:`~PyTypeObject.tp_getattro` function, but taking a C string - instead of a Python string object to give the attribute name. The signature is - the same as for :c:func:`PyObject_GetAttrString`. + instead of a Python string object to give the attribute name. The signature is :: + + PyObject * tp_getattr(PyObject *o, char *attr_name); This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when @@ -213,10 +214,11 @@ type objects) *must* have the :attr:`ob_size` field. This field is deprecated. When it is defined, it should point to a function that acts the same as the :c:member:`~PyTypeObject.tp_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`, but setting - *v* to *NULL* to delete an attribute must be supported. + instead of a Python string object to give the attribute name. The signature is :: + + PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v); + The *v* argument is set to *NULL* to delete the attribute. This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*. diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index c11e049..02f7ada 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -942,26 +942,6 @@ wchar_t Support .. versionadded:: 3.2 -UCS4 Support -"""""""""""" - -.. versionadded:: 3.3 - -.. XXX are these meant to be public? - -.. c:function:: size_t Py_UCS4_strlen(const Py_UCS4 *u) - Py_UCS4* Py_UCS4_strcpy(Py_UCS4 *s1, const Py_UCS4 *s2) - Py_UCS4* Py_UCS4_strncpy(Py_UCS4 *s1, const Py_UCS4 *s2, size_t n) - Py_UCS4* Py_UCS4_strcat(Py_UCS4 *s1, const Py_UCS4 *s2) - int Py_UCS4_strcmp(const Py_UCS4 *s1, const Py_UCS4 *s2) - int Py_UCS4_strncmp(const Py_UCS4 *s1, const Py_UCS4 *s2, size_t n) - Py_UCS4* Py_UCS4_strchr(const Py_UCS4 *s, Py_UCS4 c) - Py_UCS4* Py_UCS4_strrchr(const Py_UCS4 *s, Py_UCS4 c) - - These utility functions work on strings of :c:type:`Py_UCS4` characters and - otherwise behave like the C standard library functions with the same name. - - .. _builtincodecs: Built-in Codecs @@ -1668,10 +1648,6 @@ They all return *NULL* or ``-1`` if an exception occurs. * :const:`Py_True` or :const:`Py_False` for successful comparisons * :const:`Py_NotImplemented` in case the type combination is unknown - Note that :const:`Py_EQ` and :const:`Py_NE` comparisons can cause a - :exc:`UnicodeWarning` in case the conversion of the arguments to Unicode fails - with a :exc:`UnicodeDecodeError`. - Possible values for *op* are :const:`Py_GT`, :const:`Py_GE`, :const:`Py_EQ`, :const:`Py_NE`, :const:`Py_LT`, and :const:`Py_LE`. diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index d0ceb05..6ab5942 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -300,12 +300,13 @@ the same library that the Python runtime is using. set to *NULL*. -.. c:function:: PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *closure) +.. c:function:: PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) Evaluate a precompiled code object, given a particular environment for its evaluation. This environment consists of a dictionary of global variables, a mapping object of local variables, arrays of arguments, keywords and - defaults, and a closure tuple of cells. + defaults, a dictionary of default values for :ref:`keyword-only\ + ` arguments and a closure tuple of cells. .. c:type:: PyFrameObject diff --git a/Doc/conf.py b/Doc/conf.py index b1bb620..18aebb6 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -37,7 +37,7 @@ highlight_language = 'python3' needs_sphinx = '1.2' # Ignore any .rst files in the venv/ directory. -exclude_patterns = ['venv/*'] +exclude_patterns = ['venv/*', 'README.rst'] # Options for HTML output @@ -88,11 +88,24 @@ html_split_index = True # Options for LaTeX output # ------------------------ +# Get LaTeX to handle Unicode correctly +latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''} + +# Additional stuff for the LaTeX preamble. +latex_elements['preamble'] = r''' +\authoraddress{ + \strong{Python Software Foundation}\\ + Email: \email{docs@python.org} +} +\let\Verbatim=\OriginalVerbatim +\let\endVerbatim=\endOriginalVerbatim +''' + # The paper size ('letter' or 'a4'). -latex_paper_size = 'a4' +latex_elements['papersize'] = 'a4' # The font size ('10pt', '11pt' or '12pt'). -latex_font_size = '10pt' +latex_elements['font_size'] = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). @@ -125,22 +138,9 @@ latex_documents.extend(('howto/' + fn[:-4], 'howto-' + fn[:-4] + '.tex', for fn in os.listdir('howto') if fn.endswith('.rst') and fn != 'index.rst') -# Additional stuff for the LaTeX preamble. -latex_preamble = r''' -\authoraddress{ - \strong{Python Software Foundation}\\ - Email: \email{docs@python.org} -} -\let\Verbatim=\OriginalVerbatim -\let\endVerbatim=\endOriginalVerbatim -''' - # Documents to append as an appendix to all manuals. latex_appendices = ['glossary', 'about', 'license', 'copyright'] -# Get LaTeX to handle Unicode correctly -latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''} - # Options for Epub output # ----------------------- diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst index 28ad128..44556e3 100644 --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -173,7 +173,7 @@ name of all sections describing a repository. Each section describing a repository defines three variables: - *repository*, that defines the url of the PyPI server. Defaults to - ``https://www.python.org/pypi``. + ``https://upload.pypi.org/legacy/``. - *username*, which is the registered username on the PyPI server. - *password*, that will be used to authenticate. If omitted the user will be prompt to type it when needed. diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index f1e33af..8f6a907 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -159,7 +159,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/downloads/. The latest development sources can be obtained -via anonymous Mercurial access at https://hg.python.org/cpython. +at https://github.com/python/cpython/. The source distribution is a gzipped tar file containing the complete C source, Sphinx-formatted documentation, Python library modules, example programs, and @@ -222,8 +222,8 @@ 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. -You can also access the development version of Python through Mercurial. See -https://docs.python.org/devguide/faq.html for details. +You can also access the development version of Python through Git. See +`The Python Developer's Guide `_ for details. How do I submit bug reports and patches for Python? diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 98a28c3..477d8c6 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -77,6 +77,16 @@ for Python allow you to write GTK+ 3 applications. There is also a The older PyGtk bindings for the `Gtk+ 2 toolkit `_ have been implemented by James Henstridge; see . +Kivy +---- + +`Kivy `_ is a cross-platform GUI library supporting both +desktop operating systems (Windows, macOS, Linux) and mobile devices (Android, +iOS). It is written in Python and Cython, and can use a range of windowing +backends. + +Kivy is free and open source software distributed under the MIT license. + FLTK ---- diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst index d725343..6ac83e4 100644 --- a/Doc/faq/windows.rst +++ b/Doc/faq/windows.rst @@ -300,9 +300,10 @@ this respect, and is easily configured to use spaces: Take :menuselection:`Tools --> Options --> Tabs`, and for file type "Default" set "Tab size" and "Indent size" to 4, and select the "Insert spaces" radio button. -If you suspect mixed tabs and spaces are causing problems in leading whitespace, -run Python with the :option:`-t` switch or run ``Tools/Scripts/tabnanny.py`` to -check a directory tree in batch mode. +Python raises :exc:`IndentationError` or :exc:`TabError` if mixed tabs +and spaces are causing problems in leading whitespace. +You may also run the :mod:`tabnanny` module to check a directory tree +in batch mode. How do I check for a keypress without blocking? diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 4742d84..eaab20a 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1,3 +1,5 @@ +.. highlightlang:: c + ********************** Argument Clinic How-To ********************** @@ -78,17 +80,23 @@ Basic Concepts And Usage ======================== Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. -If you run that script, specifying a C file as an argument:: +If you run that script, specifying a C file as an argument: + +.. code-block:: shell-session - % python3 Tools/clinic/clinic.py foo.c + $ python3 Tools/clinic/clinic.py foo.c Argument Clinic will scan over the file looking for lines that -look exactly like this:: +look exactly like this: + +.. code-block:: none /*[clinic input] When it finds one, it reads everything up to a line that looks -exactly like this:: +exactly like this: + +.. code-block:: none [clinic start generated code]*/ @@ -99,7 +107,9 @@ lines, are collectively called an Argument Clinic "block". When Argument Clinic parses one of these blocks, it generates output. This output is rewritten into the C file immediately after the block, followed by a comment containing a checksum. -The Argument Clinic block now looks like this:: +The Argument Clinic block now looks like this: + +.. code-block:: none /*[clinic input] ... clinic input goes here ... @@ -375,15 +385,10 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ -12. Save and close the file, then run ``Tools/clinic/clinic.py`` on it. - With luck everything worked and your block now has output! Reopen - the file in your text editor to see:: - - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +12. Save and close the file, then run ``Tools/clinic/clinic.py`` on + it. With luck everything worked---your block now has output, and + a ``.c.h`` file has been generated! Reopen the file in your + text editor to see:: /*[clinic input] _pickle.Pickler.dump @@ -395,18 +400,20 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ - PyDoc_STRVAR(_pickle_Pickler_dump__doc__, - "Write a pickled representation of obj to the open file.\n" - "\n" - ... static PyObject * - _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) - /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) + /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ Obviously, if Argument Clinic didn't produce any output, it's because it found an error in your input. Keep fixing your errors and retrying until Argument Clinic processes your file without complaint. + For readability, most of the glue code has been generated to a ``.c.h`` + file. You'll need to include that in your original ``.c`` file, + typically right after the clinic module block:: + + #include "clinic/_pickle.c.h" + 13. Double-check that the argument-parsing code Argument Clinic generated looks basically the same as the existing code. @@ -1027,7 +1034,9 @@ that value, and an error has been set (``PyErr_Occurred()`` returns a true value), then the generated code will propagate the error. Otherwise it will encode the value you return like normal. -Currently Argument Clinic supports only a few return converters:: +Currently Argument Clinic supports only a few return converters: + +.. code-block:: none bool int @@ -1606,7 +1615,9 @@ code probably looks like this:: #endif /* HAVE_FUNCTIONNAME */ And then in the ``PyMethodDef`` structure at the bottom the existing code -will have:: +will have: + +.. code-block:: none #ifdef HAVE_FUNCTIONNAME {'functionname', ... }, @@ -1656,7 +1667,9 @@ extra code when using the "block" output preset? It can't go in the output bloc because that could be deactivated by the ``#ifdef``. (That's the whole point!) In this situation, Argument Clinic writes the extra code to the "buffer" destination. -This may mean that you get a complaint from Argument Clinic:: +This may mean that you get a complaint from Argument Clinic: + +.. code-block:: none Warning in file "Modules/posixmodule.c" on line 12357: Destination buffer 'buffer' not empty at end of file, emptying. @@ -1676,7 +1689,9 @@ wouldn't make any sense to the Python interpreter. But using Argument Clinic to run Python blocks lets you use Python as a Python preprocessor! Since Python comments are different from C comments, Argument Clinic -blocks embedded in Python files look slightly different. They look like this:: +blocks embedded in Python files look slightly different. They look like this: + +.. code-block:: python3 #/*[python input] #print("def foo(): pass") diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index f962cd8..bb79bb1 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -2165,8 +2165,8 @@ Speaking logging messages ------------------------- There might be situations when it is desirable to have logging messages rendered -in an audible rather than a visible format. This is easy to do if you have text- -to-speech (TTS) functionality available in your system, even if it doesn't have +in an audible rather than a visible format. This is easy to do if you have +text-to-speech (TTS) functionality available in your system, even if it doesn't have a Python binding. Most TTS systems have a command line program you can run, and this can be invoked from a handler using :mod:`subprocess`. It's assumed here that TTS command line programs won't expect to interact with users or take a diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index 696f8e7..8562d23 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -17,7 +17,8 @@ Porting Python 2 Code to Python 3 please see :ref:`cporting-howto`. If you would like to read one core Python developer's take on why Python 3 - came into existence, you can read Nick Coghlan's `Python 3 Q & A`_. + came into existence, you can read Nick Coghlan's `Python 3 Q & A`_ or + Brett Cannon's `Why Python 3 exists`_. For help with porting, you can email the python-porting_ mailing list with questions. @@ -32,8 +33,7 @@ are: #. Make sure you have good test coverage (coverage.py_ can help; ``pip install coverage``) #. Learn the differences between Python 2 & 3 -#. Use Modernize_ or Futurize_ to update your code (``pip install modernize`` or - ``pip install future``, respectively) +#. Use Futurize_ (or Modernize_) to update your code (e.g. ``pip install future``) #. Use Pylint_ to help make sure you don't regress on your Python 3 support (``pip install pylint``) #. Use caniusepython3_ to find out which of your dependencies are blocking your @@ -41,10 +41,9 @@ are: #. Once your dependencies are no longer blocking you, use continuous integration to make sure you stay compatible with Python 2 & 3 (tox_ can help test against multiple versions of Python; ``pip install tox``) - -If you are dropping support for Python 2 entirely, then after you learn the -differences between Python 2 & 3 you can run 2to3_ over your code and skip the -rest of the steps outlined above. +#. Consider using optional static type checking to make sure your type usage + works in both Python 2 & 3 (e.g. use mypy_ to check your typing under both + Python 2 & Python 3). Details @@ -54,7 +53,7 @@ A key point about supporting Python 2 & 3 simultaneously is that you can start **today**! Even if your dependencies are not supporting Python 3 yet that does not mean you can't modernize your code **now** to support Python 3. Most changes required to support Python 3 lead to cleaner code using newer practices even in -Python 2. +Python 2 code. Another key point is that modernizing your Python 2 code to also support Python 3 is largely automated for you. While you might have to make some API @@ -82,12 +81,13 @@ have to import a function instead of using a built-in one, but otherwise the overall transformation should not feel foreign to you. But you should aim for only supporting Python 2.7. Python 2.6 is no longer -supported and thus is not receiving bugfixes. This means **you** will have to -work around any issues you come across with Python 2.6. There are also some +freely supported and thus is not receiving bugfixes. This means **you** will have +to work around any issues you come across with Python 2.6. There are also some tools mentioned in this HOWTO which do not support Python 2.6 (e.g., Pylint_), and this will become more commonplace as time goes on. It will simply be easier for you if you only support the versions of Python that you have to support. + Make sure you specify the proper version support in your ``setup.py`` file -------------------------------------------------------------------------- @@ -98,6 +98,7 @@ Python 3 yet you should at least have also specify each major/minor version of Python that you do support, e.g. ``Programming Language :: Python :: 2.7``. + Have good test coverage ----------------------- @@ -106,9 +107,10 @@ to, you will want to make sure your test suite has good coverage. A good rule of thumb is that if you want to be confident enough in your test suite that any failures that appear after having tools rewrite your code are actual bugs in the tools and not in your code. If you want a number to aim for, try to get over 80% -coverage (and don't feel bad if you can't easily get past 90%). If you -don't already have a tool to measure test coverage then coverage.py_ is -recommended. +coverage (and don't feel bad if you find it hard to get better than 90% +coverage). If you don't already have a tool to measure test coverage then +coverage.py_ is recommended. + Learn the differences between Python 2 & 3 ------------------------------------------- @@ -127,13 +129,15 @@ Update your code Once you feel like you know what is different in Python 3 compared to Python 2, it's time to update your code! You have a choice between two tools in porting -your code automatically: Modernize_ and Futurize_. Which tool you choose will +your code automatically: Futurize_ and Modernize_. Which tool you choose will depend on how much like Python 3 you want your code to be. Futurize_ does its best to make Python 3 idioms and practices exist in Python 2, e.g. backporting the ``bytes`` type from Python 3 so that you have semantic parity between the major versions of Python. Modernize_, on the other hand, is more conservative and targets a Python 2/3 subset of -Python, relying on six_ to help provide compatibility. +Python, directly relying on six_ to help provide compatibility. As Python 3 is +the future, it might be best to consider Futurize to begin adjusting to any new +practices that Python 3 introduces which you are not accustomed to yet. Regardless of which tool you choose, they will update your code to run under Python 3 while staying compatible with the version of Python 2 you started with. @@ -153,6 +157,7 @@ the built-in ``open()`` function is off by default in Modernize). Luckily, though, there are only a couple of things to watch out for which can be considered large issues that may be hard to debug if not watched for. + Division ++++++++ @@ -173,6 +178,7 @@ an object defines a ``__truediv__`` method but not ``__floordiv__`` then your code would begin to fail (e.g. a user-defined class that uses ``/`` to signify some operation but not ``//`` for the same thing or at all). + Text versus binary data +++++++++++++++++++++++ @@ -189,7 +195,7 @@ To make the distinction between text and binary data clearer and more pronounced, Python 3 did what most languages created in the age of the internet have done and made text and binary data distinct types that cannot blindly be mixed together (Python predates widespread access to the internet). For any code -that only deals with text or only binary data, this separation doesn't pose an +that deals only with text or only binary data, this separation doesn't pose an issue. But for code that has to deal with both, it does mean you might have to now care about when you are using text compared to binary data, which is why this cannot be entirely automated. @@ -198,15 +204,15 @@ To start, you will need to decide which APIs take text and which take binary (it is **highly** recommended you don't design APIs that can take both due to the difficulty of keeping the code working; as stated earlier it is difficult to do well). In Python 2 this means making sure the APIs that take text can work -with ``unicode`` in Python 2 and those that work with binary data work with the -``bytes`` type from Python 3 and thus a subset of ``str`` in Python 2 (which the -``bytes`` type in Python 2 is an alias for). Usually the biggest issue is -realizing which methods exist for which types in Python 2 & 3 simultaneously +with ``unicode`` and those that work with binary data work with the +``bytes`` type from Python 3 (which is a subset of ``str`` in Python 2 and acts +as an alias for ``bytes`` type in Python 2). Usually the biggest issue is +realizing which methods exist on which types in Python 2 & 3 simultaneously (for text that's ``unicode`` in Python 2 and ``str`` in Python 3, for binary that's ``str``/``bytes`` in Python 2 and ``bytes`` in Python 3). The following table lists the **unique** methods of each data type across Python 2 & 3 (e.g., the ``decode()`` method is usable on the equivalent binary data type in -either Python 2 or 3, but it can't be used by the text data type consistently +either Python 2 or 3, but it can't be used by the textual data type consistently between Python 2 and 3 because ``str`` in Python 3 doesn't have the method). Do note that as of Python 3.5 the ``__mod__`` method was added to the bytes type. @@ -232,10 +238,11 @@ This allows your code to work with only text internally and thus eliminates having to keep track of what type of data you are working with. The next issue is making sure you know whether the string literals in your code -represent text or binary data. At minimum you should add a ``b`` prefix to any -literal that presents binary data. For text you should either use the -``from __future__ import unicode_literals`` statement or add a ``u`` prefix to -the text literal. +represent text or binary data. You should add a ``b`` prefix to any +literal that presents binary data. For text you should add a ``u`` prefix to +the text literal. (there is a :mod:`__future__` import to force all unspecified +literals to be Unicode, but usage has shown it isn't as effective as adding a +``b`` or ``u`` prefix to all literals explicitly) As part of this dichotomy you also need to be careful about opening files. Unless you have been working on Windows, there is a chance you have not always @@ -243,11 +250,13 @@ 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 binary data to be read and/or written) or text access +binary access (allowing binary data to be read and/or written) or textual access (allowing text data to be read and/or written). You should also use :func:`io.open` for opening files instead of the built-in :func:`open` function as the :mod:`io` module is consistent from Python 2 to 3 while the built-in :func:`open` function -is not (in Python 3 it's actually :func:`io.open`). +is not (in Python 3 it's actually :func:`io.open`). Do not bother with the +outdated practice of using :func:`codecs.open` as that's only necessary for +keeping compatibility with Python 2.5. The constructors of both ``str`` and ``bytes`` have different semantics for the same arguments between Python 2 & 3. Passing an integer to ``bytes`` in Python 2 @@ -274,21 +283,22 @@ To summarize: #. Make sure that your code that works with text also works with ``unicode`` and code for binary data works with ``bytes`` in Python 2 (see the table above for what methods you cannot use for each type) -#. Mark all binary literals with a ``b`` prefix, use a ``u`` prefix or - :mod:`__future__` import statement for text literals +#. Mark all binary literals with a ``b`` prefix, textual literals with a ``u`` + prefix #. Decode binary data to text as soon as possible, encode text as binary data as late as possible #. Open files using :func:`io.open` and make sure to specify the ``b`` mode when appropriate -#. Be careful when indexing binary data +#. Be careful when indexing into binary data Use feature detection instead of version detection ++++++++++++++++++++++++++++++++++++++++++++++++++ + Inevitably you will have code that has to choose what to do based on what version of Python is running. The best way to do this is with feature detection of whether the version of Python you're running under supports what you need. -If for some reason that doesn't work then you should make the version check is +If for some reason that doesn't work then you should make the version check be against Python 2 and not Python 3. To help explain this, let's look at an example. @@ -340,14 +350,12 @@ at least the following block of code at the top of it:: from __future__ import absolute_import from __future__ import division from __future__ import print_function - from __future__ import unicode_literals You can also run Python 2 with the ``-3`` flag to be warned about various compatibility issues your code triggers during execution. If you turn warnings into errors with ``-Werror`` then you can make sure that you don't accidentally miss a warning. - You can also use the Pylint_ project and its ``--py3k`` flag to lint your code to receive warnings when your code begins to deviate from Python 3 compatibility. This also prevents you from having to run Modernize_ or Futurize_ @@ -364,22 +372,23 @@ care about whether your dependencies have also been ported. The caniusepython3_ project was created to help you determine which projects -- directly or indirectly -- are blocking you from supporting Python 3. There is both a command-line tool as well as a web interface at -https://caniusepython3.com . +https://caniusepython3.com. The project also provides code which you can integrate into your test suite so that you will have a failing test when you no longer have dependencies blocking you from using Python 3. This allows you to avoid having to manually check your dependencies and to be notified quickly when you can start running on Python 3. + Update your ``setup.py`` file to denote Python 3 compatibility -------------------------------------------------------------- Once your code works under Python 3, you should update the classifiers in your ``setup.py`` to contain ``Programming Language :: Python :: 3`` and to not -specify sole Python 2 support. This will tell -anyone using your code that you support Python 2 **and** 3. Ideally you will -also want to add classifiers for each major/minor version of Python you now -support. +specify sole Python 2 support. This will tell anyone using your code that you +support Python 2 **and** 3. Ideally you will also want to add classifiers for +each major/minor version of Python you now support. + Use continuous integration to stay compatible --------------------------------------------- @@ -404,20 +413,17 @@ don't accidentally break Python 2 or 3 compatibility regardless of which version you typically run your tests under while developing. -Dropping Python 2 support completely -==================================== - -If you are able to fully drop support for Python 2, then the steps required -to transition to Python 3 simplify greatly. - -#. Update your code to only support Python 2.7 -#. Make sure you have good test coverage (coverage.py_ can help) -#. Learn the differences between Python 2 & 3 -#. Use 2to3_ to rewrite your code to run only under Python 3 +Consider using optional static type checking +-------------------------------------------- -After this your code will be fully Python 3 compliant but in a way that is not -supported by Python 2. You should also update the classifiers in your -``setup.py`` to contain ``Programming Language :: Python :: 3 :: Only``. +Another way to help port your code is to use a static type checker like +mypy_ or pytype_ on your code. These tools can be used to analyze your code as +if it's being run under Python 2, then you can run the tool a second time as if +your code is running under Python 3. By running a static type checker twice like +this you can discover if you're e.g. misusing binary data type in one version +of Python compared to another. If you add optional type hints to your code you +can also explicitly state whether your APIs use textual or binary data, helping +to make sure everything functions as expected in both versions of Python. .. _2to3: https://docs.python.org/3/library/2to3.html @@ -428,13 +434,19 @@ supported by Python 2. You should also update the classifiers in your .. _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/ +.. _mypy: http://mypy-lang.org/ .. _Porting to Python 3: http://python3porting.com/ .. _Pylint: https://pypi.python.org/pypi/pylint + .. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.org/en/latest/python3/questions_and_answers.html +.. _pytype: https://github.com/google/pytype .. _python-future: http://python-future.org/ .. _python-porting: https://mail.python.org/mailman/listinfo/python-porting .. _six: https://pypi.python.org/pypi/six .. _tox: https://pypi.python.org/pypi/tox .. _trove classifier: https://pypi.python.org/pypi?%3Aaction=list_classifiers + .. _"What's New": https://docs.python.org/3/whatsnew/index.html + +.. _Why Python 3 exists: http://www.snarky.ca/why-python-3-exists diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 712b4b7..18b5c65 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -578,7 +578,7 @@ Footnotes This document was reviewed and revised by John Lee. .. [#] Google for example. -.. [#] Browser sniffing is a very bad practise for website design - building +.. [#] Browser sniffing is a very bad practice for website design - building sites using web standards is much more sensible. Unfortunately a lot of sites still send different versions to different browsers. .. [#] The user agent for MSIE 6 is diff --git a/Doc/includes/setup.py b/Doc/includes/setup.py index b853d23..a38a39d 100644 --- a/Doc/includes/setup.py +++ b/Doc/includes/setup.py @@ -5,4 +5,5 @@ setup(name="noddy", version="1.0", Extension("noddy2", ["noddy2.c"]), Extension("noddy3", ["noddy3.c"]), Extension("noddy4", ["noddy4.c"]), + Extension("shoddy", ["shoddy.c"]), ]) diff --git a/Doc/includes/shoddy.c b/Doc/includes/shoddy.c index 07a2721..0c6d412 100644 --- a/Doc/includes/shoddy.c +++ b/Doc/includes/shoddy.c @@ -31,7 +31,7 @@ Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds) static PyTypeObject ShoddyType = { - PyObject_HEAD_INIT(NULL) + PyVarObject_HEAD_INIT(NULL, 0) "shoddy.Shoddy", /* tp_name */ sizeof(Shoddy), /* tp_basicsize */ 0, /* tp_itemsize */ diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index c6b2bf6..4530304 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -174,7 +174,7 @@ ArgumentParser objects * conflict_handler_ - The strategy for resolving conflicting optionals (usually unnecessary) - * add_help_ - Add a -h/--help option to the parser (default: ``True``) + * add_help_ - Add a ``-h/--help`` option to the parser (default: ``True``) * allow_abbrev_ - Allows long options to be abbreviated if the abbreviation is unambiguous. (default: ``True``) @@ -211,7 +211,7 @@ The help for this program will display ``myprogram.py`` as the program name -h, --help show this help message and exit --foo FOO foo help $ cd .. - $ python subdir\myprogram.py --help + $ python subdir/myprogram.py --help usage: myprogram.py [-h] [--foo FOO] optional arguments: diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index 3fbf510..482ffbb 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -36,7 +36,7 @@ BaseTransport Base class for transports. - .. method:: close(self) + .. method:: close() Close the transport. If the transport has a buffer for outgoing data, buffered data will be flushed asynchronously. No more data @@ -44,7 +44,7 @@ BaseTransport protocol's :meth:`connection_lost` method will be called with :const:`None` as its argument. - .. method:: is_closing(self) + .. method:: is_closing() Return ``True`` if the transport is closing or is closed. @@ -251,7 +251,7 @@ BaseSubprocessTransport if it hasn't returned, similarly to the :attr:`subprocess.Popen.returncode` attribute. - .. method:: kill(self) + .. method:: kill() Kill the subprocess, as in :meth:`subprocess.Popen.kill`. diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 9bff1c4..558d17c 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -136,17 +136,6 @@ using the :meth:`sleep` function:: loop.run_until_complete(display_date(loop)) loop.close() -The same coroutine implemented using a generator:: - - @asyncio.coroutine - def display_date(loop): - end_time = loop.time() + 5.0 - while True: - print(datetime.datetime.now()) - if (loop.time() + 1.0) >= end_time: - break - yield from asyncio.sleep(1) - .. seealso:: The :ref:`display the current date with call_later() @@ -309,9 +298,8 @@ Example combining a :class:`Future` and a :ref:`coroutine function import asyncio - @asyncio.coroutine - def slow_operation(future): - yield from asyncio.sleep(1) + async def slow_operation(future): + await asyncio.sleep(1) future.set_result('Future is done!') loop = asyncio.get_event_loop() @@ -341,9 +329,8 @@ flow:: import asyncio - @asyncio.coroutine - def slow_operation(future): - yield from asyncio.sleep(1) + async def slow_operation(future): + await asyncio.sleep(1) future.set_result('Future is done!') def got_result(future): @@ -472,21 +459,20 @@ Example executing 3 tasks (A, B, C) in parallel:: import asyncio - @asyncio.coroutine - def factorial(name, number): + async def factorial(name, number): f = 1 for i in range(2, number+1): print("Task %s: Compute factorial(%s)..." % (name, i)) - yield from asyncio.sleep(1) + await asyncio.sleep(1) f *= i print("Task %s: factorial(%s) = %s" % (name, number, f)) loop = asyncio.get_event_loop() - tasks = [ - asyncio.ensure_future(factorial("A", 2)), - asyncio.ensure_future(factorial("B", 3)), - asyncio.ensure_future(factorial("C", 4))] - loop.run_until_complete(asyncio.gather(*tasks)) + loop.run_until_complete(asyncio.gather( + factorial("A", 2), + factorial("B", 3), + factorial("C", 4), + )) loop.close() Output:: diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 080d9d7..ceecf17 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -237,14 +237,18 @@ The legacy interface: .. function:: decodebytes(s) - decodestring(s) 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 +.. function:: decodestring(s) + + Deprecated alias of :func:`decodebytes`. + + .. deprecated:: 3.1 + .. function:: encode(input, output) @@ -257,14 +261,19 @@ The legacy interface: .. function:: encodebytes(s) - encodestring(s) 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. + .. versionadded:: 3.1 + +.. function:: encodestring(s) + + Deprecated alias of :func:`encodebytes`. + + .. deprecated:: 3.1 An example usage of the module: diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 4f5f0f2..0476f50 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -116,8 +116,10 @@ The :mod:`binascii` module defines the following functions: .. function:: crc_hqx(data, value) - Compute the binhex4 crc value of *data*, starting with *value* as the - initial crc, and return the result. + Compute a 16-bit CRC value of *data*, starting with *value* as the + initial CRC, and return the result. This uses the CRC-CCITT polynomial + *x*:sup:`16` + *x*:sup:`12` + *x*:sup:`5` + 1, often represented as + 0x1021. This CRC is used in the binhex4 format. .. function:: crc32(data[, value]) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 9f3f5dc..8e2eb4d 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -1029,14 +1029,15 @@ Equality tests between :class:`OrderedDict` objects and other dictionaries. This allows :class:`OrderedDict` objects to be substituted anywhere a regular dictionary is used. -The :class:`OrderedDict` constructor and :meth:`update` method both accept -keyword arguments, but their order is lost because Python's function call -semantics pass in keyword arguments using a regular unordered dictionary. - .. versionchanged:: 3.5 The items, keys, and values :term:`views ` of :class:`OrderedDict` now support reverse iteration using :func:`reversed`. +.. versionchanged:: 3.6 + With the acceptance of :pep:`468`, order is retained for keyword arguments + passed to the :class:`OrderedDict` constructor and its :meth:`update` + method. + :class:`OrderedDict` Examples and Recipes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 8d141a2..af57cba 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -983,13 +983,16 @@ ConfigParser Objects .. method:: read(filenames, encoding=None) Attempt to read and parse a list of filenames, returning a list of - filenames which were successfully parsed. If *filenames* is a string, it - is treated as a single filename. If a file named in *filenames* cannot - be opened, that file will be ignored. This is designed so that you can - specify a list of potential configuration file locations (for example, - the current directory, the user's home directory, and some system-wide - directory), and all existing configuration files in the list will be - read. If none of the named files exist, the :class:`ConfigParser` + filenames which were successfully parsed. + + If *filenames* is a string or :term:`path-like object`, it is treated as + a single filename. If a file named in *filenames* cannot be opened, that + file will be ignored. This is designed so that you can specify a list of + potential configuration file locations (for example, the current + directory, the user's home directory, and some system-wide directory), + and all existing configuration files in the list will be read. + + If none of the named files exist, the :class:`ConfigParser` instance will contain an empty dataset. An application which requires initial values to be loaded from a file should load the required file or files using :meth:`read_file` before calling :meth:`read` for any @@ -1006,6 +1009,9 @@ ConfigParser Objects The *encoding* parameter. Previously, all files were read using the default encoding for :func:`open`. + .. versionadded:: 3.6.1 + The *filenames* parameter accepts a :term:`path-like object`. + .. method:: read_file(f, source=None) @@ -1161,20 +1167,20 @@ ConfigParser Objects Use :meth:`read_file` instead. .. versionchanged:: 3.2 - :meth:`readfp` now iterates on *f* instead of calling ``f.readline()``. + :meth:`readfp` now iterates on *fp* instead of calling ``fp.readline()``. For existing code calling :meth:`readfp` with arguments which don't support iteration, the following generator may be used as a wrapper around the file-like object:: - def readline_generator(f): - line = f.readline() + def readline_generator(fp): + line = fp.readline() while line: yield line - line = f.readline() + line = fp.readline() - Instead of ``parser.readfp(f)`` use - ``parser.read_file(readline_generator(f))``. + Instead of ``parser.readfp(fp)`` use + ``parser.read_file(readline_generator(fp))``. .. data:: MAX_INTERPOLATION_DEPTH diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst index 8eb4b81..ae45549 100644 --- a/Doc/library/crypto.rst +++ b/Doc/library/crypto.rst @@ -15,6 +15,5 @@ Here's an overview: .. toctree:: hashlib.rst - hashlib-blake2.rst hmac.rst secrets.rst diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index f916572..52a8a31 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -146,7 +146,7 @@ The :mod:`csv` module defines the following functions: The :mod:`csv` module defines the following classes: -.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, \ +.. class:: DictReader(f, fieldnames=None, restkey=None, restval=None, \ dialect='excel', *args, **kwds) Create an object that operates like a regular reader but maps the @@ -154,7 +154,7 @@ The :mod:`csv` module defines the following classes: whose keys are given by the optional *fieldnames* parameter. The *fieldnames* parameter is a :term:`sequence`. If *fieldnames* is - omitted, the values in the first row of the *csvfile* will be used as the + omitted, the values in the first row of file *f* will be used as the fieldnames. Regardless of how the fieldnames are determined, the ordered dictionary preserves their original ordering. @@ -184,14 +184,14 @@ The :mod:`csv` module defines the following classes: OrderedDict([('first_name', 'John'), ('last_name', 'Cleese')]) -.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', \ +.. class:: DictWriter(f, fieldnames, restval='', extrasaction='raise', \ dialect='excel', *args, **kwds) Create an object which operates like a regular writer but maps dictionaries onto output rows. The *fieldnames* parameter is a :mod:`sequence ` of keys that identify the order in which values in the - dictionary passed to the :meth:`writerow` method are written to the - *csvfile*. The optional *restval* parameter specifies the value to be + dictionary passed to the :meth:`writerow` method are written to file + *f*. The optional *restval* parameter specifies the value to be written if the dictionary is missing a key in *fieldnames*. If the dictionary passed to the :meth:`writerow` method contains a key not found in *fieldnames*, the optional *extrasaction* parameter indicates what action to @@ -205,7 +205,7 @@ The :mod:`csv` module defines the following classes: Note that unlike the :class:`DictReader` class, the *fieldnames* parameter of the :class:`DictWriter` is not optional. Since Python's :class:`dict` objects are not ordered, there is not enough information available to deduce - the order in which the row should be written to the *csvfile*. + the order in which the row should be written to file *f*. A short usage example:: diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 9dab353..c931855 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -1582,7 +1582,7 @@ Instance methods: Example: - >>> from datetime import time, tzinfo + >>> from datetime import time, tzinfo, timedelta >>> class GMT1(tzinfo): ... def utcoffset(self, dt): ... return timedelta(hours=1) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index a15690b..1c1e1a2 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -772,8 +772,13 @@ All of the following opcodes use their arguments. .. opcode:: BUILD_MAP (count) - Pushes a new dictionary object onto the stack. The dictionary is pre-sized - to hold *count* entries. + Pushes a new dictionary object onto the stack. Pops ``2 * count`` items + so that the dictionary holds *count* entries: + ``{..., TOS3: TOS2, TOS1: TOS}``. + + .. versionchanged:: 3.5 + The dictionary is created from stack items instead of creating an + empty dictionary pre-sized to hold *count* items. .. opcode:: BUILD_CONST_KEY_MAP (count) @@ -793,6 +798,52 @@ All of the following opcodes use their arguments. .. versionadded:: 3.6 +.. opcode:: BUILD_TUPLE_UNPACK (count) + + Pops *count* iterables from the stack, joins them in a single tuple, + and pushes the result. Implements iterable unpacking in tuple + displays ``(*x, *y, *z)``. + + .. versionadded:: 3.5 + + +.. opcode:: BUILD_LIST_UNPACK (count) + + This is similar to :opcode:`BUILD_TUPLE_UNPACK`, but pushes a list + instead of tuple. Implements iterable unpacking in list + displays ``[*x, *y, *z]``. + + .. versionadded:: 3.5 + + +.. opcode:: BUILD_SET_UNPACK (count) + + This is similar to :opcode:`BUILD_TUPLE_UNPACK`, but pushes a set + instead of tuple. Implements iterable unpacking in set + displays ``{*x, *y, *z}``. + + .. versionadded:: 3.5 + + +.. opcode:: BUILD_MAP_UNPACK (count) + + Pops *count* mappings from the stack, merges them into a single dictionary, + and pushes the result. Implements dictionary unpacking in dictionary + displays ``{**x, **y, **z}``. + + .. versionadded:: 3.5 + + +.. opcode:: BUILD_MAP_UNPACK_WITH_CALL (oparg) + + This is similar to :opcode:`BUILD_MAP_UNPACK`, + but is used for ``f(**x, **y, **z)`` call syntax. The lowest byte of + *oparg* is the count of mappings, the relative position of the + corresponding callable ``f`` is encoded in the second byte of *oparg*. + + .. versionadded:: 3.5 + + .. opcode:: LOAD_ATTR (namei) Replaces TOS with ``getattr(TOS, co_names[namei])``. diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 131206d..15b12f7 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -510,9 +510,9 @@ Option Flags A number of option flags control various aspects of doctest's behavior. Symbolic names for the flags are supplied as module constants, which can be -or'ed together and passed to various functions. The names can also be used in -:ref:`doctest directives `, and may be passed to the -doctest command line interface via the ``-o`` option. +:ref:`bitwise ORed ` together and passed to various functions. +The names can also be used in :ref:`doctest directives `, +and may be passed to the doctest command line interface via the ``-o`` option. .. versionadded:: 3.4 The ``-o`` command line option. @@ -877,8 +877,9 @@ and :ref:`doctest-simple-testfile`. nothing at the end. In verbose mode, the summary is detailed, else the summary is very brief (in fact, empty if all tests passed). - Optional argument *optionflags* (default value 0) takes the bitwise-or of - option flags. See section :ref:`doctest-options`. + Optional argument *optionflags* (default value 0) takes the + :ref:`bitwise OR ` of option flags. + See section :ref:`doctest-options`. Optional argument *raise_on_error* defaults to false. If true, an exception is raised upon the first failure or unexpected exception in an example. This @@ -1098,18 +1099,19 @@ reporting flags specific to :mod:`unittest` support, via this function: Set the :mod:`doctest` reporting flags to use. - Argument *flags* takes the bitwise-or of option flags. See section - :ref:`doctest-options`. Only "reporting flags" can be used. + Argument *flags* takes the :ref:`bitwise OR ` of option flags. See + section :ref:`doctest-options`. Only "reporting flags" can be used. This is a module-global setting, and affects all future doctests run by module :mod:`unittest`: the :meth:`runTest` method of :class:`DocTestCase` looks at the option flags specified for the test case when the :class:`DocTestCase` instance was constructed. If no reporting flags were specified (which is the typical and expected case), :mod:`doctest`'s :mod:`unittest` reporting flags are - or'ed into the option flags, and the option flags so augmented are passed to the - :class:`DocTestRunner` instance created to run the doctest. If any reporting - flags were specified when the :class:`DocTestCase` instance was constructed, - :mod:`doctest`'s :mod:`unittest` reporting flags are ignored. + :ref:`bitwise ORed ` into the option flags, and the option flags + so augmented are passed to the :class:`DocTestRunner` instance created to + run the doctest. If any reporting flags were specified when the + :class:`DocTestCase` instance was constructed, :mod:`doctest`'s + :mod:`unittest` reporting flags are ignored. The value of the :mod:`unittest` reporting flags in effect before the function was called is returned by the function. diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index 2c65079..b070764 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -33,11 +33,11 @@ having a MIME type such as :mimetype:`multipart/\*` or The conceptual model provided by a :class:`Message` object is that of an ordered dictionary of headers with additional methods for accessing both specialized information from the headers, for accessing the payload, for -generating a serialized version of the mssage, and for recursively walking over -the object tree. Note that duplicate headers are supported but special methods -must be used to access them. +generating a serialized version of the message, and for recursively walking +over the object tree. Note that duplicate headers are supported but special +methods must be used to access them. -The :class:`Message` psuedo-dictionary is indexed by the header names, which +The :class:`Message` pseudo-dictionary is indexed by the header names, which must be ASCII values. The values of the dictionary are strings that are supposed to contain only ASCII characters; there is some special handling for non-ASCII input, but it doesn't always produce the correct results. Headers @@ -181,7 +181,7 @@ Here are the methods of the :class:`Message` class: This is a legacy method. On the :class:`~email.emailmessage.EmailMessage` class its functionality is replaced by :meth:`~email.message.EmailMessage.set_content` and the - realted ``make`` and ``add`` methods. + related ``make`` and ``add`` methods. .. method:: get_payload(i=None, decode=False) diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 32852e7..d36e769 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -364,7 +364,7 @@ message objects. *header* specifies an alternative header to :mailheader:`Content-Type`. If the value contains non-ASCII characters, the charset and language may - be explicity specified using the optional *charset* and *language* + be explicitly specified using the optional *charset* and *language* parameters. Optional *language* specifies the :rfc:`2231` language, defaulting to the empty string. Both *charset* and *language* should be strings. The default is to use the ``utf8`` *charset* and ``None`` for diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index ddcc286..6548adf 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -24,8 +24,8 @@ Module Contents --------------- This module defines four enumeration classes that can be used to define unique -sets of names and values: :class:`Enum`, :class:`IntEnum`, and -:class:`IntFlags`. It also defines one decorator, :func:`unique`, and one +sets of names and values: :class:`Enum`, :class:`IntEnum`, :class:`Flag`, and +:class:`IntFlag`. It also defines one decorator, :func:`unique`, and one helper, :class:`auto`. .. class:: Enum @@ -773,7 +773,7 @@ the (unimportant) value:: Using :class:`auto` """"""""""""""""""" -Using :class:`object` would look like:: +Using :class:`auto` would look like:: >>> class Color(NoValue): ... RED = auto() diff --git a/Doc/library/hashlib-blake2.rst b/Doc/library/hashlib-blake2.rst deleted file mode 100644 index 436aa4f..0000000 --- a/Doc/library/hashlib-blake2.rst +++ /dev/null @@ -1,444 +0,0 @@ -.. _hashlib-blake2: - -:mod:`hashlib` --- BLAKE2 hash functions -======================================== - -.. module:: hashlib - :synopsis: BLAKE2 hash function for Python -.. sectionauthor:: Dmitry Chestnykh - -.. index:: - single: blake2b, blake2s - -BLAKE2_ is a cryptographic hash function defined in RFC-7693_ that comes in two -flavors: - -* **BLAKE2b**, optimized for 64-bit platforms and produces digests of any size - between 1 and 64 bytes, - -* **BLAKE2s**, optimized for 8- to 32-bit platforms and produces digests of any - size between 1 and 32 bytes. - -BLAKE2 supports **keyed mode** (a faster and simpler replacement for HMAC_), -**salted hashing**, **personalization**, and **tree hashing**. - -Hash objects from this module follow the API of standard library's -:mod:`hashlib` objects. - - -Module -====== - -Creating hash objects ---------------------- - -New hash objects are created by calling constructor functions: - - -.. function:: blake2b(data=b'', digest_size=64, key=b'', salt=b'', \ - person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ - node_depth=0, inner_size=0, last_node=False) - -.. function:: blake2s(data=b'', digest_size=32, key=b'', salt=b'', \ - person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ - node_depth=0, inner_size=0, last_node=False) - - -These functions return the corresponding hash objects for calculating -BLAKE2b or BLAKE2s. They optionally take these general parameters: - -* *data*: initial chunk of data to hash, which must be interpretable as buffer - of bytes. - -* *digest_size*: size of output digest in bytes. - -* *key*: key for keyed hashing (up to 64 bytes for BLAKE2b, up to 32 bytes for - BLAKE2s). - -* *salt*: salt for randomized hashing (up to 16 bytes for BLAKE2b, up to 8 - bytes for BLAKE2s). - -* *person*: personalization string (up to 16 bytes for BLAKE2b, up to 8 bytes - for BLAKE2s). - -The following table shows limits for general parameters (in bytes): - -======= =========== ======== ========= =========== -Hash digest_size len(key) len(salt) len(person) -======= =========== ======== ========= =========== -BLAKE2b 64 64 16 16 -BLAKE2s 32 32 8 8 -======= =========== ======== ========= =========== - -.. note:: - - BLAKE2 specification defines constant lengths for salt and personalization - parameters, however, for convenience, this implementation accepts byte - strings of any size up to the specified length. If the length of the - parameter is less than specified, it is padded with zeros, thus, for - example, ``b'salt'`` and ``b'salt\x00'`` is the same value. (This is not - the case for *key*.) - -These sizes are available as module `constants`_ described below. - -Constructor functions also accept the following tree hashing parameters: - -* *fanout*: fanout (0 to 255, 0 if unlimited, 1 in sequential mode). - -* *depth*: maximal depth of tree (1 to 255, 255 if unlimited, 1 in - sequential mode). - -* *leaf_size*: maximal byte length of leaf (0 to 2**32-1, 0 if unlimited or in - sequential mode). - -* *node_offset*: node offset (0 to 2**64-1 for BLAKE2b, 0 to 2**48-1 for - BLAKE2s, 0 for the first, leftmost, leaf, or in sequential mode). - -* *node_depth*: node depth (0 to 255, 0 for leaves, or in sequential mode). - -* *inner_size*: inner digest size (0 to 64 for BLAKE2b, 0 to 32 for - BLAKE2s, 0 in sequential mode). - -* *last_node*: boolean indicating whether the processed node is the last - one (`False` for sequential mode). - -.. figure:: hashlib-blake2-tree.png - :alt: Explanation of tree mode parameters. - -See section 2.10 in `BLAKE2 specification -`_ for comprehensive review of tree -hashing. - - -Constants ---------- - -.. data:: blake2b.SALT_SIZE -.. data:: blake2s.SALT_SIZE - -Salt length (maximum length accepted by constructors). - - -.. data:: blake2b.PERSON_SIZE -.. data:: blake2s.PERSON_SIZE - -Personalization string length (maximum length accepted by constructors). - - -.. data:: blake2b.MAX_KEY_SIZE -.. data:: blake2s.MAX_KEY_SIZE - -Maximum key size. - - -.. data:: blake2b.MAX_DIGEST_SIZE -.. data:: blake2s.MAX_DIGEST_SIZE - -Maximum digest size that the hash function can output. - - -Examples -======== - -Simple hashing --------------- - -To calculate hash of some data, you should first construct a hash object by -calling the appropriate constructor function (:func:`blake2b` or -:func:`blake2s`), then update it with the data by calling :meth:`update` on the -object, and, finally, get the digest out of the object by calling -:meth:`digest` (or :meth:`hexdigest` for hex-encoded string). - - >>> from hashlib import blake2b - >>> h = blake2b() - >>> h.update(b'Hello world') - >>> h.hexdigest() - '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183' - - -As a shortcut, you can pass the first chunk of data to update directly to the -constructor as the first argument (or as *data* keyword argument): - - >>> from hashlib import blake2b - >>> blake2b(b'Hello world').hexdigest() - '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183' - -You can call :meth:`hash.update` as many times as you need to iteratively -update the hash: - - >>> from hashlib import blake2b - >>> items = [b'Hello', b' ', b'world'] - >>> h = blake2b() - >>> for item in items: - ... h.update(item) - >>> h.hexdigest() - '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183' - - -Using different digest sizes ----------------------------- - -BLAKE2 has configurable size of digests up to 64 bytes for BLAKE2b and up to 32 -bytes for BLAKE2s. For example, to replace SHA-1 with BLAKE2b without changing -the size of output, we can tell BLAKE2b to produce 20-byte digests: - - >>> from hashlib import blake2b - >>> h = blake2b(digest_size=20) - >>> h.update(b'Replacing SHA1 with the more secure function') - >>> h.hexdigest() - 'd24f26cf8de66472d58d4e1b1774b4c9158b1f4c' - >>> h.digest_size - 20 - >>> len(h.digest()) - 20 - -Hash objects with different digest sizes have completely different outputs -(shorter hashes are *not* prefixes of longer hashes); BLAKE2b and BLAKE2s -produce different outputs even if the output length is the same: - - >>> from hashlib import blake2b, blake2s - >>> blake2b(digest_size=10).hexdigest() - '6fa1d8fcfd719046d762' - >>> blake2b(digest_size=11).hexdigest() - 'eb6ec15daf9546254f0809' - >>> blake2s(digest_size=10).hexdigest() - '1bf21a98c78a1c376ae9' - >>> blake2s(digest_size=11).hexdigest() - '567004bf96e4a25773ebf4' - - -Keyed hashing -------------- - -Keyed hashing can be used for authentication as a faster and simpler -replacement for `Hash-based message authentication code -`_ (HMAC). -BLAKE2 can be securely used in prefix-MAC mode thanks to the -indifferentiability property inherited from BLAKE. - -This example shows how to get a (hex-encoded) 128-bit authentication code for -message ``b'message data'`` with key ``b'pseudorandom key'``:: - - >>> from hashlib import blake2b - >>> h = blake2b(key=b'pseudorandom key', digest_size=16) - >>> h.update(b'message data') - >>> h.hexdigest() - '3d363ff7401e02026f4a4687d4863ced' - - -As a practical example, a web application can symmetrically sign cookies sent -to users and later verify them to make sure they weren't tampered with:: - - >>> from hashlib import blake2b - >>> from hmac import compare_digest - >>> - >>> SECRET_KEY = b'pseudorandomly generated server secret key' - >>> AUTH_SIZE = 16 - >>> - >>> def sign(cookie): - ... h = blake2b(data=cookie, digest_size=AUTH_SIZE, key=SECRET_KEY) - ... return h.hexdigest() - >>> - >>> cookie = b'user:vatrogasac' - >>> sig = sign(cookie) - >>> print("{0},{1}".format(cookie.decode('utf-8'), sig)) - user:vatrogasac,349cf904533767ed2d755279a8df84d0 - >>> compare_digest(cookie, sig) - True - >>> compare_digest(b'user:policajac', sig) - False - >>> compare_digesty(cookie, '0102030405060708090a0b0c0d0e0f00') - False - -Even though there's a native keyed hashing mode, BLAKE2 can, of course, be used -in HMAC construction with :mod:`hmac` module:: - - >>> import hmac, hashlib - >>> m = hmac.new(b'secret key', digestmod=hashlib.blake2s) - >>> m.update(b'message') - >>> m.hexdigest() - 'e3c8102868d28b5ff85fc35dda07329970d1a01e273c37481326fe0c861c8142' - - -Randomized hashing ------------------- - -By setting *salt* parameter users can introduce randomization to the hash -function. Randomized hashing is useful for protecting against collision attacks -on the hash function used in digital signatures. - - Randomized hashing is designed for situations where one party, the message - preparer, generates all or part of a message to be signed by a second - party, the message signer. If the message preparer is able to find - cryptographic hash function collisions (i.e., two messages producing the - same hash value), then she might prepare meaningful versions of the message - that would produce the same hash value and digital signature, but with - different results (e.g., transferring $1,000,000 to an account, rather than - $10). Cryptographic hash functions have been designed with collision - resistance as a major goal, but the current concentration on attacking - cryptographic hash functions may result in a given cryptographic hash - function providing less collision resistance than expected. Randomized - hashing offers the signer additional protection by reducing the likelihood - that a preparer can generate two or more messages that ultimately yield the - same hash value during the digital signature generation process --- even if - it is practical to find collisions for the hash function. However, the use - of randomized hashing may reduce the amount of security provided by a - digital signature when all portions of the message are prepared - by the signer. - - (`NIST SP-800-106 "Randomized Hashing for Digital Signatures" - `_) - -In BLAKE2 the salt is processed as a one-time input to the hash function during -initialization, rather than as an input to each compression function. - -.. warning:: - - *Salted hashing* (or just hashing) with BLAKE2 or any other general-purpose - cryptographic hash function, such as SHA-256, is not suitable for hashing - passwords. See `BLAKE2 FAQ `_ for more - information. -.. - - >>> import os - >>> from hashlib import blake2b - >>> msg = b'some message' - >>> # Calculate the first hash with a random salt. - >>> salt1 = os.urandom(blake2b.SALT_SIZE) - >>> h1 = blake2b(salt=salt1) - >>> h1.update(msg) - >>> # Calculate the second hash with a different random salt. - >>> salt2 = os.urandom(blake2b.SALT_SIZE) - >>> h2 = blake2b(salt=salt2) - >>> h2.update(msg) - >>> # The digests are different. - >>> h1.digest() != h2.digest() - True - - -Personalization ---------------- - -Sometimes it is useful to force hash function to produce different digests for -the same input for different purposes. Quoting the authors of the Skein hash -function: - - We recommend that all application designers seriously consider doing this; - we have seen many protocols where a hash that is computed in one part of - the protocol can be used in an entirely different part because two hash - computations were done on similar or related data, and the attacker can - force the application to make the hash inputs the same. Personalizing each - hash function used in the protocol summarily stops this type of attack. - - (`The Skein Hash Function Family - `_, - p. 21) - -BLAKE2 can be personalized by passing bytes to the *person* argument:: - - >>> from hashlib import blake2b - >>> FILES_HASH_PERSON = b'MyApp Files Hash' - >>> BLOCK_HASH_PERSON = b'MyApp Block Hash' - >>> h = blake2b(digest_size=32, person=FILES_HASH_PERSON) - >>> h.update(b'the same content') - >>> h.hexdigest() - '20d9cd024d4fb086aae819a1432dd2466de12947831b75c5a30cf2676095d3b4' - >>> h = blake2b(digest_size=32, person=BLOCK_HASH_PERSON) - >>> h.update(b'the same content') - >>> h.hexdigest() - 'cf68fb5761b9c44e7878bfb2c4c9aea52264a80b75005e65619778de59f383a3' - -Personalization together with the keyed mode can also be used to derive different -keys from a single one. - - >>> from hashlib import blake2s - >>> from base64 import b64decode, b64encode - >>> orig_key = b64decode(b'Rm5EPJai72qcK3RGBpW3vPNfZy5OZothY+kHY6h21KM=') - >>> enc_key = blake2s(key=orig_key, person=b'kEncrypt').digest() - >>> mac_key = blake2s(key=orig_key, person=b'kMAC').digest() - >>> print(b64encode(enc_key).decode('utf-8')) - rbPb15S/Z9t+agffno5wuhB77VbRi6F9Iv2qIxU7WHw= - >>> print(b64encode(mac_key).decode('utf-8')) - G9GtHFE1YluXY1zWPlYk1e/nWfu0WSEb0KRcjhDeP/o= - -Tree mode ---------- - -Here's an example of hashing a minimal tree with two leaf nodes:: - - 10 - / \ - 00 01 - -This example uses 64-byte internal digests, and returns the 32-byte final -digest:: - - >>> from hashlib import blake2b - >>> - >>> FANOUT = 2 - >>> DEPTH = 2 - >>> LEAF_SIZE = 4096 - >>> INNER_SIZE = 64 - >>> - >>> buf = bytearray(6000) - >>> - >>> # Left leaf - ... h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH, - ... leaf_size=LEAF_SIZE, inner_size=INNER_SIZE, - ... node_offset=0, node_depth=0, last_node=False) - >>> # Right leaf - ... h01 = blake2b(buf[LEAF_SIZE:], fanout=FANOUT, depth=DEPTH, - ... leaf_size=LEAF_SIZE, inner_size=INNER_SIZE, - ... node_offset=1, node_depth=0, last_node=True) - >>> # Root node - ... h10 = blake2b(digest_size=32, fanout=FANOUT, depth=DEPTH, - ... leaf_size=LEAF_SIZE, inner_size=INNER_SIZE, - ... node_offset=0, node_depth=1, last_node=True) - >>> h10.update(h00.digest()) - >>> h10.update(h01.digest()) - >>> h10.hexdigest() - '3ad2a9b37c6070e374c7a8c508fe20ca86b6ed54e286e93a0318e95e881db5aa' - -Credits -======= - -BLAKE2_ was designed by *Jean-Philippe Aumasson*, *Samuel Neves*, *Zooko -Wilcox-O'Hearn*, and *Christian Winnerlein* based on SHA-3_ finalist BLAKE_ -created by *Jean-Philippe Aumasson*, *Luca Henzen*, *Willi Meier*, and -*Raphael C.-W. Phan*. - -It uses core algorithm from ChaCha_ cipher designed by *Daniel J. Bernstein*. - -The stdlib implementation is based on pyblake2_ module. It was written by -*Dmitry Chestnykh* based on C implementation written by *Samuel Neves*. The -documentation was copied from pyblake2_ and written by *Dmitry Chestnykh*. - -The C code was partly rewritten for Python by *Christian Heimes*. - -The following public domain dedication applies for both C hash function -implementation, extension code, and this documentation: - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along - with this software. If not, see - http://creativecommons.org/publicdomain/zero/1.0/. - -The following people have helped with development or contributed their changes -to the project and the public domain according to the Creative Commons Public -Domain Dedication 1.0 Universal: - -* *Alexandr Sokolovskiy* - -.. seealso:: Official BLAKE2 website: https://blake2.net - -.. _RFC-7693: https://tools.ietf.org/html/rfc7693 -.. _BLAKE2: https://blake2.net -.. _HMAC: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code -.. _BLAKE: https://131002.net/blake/ -.. _SHA-3: https://en.wikipedia.org/wiki/NIST_hash_function_competition -.. _ChaCha: https://cr.yp.to/chacha.html -.. _pyblake2: https://pythonhosted.org/pyblake2/ - diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index 2cb3c78..9d56356 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -278,7 +278,438 @@ include a `salt `_. BLAKE2 ------ -BLAKE2 takes additional arguments, see :ref:`hashlib-blake2`. +.. sectionauthor:: Dmitry Chestnykh + +.. index:: + single: blake2b, blake2s + +BLAKE2_ is a cryptographic hash function defined in RFC-7693_ that comes in two +flavors: + +* **BLAKE2b**, optimized for 64-bit platforms and produces digests of any size + between 1 and 64 bytes, + +* **BLAKE2s**, optimized for 8- to 32-bit platforms and produces digests of any + size between 1 and 32 bytes. + +BLAKE2 supports **keyed mode** (a faster and simpler replacement for HMAC_), +**salted hashing**, **personalization**, and **tree hashing**. + +Hash objects from this module follow the API of standard library's +:mod:`hashlib` objects. + + +Creating hash objects +^^^^^^^^^^^^^^^^^^^^^ + +New hash objects are created by calling constructor functions: + + +.. function:: blake2b(data=b'', digest_size=64, key=b'', salt=b'', \ + person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ + node_depth=0, inner_size=0, last_node=False) + +.. function:: blake2s(data=b'', digest_size=32, key=b'', salt=b'', \ + person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ + node_depth=0, inner_size=0, last_node=False) + + +These functions return the corresponding hash objects for calculating +BLAKE2b or BLAKE2s. They optionally take these general parameters: + +* *data*: initial chunk of data to hash, which must be interpretable as buffer + of bytes. + +* *digest_size*: size of output digest in bytes. + +* *key*: key for keyed hashing (up to 64 bytes for BLAKE2b, up to 32 bytes for + BLAKE2s). + +* *salt*: salt for randomized hashing (up to 16 bytes for BLAKE2b, up to 8 + bytes for BLAKE2s). + +* *person*: personalization string (up to 16 bytes for BLAKE2b, up to 8 bytes + for BLAKE2s). + +The following table shows limits for general parameters (in bytes): + +======= =========== ======== ========= =========== +Hash digest_size len(key) len(salt) len(person) +======= =========== ======== ========= =========== +BLAKE2b 64 64 16 16 +BLAKE2s 32 32 8 8 +======= =========== ======== ========= =========== + +.. note:: + + BLAKE2 specification defines constant lengths for salt and personalization + parameters, however, for convenience, this implementation accepts byte + strings of any size up to the specified length. If the length of the + parameter is less than specified, it is padded with zeros, thus, for + example, ``b'salt'`` and ``b'salt\x00'`` is the same value. (This is not + the case for *key*.) + +These sizes are available as module `constants`_ described below. + +Constructor functions also accept the following tree hashing parameters: + +* *fanout*: fanout (0 to 255, 0 if unlimited, 1 in sequential mode). + +* *depth*: maximal depth of tree (1 to 255, 255 if unlimited, 1 in + sequential mode). + +* *leaf_size*: maximal byte length of leaf (0 to 2**32-1, 0 if unlimited or in + sequential mode). + +* *node_offset*: node offset (0 to 2**64-1 for BLAKE2b, 0 to 2**48-1 for + BLAKE2s, 0 for the first, leftmost, leaf, or in sequential mode). + +* *node_depth*: node depth (0 to 255, 0 for leaves, or in sequential mode). + +* *inner_size*: inner digest size (0 to 64 for BLAKE2b, 0 to 32 for + BLAKE2s, 0 in sequential mode). + +* *last_node*: boolean indicating whether the processed node is the last + one (`False` for sequential mode). + +.. figure:: hashlib-blake2-tree.png + :alt: Explanation of tree mode parameters. + +See section 2.10 in `BLAKE2 specification +`_ for comprehensive review of tree +hashing. + + +Constants +^^^^^^^^^ + +.. data:: blake2b.SALT_SIZE +.. data:: blake2s.SALT_SIZE + +Salt length (maximum length accepted by constructors). + + +.. data:: blake2b.PERSON_SIZE +.. data:: blake2s.PERSON_SIZE + +Personalization string length (maximum length accepted by constructors). + + +.. data:: blake2b.MAX_KEY_SIZE +.. data:: blake2s.MAX_KEY_SIZE + +Maximum key size. + + +.. data:: blake2b.MAX_DIGEST_SIZE +.. data:: blake2s.MAX_DIGEST_SIZE + +Maximum digest size that the hash function can output. + + +Examples +^^^^^^^^ + +Simple hashing +"""""""""""""" + +To calculate hash of some data, you should first construct a hash object by +calling the appropriate constructor function (:func:`blake2b` or +:func:`blake2s`), then update it with the data by calling :meth:`update` on the +object, and, finally, get the digest out of the object by calling +:meth:`digest` (or :meth:`hexdigest` for hex-encoded string). + + >>> from hashlib import blake2b + >>> h = blake2b() + >>> h.update(b'Hello world') + >>> h.hexdigest() + '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183' + + +As a shortcut, you can pass the first chunk of data to update directly to the +constructor as the first argument (or as *data* keyword argument): + + >>> from hashlib import blake2b + >>> blake2b(b'Hello world').hexdigest() + '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183' + +You can call :meth:`hash.update` as many times as you need to iteratively +update the hash: + + >>> from hashlib import blake2b + >>> items = [b'Hello', b' ', b'world'] + >>> h = blake2b() + >>> for item in items: + ... h.update(item) + >>> h.hexdigest() + '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183' + + +Using different digest sizes +"""""""""""""""""""""""""""" + +BLAKE2 has configurable size of digests up to 64 bytes for BLAKE2b and up to 32 +bytes for BLAKE2s. For example, to replace SHA-1 with BLAKE2b without changing +the size of output, we can tell BLAKE2b to produce 20-byte digests: + + >>> from hashlib import blake2b + >>> h = blake2b(digest_size=20) + >>> h.update(b'Replacing SHA1 with the more secure function') + >>> h.hexdigest() + 'd24f26cf8de66472d58d4e1b1774b4c9158b1f4c' + >>> h.digest_size + 20 + >>> len(h.digest()) + 20 + +Hash objects with different digest sizes have completely different outputs +(shorter hashes are *not* prefixes of longer hashes); BLAKE2b and BLAKE2s +produce different outputs even if the output length is the same: + + >>> from hashlib import blake2b, blake2s + >>> blake2b(digest_size=10).hexdigest() + '6fa1d8fcfd719046d762' + >>> blake2b(digest_size=11).hexdigest() + 'eb6ec15daf9546254f0809' + >>> blake2s(digest_size=10).hexdigest() + '1bf21a98c78a1c376ae9' + >>> blake2s(digest_size=11).hexdigest() + '567004bf96e4a25773ebf4' + + +Keyed hashing +""""""""""""" + +Keyed hashing can be used for authentication as a faster and simpler +replacement for `Hash-based message authentication code +`_ (HMAC). +BLAKE2 can be securely used in prefix-MAC mode thanks to the +indifferentiability property inherited from BLAKE. + +This example shows how to get a (hex-encoded) 128-bit authentication code for +message ``b'message data'`` with key ``b'pseudorandom key'``:: + + >>> from hashlib import blake2b + >>> h = blake2b(key=b'pseudorandom key', digest_size=16) + >>> h.update(b'message data') + >>> h.hexdigest() + '3d363ff7401e02026f4a4687d4863ced' + + +As a practical example, a web application can symmetrically sign cookies sent +to users and later verify them to make sure they weren't tampered with:: + + >>> from hashlib import blake2b + >>> from hmac import compare_digest + >>> + >>> SECRET_KEY = b'pseudorandomly generated server secret key' + >>> AUTH_SIZE = 16 + >>> + >>> def sign(cookie): + ... h = blake2b(data=cookie, digest_size=AUTH_SIZE, key=SECRET_KEY) + ... return h.hexdigest() + >>> + >>> cookie = b'user:vatrogasac' + >>> sig = sign(cookie) + >>> print("{0},{1}".format(cookie.decode('utf-8'), sig)) + user:vatrogasac,349cf904533767ed2d755279a8df84d0 + >>> compare_digest(cookie, sig) + True + >>> compare_digest(b'user:policajac', sig) + False + >>> compare_digesty(cookie, '0102030405060708090a0b0c0d0e0f00') + False + +Even though there's a native keyed hashing mode, BLAKE2 can, of course, be used +in HMAC construction with :mod:`hmac` module:: + + >>> import hmac, hashlib + >>> m = hmac.new(b'secret key', digestmod=hashlib.blake2s) + >>> m.update(b'message') + >>> m.hexdigest() + 'e3c8102868d28b5ff85fc35dda07329970d1a01e273c37481326fe0c861c8142' + + +Randomized hashing +"""""""""""""""""" + +By setting *salt* parameter users can introduce randomization to the hash +function. Randomized hashing is useful for protecting against collision attacks +on the hash function used in digital signatures. + + Randomized hashing is designed for situations where one party, the message + preparer, generates all or part of a message to be signed by a second + party, the message signer. If the message preparer is able to find + cryptographic hash function collisions (i.e., two messages producing the + same hash value), then she might prepare meaningful versions of the message + that would produce the same hash value and digital signature, but with + different results (e.g., transferring $1,000,000 to an account, rather than + $10). Cryptographic hash functions have been designed with collision + resistance as a major goal, but the current concentration on attacking + cryptographic hash functions may result in a given cryptographic hash + function providing less collision resistance than expected. Randomized + hashing offers the signer additional protection by reducing the likelihood + that a preparer can generate two or more messages that ultimately yield the + same hash value during the digital signature generation process --- even if + it is practical to find collisions for the hash function. However, the use + of randomized hashing may reduce the amount of security provided by a + digital signature when all portions of the message are prepared + by the signer. + + (`NIST SP-800-106 "Randomized Hashing for Digital Signatures" + `_) + +In BLAKE2 the salt is processed as a one-time input to the hash function during +initialization, rather than as an input to each compression function. + +.. warning:: + + *Salted hashing* (or just hashing) with BLAKE2 or any other general-purpose + cryptographic hash function, such as SHA-256, is not suitable for hashing + passwords. See `BLAKE2 FAQ `_ for more + information. +.. + + >>> import os + >>> from hashlib import blake2b + >>> msg = b'some message' + >>> # Calculate the first hash with a random salt. + >>> salt1 = os.urandom(blake2b.SALT_SIZE) + >>> h1 = blake2b(salt=salt1) + >>> h1.update(msg) + >>> # Calculate the second hash with a different random salt. + >>> salt2 = os.urandom(blake2b.SALT_SIZE) + >>> h2 = blake2b(salt=salt2) + >>> h2.update(msg) + >>> # The digests are different. + >>> h1.digest() != h2.digest() + True + + +Personalization +""""""""""""""" + +Sometimes it is useful to force hash function to produce different digests for +the same input for different purposes. Quoting the authors of the Skein hash +function: + + We recommend that all application designers seriously consider doing this; + we have seen many protocols where a hash that is computed in one part of + the protocol can be used in an entirely different part because two hash + computations were done on similar or related data, and the attacker can + force the application to make the hash inputs the same. Personalizing each + hash function used in the protocol summarily stops this type of attack. + + (`The Skein Hash Function Family + `_, + p. 21) + +BLAKE2 can be personalized by passing bytes to the *person* argument:: + + >>> from hashlib import blake2b + >>> FILES_HASH_PERSON = b'MyApp Files Hash' + >>> BLOCK_HASH_PERSON = b'MyApp Block Hash' + >>> h = blake2b(digest_size=32, person=FILES_HASH_PERSON) + >>> h.update(b'the same content') + >>> h.hexdigest() + '20d9cd024d4fb086aae819a1432dd2466de12947831b75c5a30cf2676095d3b4' + >>> h = blake2b(digest_size=32, person=BLOCK_HASH_PERSON) + >>> h.update(b'the same content') + >>> h.hexdigest() + 'cf68fb5761b9c44e7878bfb2c4c9aea52264a80b75005e65619778de59f383a3' + +Personalization together with the keyed mode can also be used to derive different +keys from a single one. + + >>> from hashlib import blake2s + >>> from base64 import b64decode, b64encode + >>> orig_key = b64decode(b'Rm5EPJai72qcK3RGBpW3vPNfZy5OZothY+kHY6h21KM=') + >>> enc_key = blake2s(key=orig_key, person=b'kEncrypt').digest() + >>> mac_key = blake2s(key=orig_key, person=b'kMAC').digest() + >>> print(b64encode(enc_key).decode('utf-8')) + rbPb15S/Z9t+agffno5wuhB77VbRi6F9Iv2qIxU7WHw= + >>> print(b64encode(mac_key).decode('utf-8')) + G9GtHFE1YluXY1zWPlYk1e/nWfu0WSEb0KRcjhDeP/o= + +Tree mode +""""""""" + +Here's an example of hashing a minimal tree with two leaf nodes:: + + 10 + / \ + 00 01 + +This example uses 64-byte internal digests, and returns the 32-byte final +digest:: + + >>> from hashlib import blake2b + >>> + >>> FANOUT = 2 + >>> DEPTH = 2 + >>> LEAF_SIZE = 4096 + >>> INNER_SIZE = 64 + >>> + >>> buf = bytearray(6000) + >>> + >>> # Left leaf + ... h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH, + ... leaf_size=LEAF_SIZE, inner_size=INNER_SIZE, + ... node_offset=0, node_depth=0, last_node=False) + >>> # Right leaf + ... h01 = blake2b(buf[LEAF_SIZE:], fanout=FANOUT, depth=DEPTH, + ... leaf_size=LEAF_SIZE, inner_size=INNER_SIZE, + ... node_offset=1, node_depth=0, last_node=True) + >>> # Root node + ... h10 = blake2b(digest_size=32, fanout=FANOUT, depth=DEPTH, + ... leaf_size=LEAF_SIZE, inner_size=INNER_SIZE, + ... node_offset=0, node_depth=1, last_node=True) + >>> h10.update(h00.digest()) + >>> h10.update(h01.digest()) + >>> h10.hexdigest() + '3ad2a9b37c6070e374c7a8c508fe20ca86b6ed54e286e93a0318e95e881db5aa' + +Credits +^^^^^^^ + +BLAKE2_ was designed by *Jean-Philippe Aumasson*, *Samuel Neves*, *Zooko +Wilcox-O'Hearn*, and *Christian Winnerlein* based on SHA-3_ finalist BLAKE_ +created by *Jean-Philippe Aumasson*, *Luca Henzen*, *Willi Meier*, and +*Raphael C.-W. Phan*. + +It uses core algorithm from ChaCha_ cipher designed by *Daniel J. Bernstein*. + +The stdlib implementation is based on pyblake2_ module. It was written by +*Dmitry Chestnykh* based on C implementation written by *Samuel Neves*. The +documentation was copied from pyblake2_ and written by *Dmitry Chestnykh*. + +The C code was partly rewritten for Python by *Christian Heimes*. + +The following public domain dedication applies for both C hash function +implementation, extension code, and this documentation: + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with this software. If not, see + http://creativecommons.org/publicdomain/zero/1.0/. + +The following people have helped with development or contributed their changes +to the project and the public domain according to the Creative Commons Public +Domain Dedication 1.0 Universal: + +* *Alexandr Sokolovskiy* + +.. _RFC-7693: https://tools.ietf.org/html/rfc7693 +.. _BLAKE2: https://blake2.net +.. _HMAC: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code +.. _BLAKE: https://131002.net/blake/ +.. _SHA-3: https://en.wikipedia.org/wiki/NIST_hash_function_competition +.. _ChaCha: https://cr.yp.to/chacha.html +.. _pyblake2: https://pythonhosted.org/pyblake2/ + .. seealso:: @@ -289,7 +720,8 @@ BLAKE2 takes additional arguments, see :ref:`hashlib-blake2`. Module :mod:`base64` Another way to encode binary hashes for non-binary environments. - See :ref:`hashlib-blake2`. + https://blake2.net + Official BLAKE2 website. http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf The FIPS 180-2 publication on Secure Hash Algorithms. diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index a629bc5..07c2a25 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -446,7 +446,7 @@ longer or disable the extension. Calltips ^^^^^^^^ -A calltip is shown when one types :kbd:`(` after the name of an *acccessible* +A calltip is shown when one types :kbd:`(` after the name of an *accessible* 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 :kbd:`)` is typed. When the cursor is in the argument part of a definition, diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 41a784d..3fa44a0 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -905,10 +905,8 @@ Classes and functions are the names of the ``*`` and ``**`` arguments or ``None``. *locals* is the locals dictionary of the given frame. - .. deprecated:: 3.5 - Use :func:`signature` and - :ref:`Signature Object `, which provide a - better introspecting API for callables. + .. note:: + This function was inadvertently marked as deprecated in Python 3.5. .. function:: formatargspec(args[, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations[, formatarg, formatvarargs, formatvarkw, formatvalue, formatreturns, formatannotations]]) @@ -944,10 +942,8 @@ Classes and functions :func:`getargvalues`. The format\* arguments are the corresponding optional formatting functions that are called to turn names and values into strings. - .. deprecated:: 3.5 - Use :func:`signature` and - :ref:`Signature Object `, which provide a - better introspecting API for callables. + .. note:: + This function was inadvertently marked as deprecated in Python 3.5. .. function:: getmro(cls) diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 76e936f..8103c61 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -278,6 +278,11 @@ Basic Usage If the data being deserialized is not a valid JSON document, a :exc:`JSONDecodeError` will be raised. + .. versionchanged:: 3.6 + *s* can now be of type :class:`bytes` or :class:`bytearray`. The + input encoding should be UTF-8, UTF-16 or UTF-32. + + Encoders and Decoders --------------------- @@ -500,27 +505,27 @@ Exceptions .. exception:: JSONDecodeError(msg, doc, pos, end=None) - Subclass of :exc:`ValueError` with the following additional attributes: + Subclass of :exc:`ValueError` with the following additional attributes: - .. attribute:: msg + .. attribute:: msg - The unformatted error message. + The unformatted error message. - .. attribute:: doc + .. attribute:: doc - The JSON document being parsed. + The JSON document being parsed. - .. attribute:: pos + .. attribute:: pos - The start index of *doc* where parsing failed. + The start index of *doc* where parsing failed. - .. attribute:: lineno + .. attribute:: lineno - The line corresponding to *pos*. + The line corresponding to *pos*. - .. attribute:: colno + .. attribute:: colno - The column corresponding to *pos*. + The column corresponding to *pos*. .. versionadded:: 3.5 diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index a68a890..a7928a0 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -105,8 +105,8 @@ in :mod:`logging` itself) and defining handlers which are declared either in :param disable_existing_loggers: If specified as ``False``, loggers which exist when this call is made are left enabled. The default is ``True`` because this - enables old behaviour in a backward- - compatible way. This behaviour is to + enables old behaviour in a + backward-compatible way. This behaviour is to disable any existing loggers unless they or their ancestors are explicitly named in the logging configuration. diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 6be3279..f13f765 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -282,16 +282,17 @@ module, supports rotation of disk log files. You can use the *maxBytes* and *backupCount* values to allow the file to :dfn:`rollover` at a predetermined size. When the size is about to be exceeded, the file is closed and a new file is silently opened for output. Rollover occurs - whenever the current log file is nearly *maxBytes* in length; if either of - *maxBytes* or *backupCount* is zero, rollover never occurs. If *backupCount* - is non-zero, the system will save old log files by appending the extensions - '.1', '.2' etc., to the filename. For example, with a *backupCount* of 5 and - a base file name of :file:`app.log`, you would get :file:`app.log`, + whenever the current log file is nearly *maxBytes* in length; but if either of + *maxBytes* or *backupCount* is zero, rollover never occurs, so you generally want + to set *backupCount* to at least 1, and have a non-zero *maxBytes*. + When *backupCount* is non-zero, the system will save old log files by appending + the extensions '.1', '.2' etc., to the filename. For example, with a *backupCount* + of 5 and a base file name of :file:`app.log`, you would get :file:`app.log`, :file:`app.log.1`, :file:`app.log.2`, up to :file:`app.log.5`. The file being written to is always :file:`app.log`. When this file is filled, it is closed and renamed to :file:`app.log.1`, and if files :file:`app.log.1`, - :file:`app.log.2`, etc. exist, then they are renamed to :file:`app.log.2`, - :file:`app.log.3` etc. respectively. + :file:`app.log.2`, etc. exist, then they are renamed to :file:`app.log.2`, + :file:`app.log.3` etc. respectively. .. versionchanged:: 3.6 As well as string values, :class:`~pathlib.Path` objects are also accepted @@ -945,8 +946,8 @@ possible, while any potentially slow operations (such as sending an email via .. class:: QueueHandler(queue) Returns a new instance of the :class:`QueueHandler` class. The instance is - initialized with the queue to send messages to. The queue can be any queue- - like object; it's used as-is by the :meth:`enqueue` method, which needs + initialized with the queue to send messages to. The queue can be any + queue-like object; it's used as-is by the :meth:`enqueue` method, which needs to know how to send messages to it. @@ -1001,8 +1002,8 @@ possible, while any potentially slow operations (such as sending an email via Returns a new instance of the :class:`QueueListener` class. The instance is initialized with the queue to send messages to and a list of handlers which - will handle entries placed on the queue. The queue can be any queue- - like object; it's passed as-is to the :meth:`dequeue` method, which needs + will handle entries placed on the queue. The queue can be any queue-like + object; it's passed as-is to the :meth:`dequeue` method, which needs to know how to get messages from it. If ``respect_handler_level`` is ``True``, a handler's level is respected (compared with the level for the message) when deciding whether to pass messages to that handler; otherwise, the behaviour diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 5edb23d..cce6c23 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -39,7 +39,7 @@ Reading and writing compressed files object`. The *filename* argument can be either an actual file name (given as a - :class:`str`, :class:`bytes` or :term:`path-like object` object), in + :class:`str`, :class:`bytes` or :term:`path-like ` object), in which case the named file is opened, or it can be an existing file object to read from or write to. @@ -76,7 +76,7 @@ Reading and writing compressed files An :class:`LZMAFile` can wrap an already-open :term:`file object`, or operate directly on a named file. The *filename* argument specifies either the file object to wrap, or the name of the file to open (as a :class:`str`, - :class:`bytes` or :term:`path-like object` object). When wrapping an + :class:`bytes` or :term:`path-like ` object). When wrapping an existing file object, the wrapped file will not be closed when the :class:`LZMAFile` is closed. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 988cb7c..974ab2d 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2213,7 +2213,7 @@ features: Get the status of a file or a file descriptor. Perform the equivalent of a :c:func:`stat` system call on the given path. *path* may be specified as - either a string -- directly or indirectly through the :class:`PathLike` + either a string or bytes -- directly or indirectly through the :class:`PathLike` interface -- or as an open file descriptor. Return a :class:`stat_result` object. @@ -2859,7 +2859,7 @@ These functions are all available on Linux only. :ref:`not following symlinks `. .. versionchanged:: 3.6 - Accepts a :term:`path-like object` fpr *path* and *attribute*. + Accepts a :term:`path-like object` for *path* and *attribute*. .. function:: listxattr(path=None, *, follow_symlinks=True) diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 90d69e4..fba0ea6 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -224,4 +224,6 @@ support. If the package cannot be located or loaded, or it uses a :term:`loader` which does not support :meth:`get_data `, - then ``None`` is returned. + then ``None`` is returned. In particular, the :term:`loader` for + :term:`namespace packages ` does not support + :meth:`get_data `. diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 959d9b9..bd67fe4 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -444,9 +444,10 @@ Analysis of the profiler data is done using the :class:`~pstats.Stats` class. significant entries. Initially, the list is taken to be the complete set of profiled functions. Each restriction is either an integer (to select a count of lines), or a decimal fraction between 0.0 and 1.0 inclusive (to - select a percentage of lines), or a regular expression (to pattern match - the standard name that is printed. If several restrictions are provided, - then they are applied sequentially. For example:: + select a percentage of lines), or a string that will interpreted as a + regular expression (to pattern match the standard name that is printed). + If several restrictions are provided, then they are applied sequentially. + For example:: print_stats(.1, 'foo:') diff --git a/Doc/library/quopri.rst b/Doc/library/quopri.rst index ef2b5f2..a3f94a0 100644 --- a/Doc/library/quopri.rst +++ b/Doc/library/quopri.rst @@ -32,8 +32,8 @@ sending a graphics file. .. function:: encode(input, output, quotetabs, header=False) - Encode the contents of the *input* file and write the resulting quoted- - printable data to the *output* file. *input* and *output* must be + Encode the contents of the *input* file and write the resulting quoted-printable + data to the *output* file. *input* and *output* must be :term:`binary file objects `. *quotetabs*, a flag which controls whether to encode embedded spaces and tabs must be provideda and when true it encodes such embedded whitespace, and when false it leaves them unencoded. diff --git a/Doc/library/re.rst b/Doc/library/re.rst index a298d97..9cced51 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -42,6 +42,12 @@ module-level functions and methods on that don't require you to compile a regex object first, but miss some fine-tuning parameters. +.. seealso:: + + The third-party `regex `_ module, + which has an API compatible with the standard library :mod:`re` module, + but offers additional functionality and a more thorough Unicode support. + .. _re-syntax: @@ -762,7 +768,7 @@ form. now are errors. .. deprecated-removed:: 3.5 3.7 - Unknown escapes in *repl* consist of ``'\'`` and ASCII letter now raise + Unknown escapes in *repl* consisting of ``'\'`` and an ASCII letter now raise a deprecation warning and will be forbidden in Python 3.7. @@ -1465,7 +1471,7 @@ successive matches:: elif kind == 'SKIP': pass elif kind == 'MISMATCH': - raise RuntimeError('%r unexpected on line %d' % (value, line_num)) + raise RuntimeError(f'{value!r} unexpected on line {line_num}') else: if kind == 'ID' and value in keywords: kind = value diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index 1a89bf6..55012f8 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -374,23 +374,19 @@ is changed: any run of these characters is returned as a single token. While this is short of a full parser for shells (which would be out of scope for the standard library, given the multiplicity of shells out there), it does allow you to perform processing of command lines more easily than you could -otherwise. To illustrate, you can see the difference in the following snippet:: +otherwise. To illustrate, you can see the difference in the following snippet: - import shlex +.. doctest:: + :options: +NORMALIZE_WHITESPACE - for punct in (False, True): - if punct: - message = 'Old' - else: - message = 'New' - text = "a && b; c && d || e; f >'abc'; (def \"ghi\")" - s = shlex.shlex(text, punctuation_chars=punct) - print('%s: %s' % (message, list(s))) - -which prints out:: - - Old: ['a', '&', '&', 'b', ';', 'c', '&', '&', 'd', '|', '|', 'e', ';', 'f', '>', "'abc'", ';', '(', 'def', '"ghi"', ')'] - New: ['a', '&&', 'b', ';', 'c', '&&', 'd', '||', 'e', ';', 'f', '>', "'abc'", ';', '(', 'def', '"ghi"', ')'] + >>> import shlex + >>> text = "a && b; c && d || e; f >'abc'; (def \"ghi\")" + >>> list(shlex.shlex(text)) + ['a', '&', '&', 'b', ';', 'c', '&', '&', 'd', '|', '|', 'e', ';', 'f', '>', + "'abc'", ';', '(', 'def', '"ghi"', ')'] + >>> list(shlex.shlex(text, punctuation_chars=True)) + ['a', '&&', 'b', ';', 'c', '&&', 'd', '||', 'e', ';', 'f', '>', "'abc'", + ';', '(', 'def', '"ghi"', ')'] Of course, tokens will be returned which are not valid for shells, and you'll need to implement your own error checks on the returned tokens. @@ -415,4 +411,6 @@ which characters constitute punctuation. For example:: >>> list(s) ['~/a', '&&', 'b-c', '--color=auto', '||', 'd', '*.py?'] - +For best effect, ``punctuation_chars`` should be set in conjunction with +``posix=True``. (Note that ``posix=False`` is the default for +:class:`~shlex.shlex`.) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index f559ca0..a85bf33 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -458,6 +458,10 @@ Archiving operations .. versionadded:: 3.2 +.. versionchanged:: 3.5 + Added support for the *xztar* format. + + High-level utilities to create and read compressed and archived files are also provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. @@ -467,8 +471,9 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. *base_name* is the name of the file to create, including the path, minus any format-specific extension. *format* is the archive format: one of - "zip", "tar", "bztar" (if the :mod:`bz2` module is available), "xztar" - (if the :mod:`lzma` module is available) or "gztar". + "zip" (if the :mod:`zlib` module is available), "tar", "gztar" (if the + :mod:`zlib` module is available), "bztar" (if the :mod:`bz2` module is + available), or "xztar" (if the :mod:`lzma` module is available). *root_dir* is a directory that will be the root directory of the archive; for example, we typically chdir into *root_dir* before creating the @@ -491,9 +496,6 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. The *verbose* argument is unused and deprecated. - .. versionchanged:: 3.5 - Added support for the *xztar* format. - .. function:: get_archive_formats() @@ -502,11 +504,11 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. By default :mod:`shutil` provides these formats: - - *gztar*: gzip'ed tar-file - - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available.) - - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available.) - - *tar*: uncompressed tar file - - *zip*: ZIP file + - *zip*: ZIP file (if the :mod:`zlib` module is available). + - *tar*: uncompressed tar file. + - *gztar*: gzip'ed tar-file (if the :mod:`zlib` module is available). + - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available). + - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available). You can register new formats or provide your own archiver for any existing formats, by using :func:`register_archive_format`. @@ -541,11 +543,12 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. *extract_dir* is the name of the target directory where the archive is unpacked. If not provided, the current working directory is used. - *format* is the archive format: one of "zip", "tar", or "gztar". Or any - other format registered with :func:`register_unpack_format`. If not - provided, :func:`unpack_archive` will use the archive file name extension - and see if an unpacker was registered for that extension. In case none is - found, a :exc:`ValueError` is raised. + *format* is the archive format: one of "zip", "tar", "gztar", "bztar", or + "xztar". Or any other format registered with + :func:`register_unpack_format`. If not provided, :func:`unpack_archive` + will use the archive file name extension and see if an unpacker was + registered for that extension. In case none is found, + a :exc:`ValueError` is raised. .. function:: register_unpack_format(name, extensions, function[, extra_args[, description]]) @@ -578,11 +581,12 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. By default :mod:`shutil` provides these formats: - - *gztar*: gzip'ed tar-file - - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available.) - - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available.) - - *tar*: uncompressed tar file - - *zip*: ZIP file + - *zip*: ZIP file (unpacking compressed files works only if the corresponding + module is available). + - *tar*: uncompressed tar file. + - *gztar*: gzip'ed tar-file (if the :mod:`zlib` module is available). + - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available). + - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available). You can register new formats or provide your own unpacker for any existing formats, by using :func:`register_unpack_format`. @@ -621,8 +625,6 @@ The resulting archive contains: Querying the size of the output terminal ---------------------------------------- -.. versionadded:: 3.3 - .. function:: get_terminal_size(fallback=(columns, lines)) Get the size of the terminal window. @@ -646,6 +648,8 @@ Querying the size of the output terminal See also: The Single UNIX Specification, Version 2, `Other Environment Variables`_. + .. versionadded:: 3.3 + .. _`Other Environment Variables`: http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index e383201..85ee8a7 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -13,6 +13,12 @@ This module offers several classes to implement SMTP (email) servers. +.. seealso:: + + The `aiosmtpd `_ package is a recommended + replacement for this module. It is based on :mod:`asyncio` and provides a + more straightforward API. :mod:`smtpd` should be considered deprecated. + Several server implementations are present; one is a generic do-nothing implementation, which can be overridden, while the other two offer specific mail-sending strategies. diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 9c10867..678e32c 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -300,8 +300,8 @@ Constants provided. .. versionchanged:: 3.6 - ``SO_DOMAIN``, ``SO_PROTOCOL``, ``SO_PEERSEC``, ``SO_PASSSEC`` - were added. + ``SO_DOMAIN``, ``SO_PROTOCOL``, ``SO_PEERSEC``, ``SO_PASSSEC``, + ``TCP_USER_TIMEOUT``, ``TCP_CONGESTION`` were added. .. data:: AF_CAN PF_CAN @@ -1342,8 +1342,8 @@ to sockets. to transmit as opposed to sending the file until EOF is reached. File position is updated on return or also in case of error in which case :meth:`file.tell() ` can be used to figure out the number of - bytes which were sent. The socket must be of :const:`SOCK_STREAM` type. Non- - blocking sockets are not supported. + bytes which were sent. The socket must be of :const:`SOCK_STREAM` type. + Non-blocking sockets are not supported. .. versionadded:: 3.5 diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 5635577..d1f7a6f 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -927,14 +927,6 @@ By default, the :mod:`sqlite3` module opens transactions implicitly before a Data Modification Language (DML) statement (i.e. ``INSERT``/``UPDATE``/``DELETE``/``REPLACE``). -So if you are within a transaction and issue a command like ``CREATE TABLE -...``, ``VACUUM``, ``PRAGMA``, the :mod:`sqlite3` module will commit implicitly -before executing that command. There are two reasons for doing that. The first -is that some of these commands don't work within transactions. The other reason -is that sqlite3 needs to keep track of the transaction state (if a transaction -is active or not). The current transaction state is exposed through the -:attr:`Connection.in_transaction` attribute of the connection object. - You can control which kind of ``BEGIN`` statements sqlite3 implicitly executes (or none at all) via the *isolation_level* parameter to the :func:`connect` call, or via the :attr:`isolation_level` property of connections. @@ -945,6 +937,9 @@ Otherwise leave it at its default, which will result in a plain "BEGIN" statement, or set it to one of SQLite's supported isolation levels: "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". +The current transaction state is exposed through the +:attr:`Connection.in_transaction` attribute of the connection object. + .. versionchanged:: 3.6 :mod:`sqlite3` used to implicitly commit an open transaction before DDL statements. This is no longer the case. diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index eee4849..bbb1374 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -616,7 +616,7 @@ Constants .. data:: PROTOCOL_TLS_CLIENT - Auto-negotiate the the highest protocol version like :data:`PROTOCOL_SSLv23`, + Auto-negotiate the highest protocol version like :data:`PROTOCOL_SSLv23`, but only support client-side :class:`SSLSocket` connections. The protocol enables :data:`CERT_REQUIRED` and :attr:`~SSLContext.check_hostname` by default. @@ -625,7 +625,7 @@ Constants .. data:: PROTOCOL_TLS_SERVER - Auto-negotiate the the highest protocol version like :data:`PROTOCOL_SSLv23`, + Auto-negotiate the highest protocol version like :data:`PROTOCOL_SSLv23`, but only support server-side :class:`SSLSocket` connections. .. versionadded:: 3.6 @@ -636,7 +636,7 @@ Constants .. deprecated:: 3.6 - Use data:`PROTOCOL_TLS` instead. + Use :data:`PROTOCOL_TLS` instead. .. data:: PROTOCOL_SSLv2 @@ -667,7 +667,7 @@ Constants .. deprecated:: 3.6 OpenSSL has deprecated all version specific protocols. Use the default - protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead. + protocol :data:`PROTOCOL_TLS` with flags like :data:`OP_NO_SSLv3` instead. .. data:: PROTOCOL_TLSv1 @@ -676,7 +676,7 @@ Constants .. deprecated:: 3.6 OpenSSL has deprecated all version specific protocols. Use the default - protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead. + protocol :data:`PROTOCOL_TLS` with flags like :data:`OP_NO_SSLv3` instead. .. data:: PROTOCOL_TLSv1_1 @@ -688,7 +688,7 @@ Constants .. deprecated:: 3.6 OpenSSL has deprecated all version specific protocols. Use the default - protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead. + protocol :data:`PROTOCOL_TLS` with flags like :data:`OP_NO_SSLv3` instead. .. data:: PROTOCOL_TLSv1_2 @@ -701,7 +701,7 @@ Constants .. deprecated:: 3.6 OpenSSL has deprecated all version specific protocols. Use the default - protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead. + protocol :data:`PROTOCOL_TLS` with flags like :data:`OP_NO_SSLv3` instead. .. data:: OP_ALL @@ -846,7 +846,7 @@ Constants The version string of the OpenSSL library loaded by the interpreter:: >>> ssl.OPENSSL_VERSION - 'OpenSSL 0.9.8k 25 Mar 2009' + 'OpenSSL 1.0.2k 26 Jan 2017' .. versionadded:: 3.2 @@ -856,7 +856,7 @@ Constants OpenSSL library:: >>> ssl.OPENSSL_VERSION_INFO - (0, 9, 8, 11, 15) + (1, 0, 2, 11, 15) .. versionadded:: 3.2 @@ -865,9 +865,9 @@ Constants The raw version number of the OpenSSL library, as a single integer:: >>> ssl.OPENSSL_VERSION_NUMBER - 9470143 + 268443839 >>> hex(ssl.OPENSSL_VERSION_NUMBER) - '0x9080bf' + '0x100020bf' .. versionadded:: 3.2 @@ -948,7 +948,7 @@ SSL Sockets :ref:`notes on non-blocking sockets `. Usually, :class:`SSLSocket` are not created directly, but using the - the :meth:`SSLContext.wrap_socket` method. + :meth:`SSLContext.wrap_socket` method. .. versionchanged:: 3.5 The :meth:`sendfile` method was added. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 122ed00..6729a20 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -108,11 +108,11 @@ Notes: (1) This is a short-circuit operator, so it only evaluates the second - argument if the first one is :const:`False`. + argument if the first one is false. (2) This is a short-circuit operator, so it only evaluates the second - argument if the first one is :const:`True`. + argument if the first one is true. (3) ``not`` has a lower priority than non-Boolean operators, so ``not a == b`` is @@ -927,7 +927,7 @@ Notes: :ref:`faq-multidimensional-list`. (3) - If *i* or *j* is negative, the index is relative to the end of the string: + If *i* or *j* is negative, the index is relative to the end of sequence *s*: ``len(s) + i`` or ``len(s) + j`` is substituted. But note that ``-0`` is still ``0``. @@ -942,8 +942,10 @@ Notes: The slice of *s* from *i* to *j* with step *k* is defined as the sequence of items with index ``x = i + n*k`` such that ``0 <= n < (j-i)/k``. In other words, the indices are ``i``, ``i+k``, ``i+2*k``, ``i+3*k`` and so on, stopping when - *j* is reached (but never including *j*). If *i* or *j* is greater than - ``len(s)``, use ``len(s)``. If *i* or *j* are omitted or ``None``, they become + *j* is reached (but never including *j*). When *k* is positive, + *i* and *j* are reduced to ``len(s)`` if they are greater. + When *k* is negative, *i* and *j* are reduced to ``len(s) - 1`` if + they are greater. If *i* or *j* are omitted or ``None``, they become "end" values (which end depends on the sign of *k*). Note, *k* cannot be zero. If *k* is ``None``, it is treated like ``1``. @@ -1644,18 +1646,20 @@ expression support in the :mod:`re` module). Return true if all characters in the string are decimal characters and there is at least one character, false - otherwise. Decimal characters are those from general category "Nd". This category - includes digit characters, and all characters - that can be used to form decimal-radix numbers, e.g. U+0660, - ARABIC-INDIC DIGIT ZERO. + otherwise. Decimal characters are those that can be used to form + numbers in base 10, e.g. U+0660, ARABIC-INDIC DIGIT + ZERO. Formally a decimal character is a character in the Unicode + General Category "Nd". .. method:: str.isdigit() Return true if all characters in the string are digits and there is at least one character, false otherwise. Digits include decimal characters and digits that need - special handling, such as the compatibility superscript digits. Formally, a digit - is a character that has the property value Numeric_Type=Digit or Numeric_Type=Decimal. + special handling, such as the compatibility superscript digits. + This covers digits which cannot be used to form numbers in base 10, + like the Kharosthi numbers. Formally, a digit is a character that has the + property value Numeric_Type=Digit or Numeric_Type=Decimal. .. method:: str.isidentifier() @@ -2158,7 +2162,7 @@ The conversion types are: +------------+-----------------------------------------------------+-------+ | ``'o'`` | Signed octal value. | \(1) | +------------+-----------------------------------------------------+-------+ -| ``'u'`` | Obsolete type -- it is identical to ``'d'``. | \(7) | +| ``'u'`` | Obsolete type -- it is identical to ``'d'``. | \(6) | +------------+-----------------------------------------------------+-------+ | ``'x'`` | Signed hexadecimal (lowercase). | \(2) | +------------+-----------------------------------------------------+-------+ @@ -2199,15 +2203,12 @@ The conversion types are: Notes: (1) - The alternate form causes a leading zero (``'0'``) to be inserted between - left-hand padding and the formatting of the number if the leading character - of the result is not already a zero. + The alternate form causes a leading octal specifier (``'0o'``) to be + inserted before the first digit. (2) The alternate form causes a leading ``'0x'`` or ``'0X'`` (depending on whether - the ``'x'`` or ``'X'`` format was used) to be inserted between left-hand padding - and the formatting of the number if the leading character of the result is not - already a zero. + the ``'x'`` or ``'X'`` format was used) to be inserted before the first digit. (3) The alternate form causes the result to always contain a decimal point, even if @@ -2226,8 +2227,7 @@ Notes: (5) If precision is ``N``, the output is truncated to ``N`` characters. - -(7) +(6) See :pep:`237`. Since Python strings have an explicit length, ``%s`` conversions do not assume @@ -3303,15 +3303,12 @@ The conversion types are: Notes: (1) - The alternate form causes a leading zero (``'0'``) to be inserted between - left-hand padding and the formatting of the number if the leading character - of the result is not already a zero. + The alternate form causes a leading octal specifier (``'0o'``) to be + inserted before the first digit. (2) The alternate form causes a leading ``'0x'`` or ``'0X'`` (depending on whether - the ``'x'`` or ``'X'`` format was used) to be inserted between left-hand padding - and the formatting of the number if the leading character of the result is not - already a zero. + the ``'x'`` or ``'X'`` format was used) to be inserted before the first digit. (3) The alternate form causes the result to always contain a decimal point, even if diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index ad2abe8..548e4a6 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -466,9 +466,13 @@ functions. The *pass_fds* parameter was added. If *cwd* is not ``None``, the function changes the working directory to - *cwd* before executing the child. In particular, the function looks for - *executable* (or for the first item in *args*) relative to *cwd* if the - executable path is a relative path. + *cwd* before executing the child. *cwd* can be a :class:`str` and + :term:`path-like ` object. In particular, the function + looks for *executable* (or for the first item in *args*) relative to *cwd* + if the executable path is a relative path. + + .. versionchanged:: 3.6 + *cwd* parameter accepts a :term:`path-like object`. If *restore_signals* is true (the default) all signals that Python has set to SIG_IGN are restored to SIG_DFL in the child process before the exec. diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index cddbd52..2792dfd 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -256,7 +256,7 @@ since it is impossible to detect the termination of alien threads. Wait until the thread terminates. This blocks the calling thread until the thread whose :meth:`~Thread.join` method is called terminates -- either - normally or through an unhandled exception --, or until the optional + normally or through an unhandled exception -- or until the optional timeout occurs. When the *timeout* argument is present and not ``None``, it should be a diff --git a/Doc/library/time.rst b/Doc/library/time.rst index ae17f6f..d2e2ac4 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -17,11 +17,23 @@ semantics of these functions varies among platforms. An explanation of some terminology and conventions is in order. +.. _epoch: + .. index:: single: epoch -* The :dfn:`epoch` is the point where the time starts. On January 1st of that - year, at 0 hours, the "time since the epoch" is zero. For Unix, the epoch is - 1970. To find out what the epoch is, look at ``gmtime(0)``. +* The :dfn:`epoch` is the point where the time starts, and is platform + dependent. For Unix, the epoch is January 1, 1970, 00:00:00 (UTC). + To find out what the epoch is on a given platform, look at + ``time.gmtime(0)``. + +.. _leap seconds: https://en.wikipedia.org/wiki/Leap_second + +.. index:: seconds since the epoch + +* The term :dfn:`seconds since the epoch` refers to the total number + of elapsed seconds since the epoch, typically excluding + `leap seconds`_. Leap seconds are excluded from this total on all + POSIX-compliant platforms. .. index:: single: Year 2038 @@ -467,7 +479,7 @@ The module defines the following functions and data items: (2) The range really is ``0`` to ``61``; value ``60`` is valid in - timestamps representing leap seconds and value ``61`` is supported + timestamps representing `leap seconds`_ and value ``61`` is supported for historical reasons. (3) @@ -572,12 +584,28 @@ The module defines the following functions and data items: .. function:: time() - Return the time in seconds since the epoch as a floating point number. + Return the time in seconds since the epoch_ as a floating point + number. The specific date of the epoch and the handling of + `leap seconds`_ is platform dependent. + On Windows and most Unix systems, the epoch is January 1, 1970, + 00:00:00 (UTC) and leap seconds are not counted towards the time + in seconds since the epoch. This is commonly referred to as + `Unix time `_. + To find out what the epoch is on a given platform, look at + ``gmtime(0)``. + Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a - lower value than a previous call if the system clock has been set back between - the two calls. + lower value than a previous call if the system clock has been set back + between the two calls. + + The number returned by :func:`.time` may be converted into a more common + time format (i.e. year, month, day, hour, etc...) in UTC by passing it to + :func:`gmtime` function or in local time by passing it to the + :func:`localtime` function. In both cases a + :class:`struct_time` object is returned, from which the components + of the calendar date may be accessed as attributes. .. data:: timezone diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index 3b77276..5793c54 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -134,21 +134,21 @@ The module defines three convenience functions and a public class: timeit.Timer('for i in range(10): oct(i)', 'gc.enable()').timeit() - .. method:: Timer.autorange(callback=None) + .. method:: Timer.autorange(callback=None) - Automatically determine how many times to call :meth:`.timeit`. + Automatically determine how many times to call :meth:`.timeit`. - This is a convenience function that calls :meth:`.timeit` repeatedly - so that the total time >= 0.2 second, returning the eventual - (number of loops, time taken for that number of loops). It calls - :meth:`.timeit` with *number* set to successive powers of ten (10, - 100, 1000, ...) up to a maximum of one billion, until the time taken - is at least 0.2 second, or the maximum is reached. + This is a convenience function that calls :meth:`.timeit` repeatedly + so that the total time >= 0.2 second, returning the eventual + (number of loops, time taken for that number of loops). It calls + :meth:`.timeit` with *number* set to successive powers of ten (10, + 100, 1000, ...) up to a maximum of one billion, until the time taken + is at least 0.2 second, or the maximum is reached. - If *callback* is given and is not ``None``, it will be called after - each trial with two arguments: ``callback(number, time_taken)``. + If *callback* is given and is not ``None``, it will be called after + each trial with two arguments: ``callback(number, time_taken)``. - .. versionadded:: 3.6 + .. versionadded:: 3.6 .. method:: Timer.repeat(repeat=3, number=1000000) diff --git a/Doc/library/trace.rst b/Doc/library/trace.rst index b0ac812..5cb7029 100644 --- a/Doc/library/trace.rst +++ b/Doc/library/trace.rst @@ -13,6 +13,12 @@ annotated statement coverage listings, print caller/callee relationships and list functions executed during a program run. It can be used in another program or from the command line. +.. seealso:: + + `Coverage.py `_ + A popular third-party coverage tool that provides HTML + output along with advanced features such as branch coverage. + .. _trace-cli: Command-Line Usage diff --git a/Doc/library/tracemalloc.rst b/Doc/library/tracemalloc.rst index f56f27b..e165669 100644 --- a/Doc/library/tracemalloc.rst +++ b/Doc/library/tracemalloc.rst @@ -66,7 +66,7 @@ Example of output of the Python test suite:: :5: size=49.7 KiB, count=148, average=344 B /usr/lib/python3.4/sysconfig.py:411: size=48.0 KiB, count=1, average=48.0 KiB -We can see that Python loaded ``4.8 MiB`` data (bytecode and constants) from +We can see that Python loaded ``4855 KiB`` data (bytecode and constants) from modules and that the :mod:`collections` module allocated ``244 KiB`` to build :class:`~collections.namedtuple` types. @@ -106,8 +106,8 @@ Example of output before/after running some tests of the Python test suite:: /usr/lib/python3.4/urllib/parse.py:476: size=71.8 KiB (+71.8 KiB), count=969 (+969), average=76 B /usr/lib/python3.4/contextlib.py:38: size=67.2 KiB (+67.2 KiB), count=126 (+126), average=546 B -We can see that Python has loaded ``8.2 MiB`` of module data (bytecode and -constants), and that this is ``4.4 MiB`` more than had been loaded before the +We can see that Python has loaded ``8173 KiB`` of module data (bytecode and +constants), and that this is ``4428 KiB`` more than had been loaded before the tests, when the previous snapshot was taken. Similarly, the :mod:`linecache` module has cached ``940 KiB`` of Python source code to format tracebacks, all of it since the previous snapshot. @@ -176,7 +176,7 @@ Example of output of the Python test suite (traceback limited to 25 frames):: "__main__", fname, loader, pkg_name) We can see that the most memory was allocated in the :mod:`importlib` module to -load data (bytecode and constants) from modules: ``870 KiB``. The traceback is +load data (bytecode and constants) from modules: ``870.1 KiB``. The traceback is where the :mod:`importlib` loaded data most recently: on the ``import pdb`` line of the :mod:`doctest` module. The traceback may change if a new module is loaded. @@ -192,12 +192,12 @@ ignoring ```` and ```` files:: import os import tracemalloc - def display_top(snapshot, group_by='lineno', limit=10): + def display_top(snapshot, key_type='lineno', limit=10): snapshot = snapshot.filter_traces(( tracemalloc.Filter(False, ""), tracemalloc.Filter(False, ""), )) - top_stats = snapshot.statistics(group_by) + top_stats = snapshot.statistics(key_type) print("Top %s lines" % limit) for index, stat in enumerate(top_stats[:limit], 1): @@ -468,12 +468,12 @@ Snapshot The :func:`take_snapshot` function creates a snapshot instance. - .. method:: compare_to(old_snapshot: Snapshot, group_by: str, cumulative: bool=False) + .. method:: compare_to(old_snapshot: Snapshot, key_type: str, cumulative: bool=False) Compute the differences with an old snapshot. Get statistics as a sorted - list of :class:`StatisticDiff` instances grouped by *group_by*. + list of :class:`StatisticDiff` instances grouped by *key_type*. - See the :meth:`Snapshot.statistics` method for *group_by* and *cumulative* + See the :meth:`Snapshot.statistics` method for *key_type* and *cumulative* parameters. The result is sorted from the biggest to the smallest by: absolute value @@ -511,13 +511,13 @@ Snapshot See also :meth:`dump`. - .. method:: statistics(group_by: str, cumulative: bool=False) + .. method:: statistics(key_type: str, cumulative: bool=False) Get statistics as a sorted list of :class:`Statistic` instances grouped - by *group_by*: + by *key_type*: ===================== ======================== - group_by description + key_type description ===================== ======================== ``'filename'`` filename ``'lineno'`` filename and line number @@ -526,7 +526,7 @@ Snapshot If *cumulative* is ``True``, cumulate size and count of memory blocks of all frames of the traceback of a trace, not only the most recent frame. - The cumulative mode can only be used with *group_by* equals to + The cumulative mode can only be used with *key_type* equals to ``'filename'`` and ``'lineno'``. The result is sorted from the biggest to the smallest by: diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 2bac6f8..d130e17 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -8,6 +8,13 @@ **Source code:** :source:`Lib/typing.py` +.. note:: + + The typing module has been included in the standard library on a + :term:`provisional basis `. New features might + be added and API may change even between minor releases if deemed + necessary by the core developers. + -------------- This module supports type hints as specified by :pep:`484` and :pep:`526`. @@ -299,7 +306,7 @@ comparable for equality. The :data:`Any` type ---------------------- +-------------------- A special kind of type is :data:`Any`. A static type checker will treat every type as being compatible with :data:`Any` and :data:`Any` as being @@ -563,6 +570,12 @@ The module defines the following classes, functions and decorators: As a shorthand for this type, :class:`bytes` can be used to annotate arguments of any of the types mentioned above. +.. class:: Deque(deque, MutableSequence[T]) + + A generic version of :class:`collections.deque`. + + .. versionadded:: 3.6.1 + .. class:: List(list, MutableSequence[T]) Generic version of :class:`list`. @@ -627,7 +640,7 @@ The module defines the following classes, functions and decorators: .. class:: AsyncIterator(AsyncIterable[T_co]) - A generic version of :class:`collections.abc.AsyncIterator`. + A generic version of :class:`collections.abc.AsyncIterator`. .. class:: ContextManager(Generic[T_co]) @@ -678,6 +691,39 @@ The module defines the following classes, functions and decorators: yield start start += 1 +.. class:: AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra]) + + An async generator can be annotated by the generic type + ``AsyncGenerator[YieldType, SendType]``. For example:: + + async def echo_round() -> AsyncGenerator[int, float]: + sent = yield 0 + while sent >= 0.0: + rounded = await round(sent) + sent = yield rounded + + Unlike normal generators, async generators cannot return a value, so there + is no ``ReturnType`` type parameter. As with :class:`Generator`, the + ``SendType`` behaves contravariantly. + + If your generator will only yield values, set the ``SendType`` to + ``None``:: + + async def infinite_stream(start: int) -> AsyncGenerator[int, None]: + while True: + yield start + start = await increment(start) + + Alternatively, annotate your generator as having a return type of + either ``AsyncIterable[YieldType]`` or ``AsyncIterator[YieldType]``:: + + async def infinite_stream(start: int) -> AsyncIterator[int]: + while True: + yield start + start = await increment(start) + + .. versionadded:: 3.5.4 + .. class:: Text ``Text`` is an alias for ``str``. It is provided to supply a forward @@ -724,10 +770,21 @@ The module defines the following classes, functions and decorators: Employee = collections.namedtuple('Employee', ['name', 'id']) - The resulting class has one extra attribute: ``_field_types``, - giving a dict mapping field names to types. (The field names - are in the ``_fields`` attribute, which is part of the namedtuple - API.) + To give a field a default value, you can assign to it in the class body:: + + class Employee(NamedTuple): + name: str + id: int = 3 + + employee = Employee('Guido') + assert employee.id == 3 + + Fields with a default value must come after any fields without a default. + + The resulting class has two extra attributes: ``_field_types``, + giving a dict mapping field names to types, and ``field_defaults``, a dict + mapping field names to default values. (The field names are in the + ``_fields`` attribute, which is part of the namedtuple API.) Backward-compatible usage:: @@ -736,6 +793,9 @@ The module defines the following classes, functions and decorators: .. versionchanged:: 3.6 Added support for :pep:`526` variable annotation syntax. + .. versionchanged:: 3.6.1 + Added support for default values. + .. function:: NewType(typ) A helper function to indicate a distinct types to a typechecker, diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 3cc22fd..a552cbf 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -303,14 +303,14 @@ the *new_callable* argument to :func:`patch`. .. method:: assert_called_once_with(*args, **kwargs) - Assert that the mock was called exactly once and with the specified - arguments. + Assert that the mock was called exactly once and that that call was + with the specified arguments. >>> mock = Mock(return_value=None) >>> mock('foo', bar='baz') >>> mock.assert_called_once_with('foo', bar='baz') - >>> mock('foo', bar='baz') - >>> mock.assert_called_once_with('foo', bar='baz') + >>> mock('other', bar='values') + >>> mock.assert_called_once_with('other', bar='values') Traceback (most recent call last): ... AssertionError: Expected 'mock' to be called once. Called 2 times. @@ -322,7 +322,8 @@ the *new_callable* argument to :func:`patch`. The assert passes if the mock has *ever* been called, unlike :meth:`assert_called_with` and :meth:`assert_called_once_with` that - only pass if the call is the most recent one. + only pass if the call is the most recent one, and in the case of + :meth:`assert_called_once_with` it must also be the only call. >>> mock = Mock(return_value=None) >>> mock(1, 2, arg='thing') @@ -1831,6 +1832,9 @@ sentinel the same attribute will always return the same object. The objects returned have a sensible repr so that test failure messages are readable. + The ``sentinel`` attributes don't preserve their identity when they are + :mod:`copied ` or :mod:`pickled `. + Sometimes when testing you need to test that a specific object is passed as an argument to another method, or returned. It can be common to create named sentinel objects to test this. :data:`sentinel` provides a convenient way of diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index c13a731..92e567d 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -1465,7 +1465,7 @@ Grouping tests .. class:: TestSuite(tests=()) - This class represents an aggregation of individual tests cases and test suites. + This class represents an aggregation of individual test cases and test suites. The class presents the interface needed by the test runner to allow it to be run as any other test case. Running a :class:`TestSuite` instance is the same as iterating over the suite, running each test individually. @@ -1573,7 +1573,7 @@ Loading and running tests .. method:: loadTestsFromTestCase(testCaseClass) - Return a suite of all tests cases contained in the :class:`TestCase`\ -derived + Return a suite of all test cases contained in the :class:`TestCase`\ -derived :class:`testCaseClass`. A test case instance is created for each method named by @@ -1585,7 +1585,7 @@ Loading and running tests .. method:: loadTestsFromModule(module, pattern=None) - Return a suite of all tests cases contained in the given module. This + Return a suite of all test cases contained in the given module. This method searches *module* for classes derived from :class:`TestCase` and creates an instance of the class for each test method defined for the class. @@ -1615,7 +1615,7 @@ Loading and running tests .. method:: loadTestsFromName(name, module=None) - Return a suite of all tests cases given a string specifier. + Return a suite of all test cases given a string specifier. The specifier *name* is a "dotted name" that may resolve either to a module, a test case class, a test method within a test case class, a @@ -1637,11 +1637,11 @@ Loading and running tests The method optionally resolves *name* relative to the given *module*. - .. versionchanged:: 3.5 - If an :exc:`ImportError` or :exc:`AttributeError` occurs while traversing - *name* then a synthetic test that raises that error when run will be - returned. These errors are included in the errors accumulated by - self.errors. + .. versionchanged:: 3.5 + If an :exc:`ImportError` or :exc:`AttributeError` occurs while traversing + *name* then a synthetic test that raises that error when run will be + returned. These errors are included in the errors accumulated by + self.errors. .. method:: loadTestsFromNames(names, module=None) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 473effc..5a10f95 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -170,15 +170,15 @@ The :mod:`urllib.request` module defines the following functions: If both lowercase and uppercase environment variables exist (and disagree), lowercase is preferred. - .. note:: + .. note:: - If the environment variable ``REQUEST_METHOD`` is set, which usually - indicates your script is running in a CGI environment, the environment - variable ``HTTP_PROXY`` (uppercase ``_PROXY``) will be ignored. This is - because that variable can be injected by a client using the "Proxy:" HTTP - header. If you need to use an HTTP proxy in a CGI environment, either use - ``ProxyHandler`` explicitly, or make sure the variable name is in - lowercase (or at least the ``_proxy`` suffix). + If the environment variable ``REQUEST_METHOD`` is set, which usually + indicates your script is running in a CGI environment, the environment + variable ``HTTP_PROXY`` (uppercase ``_PROXY``) will be ignored. This is + because that variable can be injected by a client using the "Proxy:" HTTP + header. If you need to use an HTTP proxy in a CGI environment, either use + ``ProxyHandler`` explicitly, or make sure the variable name is in + lowercase (or at least the ``_proxy`` suffix). The following classes are provided: @@ -1407,48 +1407,48 @@ some point in the future. :class:`URLopener` objects will raise an :exc:`OSError` exception if the server returns an error code. - .. method:: open(fullurl, data=None) + .. method:: open(fullurl, data=None) - Open *fullurl* using the appropriate protocol. This method sets up cache and - proxy information, then calls the appropriate open method with its input - arguments. If the scheme is not recognized, :meth:`open_unknown` is called. - The *data* argument has the same meaning as the *data* argument of - :func:`urlopen`. + Open *fullurl* using the appropriate protocol. This method sets up cache and + proxy information, then calls the appropriate open method with its input + arguments. If the scheme is not recognized, :meth:`open_unknown` is called. + The *data* argument has the same meaning as the *data* argument of + :func:`urlopen`. - .. method:: open_unknown(fullurl, data=None) + .. method:: open_unknown(fullurl, data=None) - Overridable interface to open unknown URL types. + Overridable interface to open unknown URL types. - .. method:: retrieve(url, filename=None, reporthook=None, data=None) + .. method:: retrieve(url, filename=None, reporthook=None, data=None) - Retrieves the contents of *url* and places it in *filename*. The return value - is a tuple consisting of a local filename and either an - :class:`email.message.Message` object containing the response headers (for remote - URLs) or ``None`` (for local URLs). The caller must then open and read the - contents of *filename*. If *filename* is not given and the URL refers to a - local file, the input filename is returned. If the URL is non-local and - *filename* is not given, the filename is the output of :func:`tempfile.mktemp` - with a suffix that matches the suffix of the last path component of the input - URL. If *reporthook* is given, it must be a function accepting three numeric - parameters: A chunk number, the maximum size chunks are read in and the total size of the download - (-1 if unknown). It will be called once at the start and after each chunk of data is read from the - network. *reporthook* is ignored for local URLs. + Retrieves the contents of *url* and places it in *filename*. The return value + is a tuple consisting of a local filename and either an + :class:`email.message.Message` object containing the response headers (for remote + URLs) or ``None`` (for local URLs). The caller must then open and read the + contents of *filename*. If *filename* is not given and the URL refers to a + local file, the input filename is returned. If the URL is non-local and + *filename* is not given, the filename is the output of :func:`tempfile.mktemp` + with a suffix that matches the suffix of the last path component of the input + URL. If *reporthook* is given, it must be a function accepting three numeric + parameters: A chunk number, the maximum size chunks are read in and the total size of the download + (-1 if unknown). It will be called once at the start and after each chunk of data is read from the + network. *reporthook* is ignored for local URLs. - If the *url* uses the :file:`http:` scheme identifier, the optional *data* - argument may be given to specify a ``POST`` request (normally the request type - is ``GET``). The *data* argument must in standard - :mimetype:`application/x-www-form-urlencoded` format; see the - :func:`urllib.parse.urlencode` function. + If the *url* uses the :file:`http:` scheme identifier, the optional *data* + argument may be given to specify a ``POST`` request (normally the request type + is ``GET``). The *data* argument must in standard + :mimetype:`application/x-www-form-urlencoded` format; see the + :func:`urllib.parse.urlencode` function. - .. attribute:: version + .. attribute:: version - Variable that specifies the user agent of the opener object. To get - :mod:`urllib` to tell servers that it is a particular user agent, set this in a - subclass as a class variable or in the constructor before calling the base - constructor. + Variable that specifies the user agent of the opener object. To get + :mod:`urllib` to tell servers that it is a particular user agent, set this in a + subclass as a class variable or in the constructor before calling the base + constructor. .. class:: FancyURLopener(...) diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index 53cbd6c..edbf832 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -45,6 +45,13 @@ random UUID. variant and version number set according to RFC 4122, overriding bits in the given *hex*, *bytes*, *bytes_le*, *fields*, or *int*. + Comparison of UUID objects are made by way of comparing their + :attr:`UUID.int` attributes. Comparison with a non-UUID object + raises a :exc:`TypeError`. + + ``str(uuid)`` returns a string in the form + ``12345678-1234-5678-1234-567812345678`` where the 32 hexadecimal digits + represent the UUID. :class:`UUID` instances have these read-only attributes: @@ -104,7 +111,7 @@ random UUID. .. attribute:: UUID.variant The UUID variant, which determines the internal layout of the UUID. This will be - one of the integer constants :const:`RESERVED_NCS`, :const:`RFC_4122`, + one of the constants :const:`RESERVED_NCS`, :const:`RFC_4122`, :const:`RESERVED_MICROSOFT`, or :const:`RESERVED_FUTURE`. diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index e289b97..b02a006 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -166,8 +166,8 @@ Extension types can easily be made to support weak references; see performed by the program during iteration may cause items in the dictionary to vanish "by magic" (as a side effect of garbage collection). -:class:`WeakKeyDictionary` objects have the following additional methods. These -expose the internal references directly. The references are not guaranteed to +:class:`WeakKeyDictionary` objects have an additional method that +exposes the internal references directly. The references are not guaranteed to be "live" at the time they are used, so the result of calling the references needs to be checked before being used. This can be used to avoid creating references that will cause the garbage collector to keep the keys around longer @@ -192,9 +192,9 @@ than needed. by the program during iteration may cause items in the dictionary to vanish "by magic" (as a side effect of garbage collection). -:class:`WeakValueDictionary` objects have the following additional methods. -These method have the same issues as the and :meth:`keyrefs` method of -:class:`WeakKeyDictionary` objects. +:class:`WeakValueDictionary` objects have an additional method that has the +same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary` +objects. .. method:: WeakValueDictionary.valuerefs() diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 9056489..5eb6f10 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -152,7 +152,7 @@ ZipFile Objects (:mod:`zlib`, :mod:`bz2` or :mod:`lzma`) is not available, :exc:`RuntimeError` is raised. The default is :const:`ZIP_STORED`. If *allowZip64* is ``True`` (the default) zipfile will create ZIP files that use the ZIP64 - extensions when the zipfile is larger than 2 GiB. If it is false :mod:`zipfile` + extensions when the zipfile is larger than 4 GiB. If it is false :mod:`zipfile` will raise an exception when the ZIP file would require ZIP64 extensions. If the file is created with mode ``'w'``, ``'x'`` or ``'a'`` and then diff --git a/Doc/license.rst b/Doc/license.rst index 8843116..49d29ce 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -87,7 +87,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release| 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 + copyright, i.e., "Copyright © 2001-2017 Python Software Foundation; All Rights Reserved" are retained in Python |release| alone or in any derivative version prepared by Licensee. diff --git a/Doc/make.bat b/Doc/make.bat index da1f876..b1a3738 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -74,7 +74,7 @@ echo. Provided by this script: echo. clean, check, serve, htmlview echo. echo.All arguments past the first one are passed through to sphinx-build as -echo.filenames to build or are ignored. See README.txt in this directory or +echo.filenames to build or are ignored. See README.rst in this directory or echo.the documentation for your version of Sphinx for more exhaustive lists echo.of available targets and descriptions of each. echo. @@ -86,7 +86,7 @@ goto end :build if NOT "%PAPER%" == "" ( - set SPHINXOPTS=-D latex_paper_size=%PAPER% %SPHINXOPTS% + set SPHINXOPTS=-D latex_elements.papersize=%PAPER% %SPHINXOPTS% ) cmd /C %SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . %BUILDDIR%\%* diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 82e35e5..095a238 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -788,11 +788,10 @@ Custom classes Special attributes: :attr:`~definition.__name__` is the class name; :attr:`__module__` is the module name in which the class was defined; :attr:`~object.__dict__` is the dictionary containing the class's namespace; :attr:`~class.__bases__` is a - tuple (possibly empty or a singleton) containing the base classes, in the - order of their occurrence in the base class list; :attr:`__doc__` is the - class's documentation string, or ``None`` if undefined; - :attr:`__annotations__` (optional) is a dictionary containing - :term:`variable annotations ` collected during + tuple containing the base classes, in the order of their occurrence in the + base class list; :attr:`__doc__` is the class's documentation string, + or ``None`` if undefined; :attr:`__annotations__` (optional) is a dictionary + containing :term:`variable annotations ` collected during class body execution. Class instances @@ -1338,11 +1337,14 @@ Basic customization Called by built-in function :func:`hash` and for operations on members of hashed collections including :class:`set`, :class:`frozenset`, and - :class:`dict`. :meth:`__hash__` should return an integer. The only - required property is that objects which compare equal have the same hash - value; it is advised to somehow mix together (e.g. using exclusive or) the - hash values for the components of the object that also play a part in - comparison of objects. + :class:`dict`. :meth:`__hash__` should return an integer. The only required + property is that objects which compare equal have the same hash value; it is + advised to mix together the hash values of the components of the object that + also play a part in comparison of objects by packing them into a tuple and + hashing the tuple. Example:: + + def __hash__(self): + return hash((self.name, self.nick, self.color)) .. note:: diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 39c33bc..f4a8269 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -190,7 +190,7 @@ Since Python 3.6, in an :keyword:`async def` function, an :keyword:`async for` clause may be used to iterate over a :term:`asynchronous iterator`. A comprehension in an :keyword:`async def` function may consist of either a :keyword:`for` or :keyword:`async for` clause following the leading -expression, may contan additonal :keyword:`for` or :keyword:`async for` +expression, may contain additional :keyword:`for` or :keyword:`async for` clauses, and may also use :keyword:`await` expressions. If a comprehension contains either :keyword:`async for` clauses or :keyword:`await` expressions it is called an @@ -827,7 +827,7 @@ series of :term:`arguments `: starred_and_keywords: ("*" `expression` | `keyword_item`) : ("," "*" `expression` | "," `keyword_item`)* keywords_arguments: (`keyword_item` | "**" `expression`) - : ("," `keyword_item` | "**" `expression`)* + : ("," `keyword_item` | "," "**" `expression`)* keyword_item: `identifier` "=" `expression` An optional trailing comma may be present after the positional and keyword arguments @@ -1317,7 +1317,7 @@ built-in types. * Sequences (instances of :class:`tuple`, :class:`list`, or :class:`range`) can be compared only within each of their types, with the restriction that ranges do not support order comparison. Equality comparison across these types - results in unequality, and ordering comparison across these types raises + results in inequality, and ordering comparison across these types raises :exc:`TypeError`. Sequences compare lexicographically using comparison of corresponding @@ -1415,6 +1415,10 @@ some consistency rules, if possible: sequences, but not to sets or mappings). See also the :func:`~functools.total_ordering` decorator. +* The :func:`hash` result should be consistent with equality. + Objects that are equal should either have the same hash value, + or be marked as unhashable. + Python does not enforce these consistency rules. In fact, the not-a-number values are an example for not following these rules. diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 5e2c1c8..4dbd9d8 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -431,7 +431,7 @@ on the module object. If the method returns ``None``, the import machinery will create the new module itself. .. versionadded:: 3.4 - The create_module() method of loaders. + The :meth:`~importlib.abc.Loader.create_module` method of loaders. .. versionchanged:: 3.4 The :meth:`~importlib.abc.Loader.load_module` method was replaced by @@ -464,8 +464,11 @@ import machinery will create the new module itself. .. versionchanged:: 3.5 A :exc:`DeprecationWarning` is raised when ``exec_module()`` is defined but - ``create_module()`` is not. Starting in Python 3.6 it will be an error to not - define ``create_module()`` on a loader attached to a ModuleSpec. + ``create_module()`` is not. + +.. versionchanged:: 3.6 + An :exc:`ImportError` is raised when ``exec_module()`` is defined but + ``create_module()`` is not. Submodules ---------- diff --git a/Doc/tools/extensions/patchlevel.py b/Doc/tools/extensions/patchlevel.py index bca2eb8..919ba4a 100644 --- a/Doc/tools/extensions/patchlevel.py +++ b/Doc/tools/extensions/patchlevel.py @@ -10,6 +10,8 @@ :license: Python license. """ +from __future__ import print_function + import os import re import sys @@ -61,8 +63,8 @@ def get_version_info(): return get_header_version_info('.') except (IOError, OSError): version, release = get_sys_version_info() - print >>sys.stderr, 'Can\'t get version info from Include/patchlevel.h, ' \ - 'using version of this interpreter (%s).' % release + print('Can\'t get version info from Include/patchlevel.h, ' \ + 'using version of this interpreter (%s).' % release, file=sys.stderr) return version, release if __name__ == '__main__': diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 273191b..1141d6c 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -34,7 +34,7 @@ import suspicious ISSUE_URI = 'https://bugs.python.org/issue%s' -SOURCE_URI = 'https://hg.python.org/cpython/file/3.6/%s' +SOURCE_URI = 'https://github.com/python/cpython/tree/3.6/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists from docutils.parsers.rst.states import Body @@ -79,7 +79,7 @@ LaTeXTranslator.depart_literal_block = new_depart_literal_block def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): issue = utils.unescape(text) - text = 'issue ' + issue + text = 'bpo-' + issue refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue) return [refnode], [] @@ -225,7 +225,7 @@ class DeprecatedRemoved(Directive): # Support for including Misc/NEWS -issue_re = re.compile('([Ii])ssue #([0-9]+)') +issue_re = re.compile('(?:[Ii]ssue #|bpo-)([0-9]+)') whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$") @@ -253,7 +253,7 @@ class MiscNews(Directive): text = 'The NEWS file is not available.' node = nodes.strong(text, text) return [node] - content = issue_re.sub(r'`\1ssue #\2 `__', + content = issue_re.sub(r'`bpo-\1 `__', content) content = whatsnew_re.sub(r'\1', content) # remove first 3 lines as they are the main heading diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 96483c4..c6e0311 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -130,10 +130,10 @@ library/exceptions,,:err,err.object[err.start:err.end] library/functions,,:step,a[start:stop:step] library/functions,,:stop,"a[start:stop, i]" library/functions,,:stop,a[start:stop:step] -library/hashlib-blake2,,:vatrogasac,>>> cookie = b'user:vatrogasac' -library/hashlib-blake2,,:vatrogasac,"user:vatrogasac,349cf904533767ed2d755279a8df84d0" -library/hashlib-blake2,,:policajac,">>> compare_digest(b'user:policajac', sig)" -library/hashlib-blake2,,:LEAF,"h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH," +library/hashlib,,:vatrogasac,>>> cookie = b'user:vatrogasac' +library/hashlib,,:vatrogasac,"user:vatrogasac,349cf904533767ed2d755279a8df84d0" +library/hashlib,,:policajac,">>> compare_digest(b'user:policajac', sig)" +library/hashlib,,:LEAF,"h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH," library/http.client,,:port,host:port library/http.cookies,,`,!#$%&'*+-.^_`|~: library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS" diff --git a/Doc/tools/templates/customsourcelink.html b/Doc/tools/templates/customsourcelink.html index 243d810..71d0bba 100644 --- a/Doc/tools/templates/customsourcelink.html +++ b/Doc/tools/templates/customsourcelink.html @@ -3,8 +3,11 @@

{{ _('This Page') }}

{%- endif %} diff --git a/Doc/tools/templates/indexcontent.html b/Doc/tools/templates/indexcontent.html index 1076c1f..d795c0a 100644 --- a/Doc/tools/templates/indexcontent.html +++ b/Doc/tools/templates/indexcontent.html @@ -1,5 +1,12 @@ -{% extends "defindex.html" %} -{% block tables %} +{% extends "layout.html" %} +{%- block htmltitle -%} +{{ shorttitle }} +{%- endblock -%} +{% block body %} +

{{ docstitle|e }}

+

+ {% trans %}Welcome! This is the documentation for Python {{ release }}.{% endtrans %} +

{% trans %}Parts of the documentation:{% endtrans %}

diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html index 5c180e7..640d8b3 100644 --- a/Doc/tools/templates/layout.html +++ b/Doc/tools/templates/layout.html @@ -38,6 +38,7 @@ {% endblock %} {% block extrahead %} + {% if builder != "htmlhelp" %} {% if not embedded %}{% endif %} {% if versionswitcher is defined and not embedded %}{% endif %} diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 75c79d2..e134d5d 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -374,11 +374,11 @@ Surely Python raises an exception when a function that requires an argument is called without any --- even if the argument isn't actually used... Actually, you may have guessed the answer: the special thing about methods is -that the object is passed as the first argument of the function. In our +that the instance object is passed as the first argument of the function. In our example, the call ``x.f()`` is exactly equivalent to ``MyClass.f(x)``. In general, calling a method with a list of *n* arguments is equivalent to calling the corresponding function with an argument list that is created by inserting -the method's object before the first argument. +the method's instance object before the first argument. If you still don't understand how methods work, a look at the implementation can perhaps clarify matters. When an instance attribute is referenced that isn't a @@ -906,4 +906,3 @@ Examples:: namespace; the name :attr:`~object.__dict__` is an attribute but not a global name. Obviously, using this violates the abstraction of namespace implementation, and should be restricted to things like post-mortem debuggers. - diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index d434618..6a9bb48 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -492,8 +492,7 @@ function like this:: for arg in arguments: print(arg) print("-" * 40) - keys = sorted(keywords.keys()) - for kw in keys: + for kw in keywords: print(kw, ":", keywords[kw]) It could be called like this:: @@ -513,13 +512,13 @@ and of course it would print: It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- - client : John Cleese shopkeeper : Michael Palin + client : John Cleese sketch : Cheese Shop Sketch -Note that the list of keyword argument names is created by sorting the result -of the keywords dictionary's ``keys()`` method before printing its contents; -if this is not done, the order in which the arguments are printed is undefined. +Note that the order in which the keyword arguments are printed is guaranteed +to match the order in which they were provided in the function call. + .. _tut-arbitraryargs: diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 953a68b..6140ece 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -22,11 +22,11 @@ objects: Add an item to the end of the list. Equivalent to ``a[len(a):] = [x]``. -.. method:: list.extend(L) +.. method:: list.extend(iterable) :noindex: - Extend the list by appending all the items in the given list. Equivalent to - ``a[len(a):] = L``. + Extend the list by appending all the items from the iterable. Equivalent to + ``a[len(a):] = iterable``. .. method:: list.insert(i, x) @@ -68,7 +68,7 @@ objects: The optional arguments *start* and *end* are interpreted as in the slice notation and are used to limit the search to a particular subsequence of - *x*. The returned index is computed relative to the beginning of the full + the list. The returned index is computed relative to the beginning of the full sequence rather than the *start* argument. diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index faf57a3..3bd100d 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -138,25 +138,24 @@ should follow. To display all these characters properly, your editor must recognize that the file is UTF-8, and it must use a font that supports all the characters in the file. -It is also possible to specify a different encoding for source files. In order -to do this, put one more special comment line right after the ``#!`` line to -define the source file encoding:: +To declare an encoding other than the default one, a special comment line +should be added as the *first* line of the file. The syntax is as follows:: # -*- coding: encoding -*- -With that declaration, everything in the source file will be treated as having -the encoding *encoding* instead of UTF-8. The list of possible encodings can be -found in the Python Library Reference, in the section on :mod:`codecs`. +where *encoding* is one of the valid :mod:`codecs` supported by Python. -For example, if your editor of choice does not support UTF-8 encoded files and -insists on using some other encoding, say Windows-1252, you can write:: +For example, to declare that Windows-1252 encoding is to be used, the first +line of your source code file should be:: # -*- coding: cp-1252 -*- -and still use all characters in the Windows-1252 character set in the source -files. The special encoding comment must be in the *first or second* line -within the file. +One exception to the *first line* rule is when the source code starts with a +:ref:`UNIX "shebang" line `. In this case, the encoding +declaration should be added as the second line of the file. For example:: + #!/usr/bin/env python3 + # -*- coding: cp-1252 -*- .. rubric:: Footnotes diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 7e8ee3e..52120a0 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -359,7 +359,7 @@ The built-in function :func:`len` returns the length of a string:: Information about string formatting with :meth:`str.format`. :ref:`old-string-formatting` - The old formatting operations invoked when strings and Unicode strings are + The old formatting operations invoked when strings are the left operand of the ``%`` operator are described in more detail here. diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index 35db305..1e3d5c0 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -501,7 +501,7 @@ when the ``from...import`` statement is executed. (This also works when ``__all__`` is defined.) Although certain modules are designed to export only names that follow certain -patterns when you use ``import *``, it is still considered bad practise in +patterns when you use ``import *``, it is still considered bad practice in production code. Remember, there is nothing wrong with using ``from Package import diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index c0e64d6..195f63f 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -396,21 +396,23 @@ Miscellaneous options defines the following possible values: * ``-X faulthandler`` to enable :mod:`faulthandler`; - * ``-X showrefcount`` to enable the output of the total reference count - and memory blocks (only works on debug builds); + * ``-X showrefcount`` to output the total reference count and number of used + memory blocks when the program finishes or after each statement in the + interactive interpreter. This only works on debug builds. * ``-X tracemalloc`` to start tracing Python memory allocations using the :mod:`tracemalloc` module. By default, only the most recent frame is stored in a traceback of a trace. Use ``-X tracemalloc=NFRAME`` to start tracing with a traceback limit of *NFRAME* frames. See the :func:`tracemalloc.start` for more information. - * ``-X showalloccount`` to enable the output of the total count of allocated - objects for each type (only works when built with ``COUNT_ALLOCS`` defined); + * ``-X showalloccount`` to output the total count of allocated objects for + each type when the program finishes. This only works when Python was built with + ``COUNT_ALLOCS`` defined. It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. .. versionchanged:: 3.2 - It is now allowed to pass :option:`-X` with CPython. + The :option:`-X` option was added. .. versionadded:: 3.3 The ``-X faulthandler`` option. diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst index 4449d4f..97f0a49 100644 --- a/Doc/using/unix.rst +++ b/Doc/using/unix.rst @@ -132,17 +132,12 @@ some Unices may not have the :program:`env` command, so you may need to hardcode To use shell commands in your Python scripts, look at the :mod:`subprocess` module. -Editors -======= +Editors and IDEs +================ -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: +There are a number of IDEs that support Python programming language. +Many editors and IDEs provide syntax highlighting, debugging tools, and PEP-8 checks. -* http://www.vim.org/scripts/script.php?script_id=790 -* https://sourceforge.net/projects/python-mode - -Geany is an excellent IDE with support for a lot of languages. For more -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 https://komodoide.com/. +Please go to `Python Editors `_ and +`Integrated Development Environments `_ +for a comprehensive list. \ No newline at end of file diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index 010a007..5cbf501 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -145,8 +145,8 @@ strings. Unicode uses 16-bit numbers to represent characters instead of the 8-bit number used by ASCII, meaning that 65,536 distinct characters can be supported. -The final interface for Unicode support was arrived at through countless often- -stormy discussions on the python-dev mailing list, and mostly implemented by +The final interface for Unicode support was arrived at through countless +often-stormy discussions on the python-dev mailing list, and mostly implemented by Marc-André Lemburg, based on a Unicode string type implementation by Fredrik Lundh. A detailed explanation of the interface was written up as :pep:`100`, "Python Unicode Integration". This article will simply cover the most @@ -885,8 +885,8 @@ interfaces for processing XML have become common: SAX2 (version 2 of the Simple API for XML) provides an event-driven interface with some similarities to :mod:`xmllib`, and the DOM (Document Object Model) provides a tree-based interface, transforming an XML document into a tree of nodes that can be -traversed and modified. Python 2.0 includes a SAX2 interface and a stripped- -down DOM interface as part of the :mod:`xml` package. Here we will give a brief +traversed and modified. Python 2.0 includes a SAX2 interface and a stripped-down +DOM interface as part of the :mod:`xml` package. Here we will give a brief overview of these new interfaces; consult the Python documentation or the source code for complete details. The Python XML SIG is also working on improved documentation. diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst index 380edec..3486cdd 100644 --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -159,8 +159,8 @@ precede any statement that will result in bytecodes being produced. PEP 207: Rich Comparisons ========================= -In earlier versions, Python's support for implementing comparisons on user- -defined classes and extension types was quite simple. Classes could implement a +In earlier versions, Python's support for implementing comparisons on user-defined +classes and extension types was quite simple. Classes could implement a :meth:`__cmp__` method that was given two instances of a class, and could only return 0 if they were equal or +1 or -1 if they weren't; the method couldn't raise an exception or return anything other than a Boolean value. Users of @@ -465,11 +465,11 @@ Windows being the primary examples; on these systems, it's impossible to distinguish the filenames ``FILE.PY`` and ``file.py``, even though they do store the file's name in its original case (they're case-preserving, too). -In Python 2.1, the :keyword:`import` statement will work to simulate case- -sensitivity on case-insensitive platforms. Python will now search for the first +In Python 2.1, the :keyword:`import` statement will work to simulate case-sensitivity +on case-insensitive platforms. Python will now search for the first case-sensitive match by default, raising an :exc:`ImportError` if no such file -is found, so ``import file`` will not import a module named ``FILE.PY``. Case- -insensitive matching can be requested by setting the :envvar:`PYTHONCASEOK` +is found, so ``import file`` will not import a module named ``FILE.PY``. +Case-insensitive matching can be requested by setting the :envvar:`PYTHONCASEOK` environment variable before starting the Python interpreter. .. ====================================================================== @@ -481,8 +481,8 @@ PEP 217: Interactive Display Hook When using the Python interpreter interactively, the output of commands is displayed using the built-in :func:`repr` function. In Python 2.1, the variable :func:`sys.displayhook` can be set to a callable object which will be called -instead of :func:`repr`. For example, you can set it to a special pretty- -printing function:: +instead of :func:`repr`. For example, you can set it to a special +pretty-printing function:: >>> # Create a recursive data structure ... L = [1,2,3] diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index 5f28c29..a0bb81a 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -962,8 +962,8 @@ New and Improved Modules * The new :mod:`hmac` module implements the HMAC algorithm described by :rfc:`2104`. (Contributed by Gerhard Häring.) -* Several functions that originally returned lengthy tuples now return pseudo- - sequences that still behave like tuples but also have mnemonic attributes such +* Several functions that originally returned lengthy tuples now return + pseudo-sequences that still behave like tuples but also have mnemonic attributes such as memberst_mtime or :attr:`tm_year`. The enhanced functions include :func:`stat`, :func:`fstat`, :func:`statvfs`, and :func:`fstatvfs` in the :mod:`os` module, and :func:`localtime`, :func:`gmtime`, and :func:`strptime` in @@ -1141,8 +1141,8 @@ Some of the more notable changes are: The most significant change is the ability to build Python as a framework, enabled by supplying the :option:`!--enable-framework` option to the configure - script when compiling Python. According to Jack Jansen, "This installs a self- - contained Python installation plus the OS X framework "glue" into + script when compiling Python. According to Jack Jansen, "This installs a + self-contained Python installation plus the OS X framework "glue" into :file:`/Library/Frameworks/Python.framework` (or another location of choice). For now there is little immediate added benefit to this (actually, there is the disadvantage that you have to change your PATH to be able to find Python), but diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index 93930b8..cebfb21 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -86,8 +86,8 @@ The union and intersection of sets can be computed with the :meth:`union` and It's also possible to take the symmetric difference of two sets. This is the set of all elements in the union that aren't in the intersection. Another way of putting it is that the symmetric difference contains all elements that are in -exactly one set. Again, there's an alternative notation (``^``), and an in- -place version with the ungainly name :meth:`symmetric_difference_update`. :: +exactly one set. Again, there's an alternative notation (``^``), and an +in-place version with the ungainly name :meth:`symmetric_difference_update`. :: >>> S1 = sets.Set([1,2,3,4]) >>> S2 = sets.Set([3,4,5,6]) @@ -288,8 +288,8 @@ use characters outside of the usual alphanumerics. PEP 273: Importing Modules from ZIP Archives ============================================ -The new :mod:`zipimport` module adds support for importing modules from a ZIP- -format archive. You don't need to import the module explicitly; it will be +The new :mod:`zipimport` module adds support for importing modules from a +ZIP-format archive. You don't need to import the module explicitly; it will be automatically imported if a ZIP archive's filename is added to ``sys.path``. For example: @@ -375,8 +375,8 @@ PEP 278: Universal Newline Support ================================== The three major operating systems used today are Microsoft Windows, Apple's -Macintosh OS, and the various Unix derivatives. A minor irritation of cross- -platform work is that these three platforms all use different characters to +Macintosh OS, and the various Unix derivatives. A minor irritation of +cross-platform work is that these three platforms all use different characters to mark the ends of lines in text files. Unix uses the linefeed (ASCII character 10), MacOS uses the carriage return (ASCII character 13), and Windows uses a two-character sequence of a carriage return plus a newline. diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst index 8db90cc..7c125ff 100644 --- a/Doc/whatsnew/2.4.rst +++ b/Doc/whatsnew/2.4.rst @@ -517,8 +517,8 @@ Sometimes you can see this inaccuracy when the number is printed:: >>> 1.1 1.1000000000000001 -The inaccuracy isn't always visible when you print the number because the FP-to- -decimal-string conversion is provided by the C library, and most C libraries try +The inaccuracy isn't always visible when you print the number because the +FP-to-decimal-string conversion is provided by the C library, and most C libraries try to produce sensible output. Even if it's not displayed, however, the inaccuracy is still there and subsequent operations can magnify the error. @@ -595,8 +595,8 @@ exponent:: ... decimal.InvalidOperation: x ** (non-integer) -You can combine :class:`Decimal` instances with integers, but not with floating- -point numbers:: +You can combine :class:`Decimal` instances with integers, but not with +floating-point numbers:: >>> a + 4 Decimal("39.72") @@ -684,8 +684,8 @@ includes a quick-start tutorial and a reference. Raymond Hettinger, Aahz, and Tim Peters. http://www.lahey.com/float.htm - The article uses Fortran code to illustrate many of the problems that floating- - point inaccuracy can cause. + The article uses Fortran code to illustrate many of the problems that + floating-point inaccuracy can cause. http://speleotrove.com/decimal/ A description of a decimal-based representation. This representation is being @@ -741,8 +741,8 @@ functions in Python's implementation required that the numeric locale remain set to the ``'C'`` locale. Often this was because the code was using the C library's :c:func:`atof` function. -Not setting the numeric locale caused trouble for extensions that used third- -party C libraries, however, because they wouldn't have the correct locale set. +Not setting the numeric locale caused trouble for extensions that used third-party +C libraries, however, because they wouldn't have the correct locale set. The motivating example was GTK+, whose user interface widgets weren't displaying numbers in the current locale. @@ -918,8 +918,8 @@ Here are all of the changes that Python 2.4 makes to the core Python language. (Contributed by Raymond Hettinger.) -* Encountering a failure while importing a module no longer leaves a partially- - initialized module object in ``sys.modules``. The incomplete module object left +* Encountering a failure while importing a module no longer leaves a partially-initialized + module object in ``sys.modules``. The incomplete module object left behind would fool further imports of the same module into succeeding, leading to confusing errors. (Fixed by Tim Peters.) @@ -1028,8 +1028,8 @@ complete list of changes, or look through the CVS logs for all the details. previous ones left off. (Implemented by Walter Dörwald.) * There is a new :mod:`collections` module for various specialized collection - datatypes. Currently it contains just one type, :class:`deque`, a double- - ended queue that supports efficiently adding and removing elements from either + datatypes. Currently it contains just one type, :class:`deque`, a double-ended + queue that supports efficiently adding and removing elements from either end:: >>> from collections import deque @@ -1485,8 +1485,8 @@ Some of the changes to Python's build process and to the C API are: intended as an aid to people developing the Python core. Providing :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.) @@ -1540,8 +1540,8 @@ code: * The :mod:`tarfile` module now generates GNU-format tar files by default. -* Encountering a failure while importing a module no longer leaves a partially- - initialized module object in ``sys.modules``. +* Encountering a failure while importing a module no longer leaves a + partially-initialized module object in ``sys.modules``. * :const:`None` is now a constant; code that binds a new value to the name ``None`` is now a syntax error. diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index db8f9df..4d48291 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -157,8 +157,8 @@ Here's a small but realistic example:: server_log = functools.partial(log, subsystem='server') server_log('Unable to open socket') -Here's another example, from a program that uses PyGTK. Here a context- -sensitive pop-up menu is being constructed dynamically. The callback provided +Here's another example, from a program that uses PyGTK. Here a context-sensitive +pop-up menu is being constructed dynamically. The callback provided for the menu option is a partially applied version of the :meth:`open_item` method, where the first argument has been provided. :: @@ -171,8 +171,8 @@ method, where the first argument has been provided. :: popup_menu.append( ("Open", open_func, 1) ) Another function in the :mod:`functools` module is the -``update_wrapper(wrapper, wrapped)`` function that helps you write well- -behaved decorators. :func:`update_wrapper` copies the name, module, and +``update_wrapper(wrapper, wrapped)`` function that helps you write +well-behaved decorators. :func:`update_wrapper` copies the name, module, and docstring attribute to a wrapper function so that tracebacks inside the wrapped function are easier to understand. For example, you might write:: @@ -297,8 +297,8 @@ can't protect against having your submodule's name being used for a new module added in a future version of Python. In Python 2.5, you can switch :keyword:`import`'s behaviour to absolute imports -using a ``from __future__ import absolute_import`` directive. This absolute- -import behaviour will become the default in a future version (probably Python +using a ``from __future__ import absolute_import`` directive. This absolute-import +behaviour will become the default in a future version (probably Python 2.7). Once absolute imports are the default, ``import string`` will always find the standard library's version. It's suggested that users should begin using absolute imports as much as possible, so it's preferable to begin writing @@ -602,8 +602,8 @@ be used with the ':keyword:`with`' statement. File objects are one example:: ... more processing code ... After this statement has executed, the file object in *f* will have been -automatically closed, even if the :keyword:`for` loop raised an exception part- -way through the block. +automatically closed, even if the :keyword:`for` loop raised an exception +part-way through the block. .. note:: @@ -1558,8 +1558,8 @@ complete list of changes, or look through the SVN logs for all the details. You can also pack and unpack data to and from buffer objects directly using the ``pack_into(buffer, offset, v1, v2, ...)`` and ``unpack_from(buffer, - offset)`` methods. This lets you store data directly into an array or a memory- - mapped file. + offset)`` methods. This lets you store data directly into an array or a + memory-mapped file. (:class:`Struct` objects were implemented by Bob Ippolito at the NeedForSpeed sprint. Support for buffer objects was added by Martin Blais, also at the @@ -2281,8 +2281,8 @@ Acknowledgements The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this article: Georg Brandl, -Nick Coghlan, Phillip J. Eby, Lars Gustäbel, Raymond Hettinger, Ralf W. Grosse- -Kunstleve, Kent Johnson, Iain Lowe, Martin von Löwis, Fredrik Lundh, Andrew +Nick Coghlan, Phillip J. Eby, Lars Gustäbel, Raymond Hettinger, Ralf W. +Grosse-Kunstleve, Kent Johnson, Iain Lowe, Martin von Löwis, Fredrik Lundh, Andrew McNamara, Skip Montanaro, Gustavo Niemeyer, Paul Prescod, James Pryor, Mike Rovner, Scott Weikart, Barry Warsaw, Thomas Wouters. diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index 4fc0c36..cc2fa3d 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -290,8 +290,8 @@ be used with the ':keyword:`with`' statement. File objects are one example:: ... more processing code ... After this statement has executed, the file object in *f* will have been -automatically closed, even if the :keyword:`for` loop raised an exception part- -way through the block. +automatically closed, even if the :keyword:`for` loop raised an exception +part-way through the block. .. note:: diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index edb74f0..a6ba5bb 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -2327,11 +2327,12 @@ The :func:`inspect.getargspec` function is deprecated and scheduled to be removed in Python 3.6. (See :issue:`20438` for details.) The :mod:`inspect` :func:`~inspect.getfullargspec`, -:func:`~inspect.getargvalues`, :func:`~inspect.getcallargs`, -:func:`~inspect.getargvalues`, :func:`~inspect.formatargspec`, and -:func:`~inspect.formatargvalues` functions are deprecated in favor of -the :func:`inspect.signature` API. -(Contributed by Yury Selivanov in :issue:`20438`.) +:func:`~inspect.getcallargs`, and :func:`~inspect.formatargspec` functions are +deprecated in favor of the :func:`inspect.signature` API. (Contributed by Yury +Selivanov in :issue:`20438`.) + +:func:`~inspect.getargvalues` and :func:`~inspect.formatargvalues` functions +were inadvertently marked as deprecated with the release of Python 3.5.0. Use of :const:`re.LOCALE` flag with str patterns or :const:`re.ASCII` is now deprecated. (Contributed by Serhiy Storchaka in :issue:`22407`.) diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index c0d8ac4..a696af4 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -2,8 +2,6 @@ What's New In Python 3.6 **************************** -:Release: |release| -:Date: |today| :Editors: Elvis Pranskevichus , Yury Selivanov .. Rules for maintenance: @@ -81,7 +79,9 @@ CPython implementation improvements: * The :ref:`dict ` type has been reimplemented to use a :ref:`more compact representation ` - similar to the `PyPy dict implementation`_. This resulted in dictionaries + based on `a proposal by Raymond Hettinger + `_ + and similar to the `PyPy dict implementation`_. This resulted in dictionaries using 20% to 25% less memory when compared to Python 3.5. * Customization of class creation has been simplified with the @@ -118,7 +118,7 @@ Significant improvements in the standard library: :ref:`Local Time Disambiguation `. * The :mod:`typing` module received a number of - :ref:`improvements ` and is no longer provisional. + :ref:`improvements `. * The :mod:`tracemalloc` module has been significantly reworked and is now used to provide better output for :exc:`ResourceWarning` @@ -363,7 +363,7 @@ ensure that the new ``__classcell__`` namespace entry is propagated to PEP 487: Descriptor Protocol Enhancements ----------------------------------------- -:pep:`487` extends the descriptor protocol has to include the new optional +:pep:`487` extends the descriptor protocol to include the new optional :meth:`~object.__set_name__` method. Whenever a new class is defined, the new method will be called on all descriptors included in the definition, providing them with a reference to the class being defined and the name given to the @@ -581,7 +581,10 @@ New :ref:`dict ` implementation --------------------------------------------- The :ref:`dict ` type now uses a "compact" representation -`pioneered by PyPy `_. +based on `a proposal by Raymond Hettinger +`_ +which was `first implemented by PyPy +`_. The memory usage of the new :func:`dict` is between 20% and 25% smaller compared to Python 3.5. @@ -1366,6 +1369,9 @@ The socket module now supports the address family (Contributed by Christian Heimes in :issue:`27744` with support from Victor Stinner.) +New Linux constants ``TCP_USER_TIMEOUT`` and ``TCP_CONGESTION`` were added. +(Contributed by Omar Sandoval, issue:`26273`). + socketserver ------------ @@ -1539,11 +1545,8 @@ to filter block traces by their address space (domain). typing ------ -Starting with Python 3.6 the :mod:`typing` module is no longer provisional -and its API is considered stable. - -Since the :mod:`typing` module was :term:`provisional ` -in Python 3.5, all changes introduced in Python 3.6 have also been +Since the :mod:`typing` module is :term:`provisional `, +all changes introduced in Python 3.6 have also been backported to Python 3.5.x. The :mod:`typing` module has a much improved support for generic type @@ -1816,7 +1819,7 @@ Build and C API Changes * The ``--enable-optimizations`` configure flag has been added. Turning it on will activate expensive optimizations like PGO. - (Original patch by Alecsandru Patrascu of Intel in :issue:`26539`.) + (Original patch by Alecsandru Patrascu of Intel in :issue:`26359`.) * The :term:`GIL ` must now be held when allocator functions of :c:data:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and diff --git a/Grammar/Grammar b/Grammar/Grammar index b139e9f..59c807e 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -1,12 +1,5 @@ # Grammar for Python -# Note: Changing the grammar specified in this file will most likely -# require corresponding changes in the parser module -# (../Modules/parsermodule.c). If you can't make the changes to -# that module yourself, please co-ordinate the required changes -# with someone who can; ask around on python-dev for help. Fred -# Drake will probably be listening there. - # NOTE WELL: You should also follow all the steps listed at # https://docs.python.org/devguide/grammar.html diff --git a/Include/abstract.h b/Include/abstract.h index 03f8dbb..7d137a2 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -750,11 +750,13 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ o1*o2. */ +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2); /* This is the equivalent of the Python expression: o1 @ o2. */ +#endif PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2); @@ -930,11 +932,13 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ o1 *= o2. */ +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2); /* This is the equivalent of the Python expression: o1 @= o2. */ +#endif PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2); diff --git a/Include/bytesobject.h b/Include/bytesobject.h index 98e29b6..0f0bf9f 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -74,11 +74,13 @@ PyAPI_FUNC(PyObject*) _PyBytes_FromHex( PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, const char *, Py_ssize_t, const char *); +#ifndef Py_LIMITED_API /* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, const char *, Py_ssize_t, const char *, const char **); +#endif /* Macro, trading safety for speed */ #ifndef Py_LIMITED_API diff --git a/Include/codecs.h b/Include/codecs.h index f8275a1..3ad0f2b 100644 --- a/Include/codecs.h +++ b/Include/codecs.h @@ -225,10 +225,14 @@ PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc); /* replace the unicode encode error with backslash escapes (\x, \u and \U) */ PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 /* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */ PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc); +#endif +#ifndef Py_LIMITED_API PyAPI_DATA(const char *) Py_hexdigits; +#endif #ifdef __cplusplus } diff --git a/Include/dictobject.h b/Include/dictobject.h index 30f114e..c4f2e2f 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -88,6 +88,8 @@ PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, Py_hash_t hash); +PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key, + int (*predicate)(PyObject *value)); #endif PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); PyAPI_FUNC(int) PyDict_Next( @@ -113,6 +115,7 @@ PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys); Py_ssize_t _PyDict_SizeOf(PyDictObject *); PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *); +PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *); PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); #define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) diff --git a/Include/fileobject.h b/Include/fileobject.h index 03984ba..6120e51 100644 --- a/Include/fileobject.h +++ b/Include/fileobject.h @@ -23,7 +23,9 @@ PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); If non-NULL, this is different than the default encoding for strings */ PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; +#endif PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; /* Internal API diff --git a/Include/fileutils.h b/Include/fileutils.h index 4016431..b933e98 100644 --- a/Include/fileutils.h +++ b/Include/fileutils.h @@ -5,6 +5,7 @@ extern "C" { #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_FUNC(wchar_t *) Py_DecodeLocale( const char *arg, size_t *size); @@ -12,6 +13,7 @@ PyAPI_FUNC(wchar_t *) Py_DecodeLocale( PyAPI_FUNC(char*) Py_EncodeLocale( const wchar_t *text, size_t *error_pos); +#endif #ifndef Py_LIMITED_API diff --git a/Include/import.h b/Include/import.h index 46c0d8e..bb6beba 100644 --- a/Include/import.h +++ b/Include/import.h @@ -9,9 +9,9 @@ extern "C" { #ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyImportZip_Init(void); -#endif /* !Py_LIMITED_API */ PyMODINIT_FUNC PyInit_imp(void); +#endif /* !Py_LIMITED_API */ PyAPI_FUNC(long) PyImport_GetMagicNumber(void); PyAPI_FUNC(const char *) PyImport_GetMagicTag(void); PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule( @@ -29,16 +29,20 @@ PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleWithPathnames( const char *pathname, /* decoded from the filesystem encoding */ const char *cpathname /* decoded from the filesystem encoding */ ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleObject( PyObject *name, PyObject *co, PyObject *pathname, PyObject *cpathname ); +#endif PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyImport_AddModuleObject( PyObject *name ); +#endif PyAPI_FUNC(PyObject *) PyImport_AddModule( const char *name /* UTF-8 encoded string */ ); @@ -55,6 +59,7 @@ PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel( PyObject *fromlist, int level ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject( PyObject *name, PyObject *globals, @@ -62,6 +67,7 @@ PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject( PyObject *fromlist, int level ); +#endif #define PyImport_ImportModuleEx(n, g, l, f) \ PyImport_ImportModuleLevel(n, g, l, f, 0) @@ -70,9 +76,11 @@ PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path); PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m); PyAPI_FUNC(void) PyImport_Cleanup(void); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(int) PyImport_ImportFrozenModuleObject( PyObject *name ); +#endif PyAPI_FUNC(int) PyImport_ImportFrozenModule( const char *name /* UTF-8 encoded string */ ); diff --git a/Include/memoryobject.h b/Include/memoryobject.h index ab5ee09..990a716 100644 --- a/Include/memoryobject.h +++ b/Include/memoryobject.h @@ -21,8 +21,10 @@ PyAPI_DATA(PyTypeObject) PyMemoryView_Type; #endif PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags); +#endif #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(Py_buffer *info); #endif diff --git a/Include/modsupport.h b/Include/modsupport.h index 833e33d..86719c6 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -15,10 +15,8 @@ extern "C" { #define PyArg_Parse _PyArg_Parse_SizeT #define PyArg_ParseTuple _PyArg_ParseTuple_SizeT #define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT -#ifndef Py_LIMITED_API #define PyArg_VaParse _PyArg_VaParse_SizeT #define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT -#endif /* !Py_LIMITED_API */ #define Py_BuildValue _Py_BuildValue_SizeT #define Py_VaBuildValue _Py_VaBuildValue_SizeT #else @@ -33,18 +31,18 @@ PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, const char *, char **, ...); +PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); +PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, va_list); +#endif PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *); PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); -#endif + #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kw); PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); - -PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); -PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, va_list); #endif PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); diff --git a/Include/moduleobject.h b/Include/moduleobject.h index b44fb9b..b6e4933 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -12,14 +12,18 @@ PyAPI_DATA(PyTypeObject) PyModule_Type; #define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) #define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyModule_NewObject( PyObject *name ); +#endif PyAPI_FUNC(PyObject *) PyModule_New( const char *name /* UTF-8 encoded string */ ); PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyModule_GetNameObject(PyObject *); +#endif PyAPI_FUNC(const char *) PyModule_GetName(PyObject *); PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *); PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *); diff --git a/Include/object.h b/Include/object.h index 338ec1b..63e37b8 100644 --- a/Include/object.h +++ b/Include/object.h @@ -547,7 +547,9 @@ PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(int) PyObject_GenericSetDict(PyObject *, PyObject *, void *); +#endif PyAPI_FUNC(Py_hash_t) PyObject_Hash(PyObject *); PyAPI_FUNC(Py_hash_t) PyObject_HashNotImplemented(PyObject *); PyAPI_FUNC(int) PyObject_IsTrue(PyObject *); diff --git a/Include/objimpl.h b/Include/objimpl.h index c0ed9b7..746f9c9 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -95,7 +95,9 @@ PyObject_{New, NewVar, Del}. the raw memory. */ PyAPI_FUNC(void *) PyObject_Malloc(size_t size); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_FUNC(void *) PyObject_Calloc(size_t nelem, size_t elsize); +#endif PyAPI_FUNC(void *) PyObject_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyObject_Free(void *ptr); diff --git a/Include/odictobject.h b/Include/odictobject.h index c1d9592..381de58 100644 --- a/Include/odictobject.h +++ b/Include/odictobject.h @@ -17,12 +17,13 @@ PyAPI_DATA(PyTypeObject) PyODictKeys_Type; PyAPI_DATA(PyTypeObject) PyODictItems_Type; PyAPI_DATA(PyTypeObject) PyODictValues_Type; -#endif /* Py_LIMITED_API */ - #define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) #define PyODict_CheckExact(op) (Py_TYPE(op) == &PyODict_Type) #define PyODict_SIZE(op) ((PyDictObject *)op)->ma_used -#define PyODict_HasKey(od, key) (PyMapping_HasKey(PyObject *)od, key) + +#endif /* Py_LIMITED_API */ + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_FUNC(PyObject *) PyODict_New(void); PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); @@ -37,6 +38,8 @@ PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); #define PyODict_GetItemString(od, key) \ PyDict_GetItemString((PyObject *)od, key) +#endif + #ifdef __cplusplus } #endif diff --git a/Include/osmodule.h b/Include/osmodule.h index 7146757..9095c2f 100644 --- a/Include/osmodule.h +++ b/Include/osmodule.h @@ -7,7 +7,9 @@ extern "C" { #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 PyAPI_FUNC(PyObject *) PyOS_FSPath(PyObject *path); +#endif #ifdef __cplusplus } diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 92a63bd..54a9ab6 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 6 -#define PY_MICRO_VERSION 0 +#define PY_MICRO_VERSION 1 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.6.0" +#define PY_VERSION "3.6.1" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/pyerrors.h b/Include/pyerrors.h index f9f74c0..8c1dbc5 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -87,8 +87,10 @@ PyAPI_FUNC(PyObject *) PyErr_Occurred(void); PyAPI_FUNC(void) PyErr_Clear(void); PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(void) PyErr_GetExcInfo(PyObject **, PyObject **, PyObject **); PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); +#endif #if defined(__clang__) || \ (defined(__GNUC_MAJOR__) && \ @@ -147,7 +149,9 @@ PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); PyAPI_DATA(PyObject *) PyExc_BaseException; PyAPI_DATA(PyObject *) PyExc_Exception; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_DATA(PyObject *) PyExc_StopAsyncIteration; +#endif PyAPI_DATA(PyObject *) PyExc_StopIteration; PyAPI_DATA(PyObject *) PyExc_GeneratorExit; PyAPI_DATA(PyObject *) PyExc_ArithmeticError; @@ -160,7 +164,9 @@ PyAPI_DATA(PyObject *) PyExc_EOFError; PyAPI_DATA(PyObject *) PyExc_FloatingPointError; PyAPI_DATA(PyObject *) PyExc_OSError; PyAPI_DATA(PyObject *) PyExc_ImportError; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 PyAPI_DATA(PyObject *) PyExc_ModuleNotFoundError; +#endif PyAPI_DATA(PyObject *) PyExc_IndexError; PyAPI_DATA(PyObject *) PyExc_KeyError; PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt; @@ -168,7 +174,9 @@ PyAPI_DATA(PyObject *) PyExc_MemoryError; PyAPI_DATA(PyObject *) PyExc_NameError; PyAPI_DATA(PyObject *) PyExc_OverflowError; PyAPI_DATA(PyObject *) PyExc_RuntimeError; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_DATA(PyObject *) PyExc_RecursionError; +#endif PyAPI_DATA(PyObject *) PyExc_NotImplementedError; PyAPI_DATA(PyObject *) PyExc_SyntaxError; PyAPI_DATA(PyObject *) PyExc_IndentationError; @@ -185,6 +193,7 @@ PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError; PyAPI_DATA(PyObject *) PyExc_ValueError; PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_DATA(PyObject *) PyExc_BlockingIOError; PyAPI_DATA(PyObject *) PyExc_BrokenPipeError; PyAPI_DATA(PyObject *) PyExc_ChildProcessError; @@ -200,6 +209,7 @@ PyAPI_DATA(PyObject *) PyExc_NotADirectoryError; PyAPI_DATA(PyObject *) PyExc_PermissionError; PyAPI_DATA(PyObject *) PyExc_ProcessLookupError; PyAPI_DATA(PyObject *) PyExc_TimeoutError; +#endif /* Compatibility aliases */ @@ -232,8 +242,10 @@ PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObjects( PyObject *, PyObject *, PyObject *); +#endif PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename( PyObject *exc, const char *filename /* decoded from the filesystem encoding */ @@ -279,8 +291,10 @@ PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( PyObject *,int, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObjects( PyObject *,int, PyObject *, PyObject *); +#endif PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( PyObject *exc, int ierr, @@ -293,13 +307,14 @@ PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename( PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); #endif /* MS_WINDOWS */ -PyAPI_FUNC(PyObject *) PyErr_SetExcWithArgsKwargs(PyObject *, PyObject *, - PyObject *); - +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 PyAPI_FUNC(PyObject *) PyErr_SetImportErrorSubclass(PyObject *, PyObject *, PyObject *, PyObject *); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyErr_SetImportError(PyObject *, PyObject *, PyObject *); +#endif /* Export the old function so that the existing API remains available: */ PyAPI_FUNC(void) PyErr_BadInternalCall(void); diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index 5a67666..01abfa9 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -70,8 +70,8 @@ PyAPI_FUNC(const char *) Py_GetCopyright(void); PyAPI_FUNC(const char *) Py_GetCompiler(void); PyAPI_FUNC(const char *) Py_GetBuildInfo(void); #ifndef Py_LIMITED_API -PyAPI_FUNC(const char *) _Py_hgidentifier(void); -PyAPI_FUNC(const char *) _Py_hgversion(void); +PyAPI_FUNC(const char *) _Py_gitidentifier(void); +PyAPI_FUNC(const char *) _Py_gitversion(void); #endif /* Internal -- various one-time initializations */ diff --git a/Include/pymem.h b/Include/pymem.h index ce63bf8..a7eb4d2 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -101,7 +101,9 @@ PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback( */ PyAPI_FUNC(void *) PyMem_Malloc(size_t size); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); +#endif PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyMem_Free(void *ptr); diff --git a/Include/pyport.h b/Include/pyport.h index 28bf4b2..426822a 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -37,9 +37,9 @@ Used in: Py_SAFE_DOWNCAST * integral synonyms. Only define the ones we actually need. */ -// long long is required. Ensure HAVE_LONG_LONG is defined for compatibility. +/* long long is required. Ensure HAVE_LONG_LONG is defined for compatibility. */ #ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG +#define HAVE_LONG_LONG 1 #endif #ifndef PY_LONG_LONG #define PY_LONG_LONG long long diff --git a/Include/pythonrun.h b/Include/pythonrun.h index cfa0a9f..efc613f 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -91,9 +91,11 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFromFileObject( #endif PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, int); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlagsFilename(const char *, const char *, int, int); +#endif PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *, int, int); diff --git a/Include/pythread.h b/Include/pythread.h index dd681be..88c4873 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -69,7 +69,9 @@ PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock); PyAPI_FUNC(size_t) PyThread_get_stacksize(void); PyAPI_FUNC(int) PyThread_set_stacksize(size_t); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject*) PyThread_GetInfo(void); +#endif /* Thread Local Storage (TLS) API */ PyAPI_FUNC(int) PyThread_create_key(void); diff --git a/Include/sliceobject.h b/Include/sliceobject.h index 26370e0..3626354 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -41,8 +41,21 @@ PyAPI_FUNC(int) _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, - Py_ssize_t *step, Py_ssize_t *slicelength); + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t *step, Py_ssize_t *slicelength); + +#if !defined(Py_LIMITED_API) || (Py_LIMITED_API+0 >= 0x03050400 && Py_LIMITED_API+0 < 0x03060000) || Py_LIMITED_API+0 >= 0x03060100 +#define PySlice_GetIndicesEx(slice, length, start, stop, step, slicelen) ( \ + PySlice_Unpack((slice), (start), (stop), (step)) < 0 ? \ + ((*(slicelen) = 0), -1) : \ + ((*(slicelen) = PySlice_AdjustIndices((length), (start), (stop), *(step))), \ + 0)) +PyAPI_FUNC(int) PySlice_Unpack(PyObject *slice, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +PyAPI_FUNC(Py_ssize_t) PySlice_AdjustIndices(Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t step); +#endif #ifdef __cplusplus } diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 8103a63..587cf03 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -718,10 +718,12 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FromASCII( Py_ssize_t size); #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject*) PyUnicode_Substring( PyObject *str, Py_ssize_t start, Py_ssize_t end); +#endif #ifndef Py_LIMITED_API /* Compute the maximum character of the substring unicode[start:end]. @@ -732,6 +734,7 @@ PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar ( Py_ssize_t end); #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* Copy the string into a UCS4 buffer including the null character if copy_null is set. Return NULL and raise an exception on error. Raise a SystemError if the buffer is smaller than the string. Return buffer on success. @@ -747,6 +750,7 @@ PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4( * PyMem_Malloc; if this fails, NULL is returned with a memory error exception set. */ PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4Copy(PyObject *unicode); +#endif /* Return a read-only pointer to the Unicode object's internal Py_UNICODE buffer. @@ -771,11 +775,13 @@ PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( ); #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* Get the length of the Unicode object. */ PyAPI_FUNC(Py_ssize_t) PyUnicode_GetLength( PyObject *unicode ); +#endif /* Get the number of Py_UNICODE units in the string representation. */ @@ -784,6 +790,7 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( PyObject *unicode /* Unicode object */ ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* Read a character from the string. */ PyAPI_FUNC(Py_UCS4) PyUnicode_ReadChar( @@ -801,6 +808,7 @@ PyAPI_FUNC(int) PyUnicode_WriteChar( Py_ssize_t index, Py_UCS4 character ); +#endif #ifndef Py_LIMITED_API /* Get the maximum ordinal for a Unicode character. */ @@ -1486,6 +1494,7 @@ PyAPI_FUNC(PyObject*) PyUnicode_DecodeUnicodeEscape( const char *errors /* error handling */ ); +#ifndef Py_LIMITED_API /* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape chars. */ PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscape( @@ -1496,6 +1505,7 @@ PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscape( invalid escaped char in string. */ ); +#endif PyAPI_FUNC(PyObject*) PyUnicode_AsUnicodeEscapeString( PyObject *unicode /* Unicode object */ @@ -1686,6 +1696,7 @@ PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCSStateful( Py_ssize_t *consumed /* bytes consumed */ ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject*) PyUnicode_DecodeCodePageStateful( int code_page, /* code page number */ const char *string, /* encoded string */ @@ -1693,6 +1704,7 @@ PyAPI_FUNC(PyObject*) PyUnicode_DecodeCodePageStateful( const char *errors, /* error handling */ Py_ssize_t *consumed /* bytes consumed */ ); +#endif PyAPI_FUNC(PyObject*) PyUnicode_AsMBCSString( PyObject *unicode /* Unicode object */ @@ -1706,11 +1718,13 @@ PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( ); #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject*) PyUnicode_EncodeCodePage( int code_page, /* code page number */ PyObject *unicode, /* Unicode object */ const char *errors /* error handling */ ); +#endif #endif /* MS_WINDOWS */ @@ -1773,6 +1787,7 @@ PyAPI_FUNC(PyObject*) _PyUnicode_TransformDecimalAndSpaceToASCII( /* --- Locale encoding --------------------------------------------------- */ +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* Decode a string from the current locale encoding. The decoder is strict if *surrogateescape* is equal to zero, otherwise it uses the 'surrogateescape' error handler (PEP 383) to escape undecodable bytes. If a byte sequence can @@ -1802,6 +1817,7 @@ PyAPI_FUNC(PyObject*) PyUnicode_EncodeLocale( PyObject *unicode, const char *errors ); +#endif /* --- File system encoding ---------------------------------------------- */ @@ -1998,6 +2014,7 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_Find( int direction /* Find direction: +1 forward, -1 backward */ ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* Like PyUnicode_Find, but search for single character only. */ PyAPI_FUNC(Py_ssize_t) PyUnicode_FindChar( PyObject *str, @@ -2006,6 +2023,7 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_FindChar( Py_ssize_t end, int direction ); +#endif /* Count the number of occurrences of substr in str[start:end]. */ @@ -2075,10 +2093,6 @@ PyAPI_FUNC(int) _PyUnicode_EqualToASCIIString( - Py_True or Py_False for successful comparisons - Py_NotImplemented in case the type combination is unknown - Note that Py_EQ and Py_NE comparisons can cause a UnicodeWarning in - case the conversion of the arguments to Unicode fails with a - UnicodeDecodeError. - Possible values for op: Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE diff --git a/Include/warnings.h b/Include/warnings.h index c1c6992..a3f83ff 100644 --- a/Include/warnings.h +++ b/Include/warnings.h @@ -18,12 +18,14 @@ PyAPI_FUNC(int) PyErr_WarnFormat( const char *format, /* ASCII-encoded string */ ...); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 /* Emit a ResourceWarning warning */ PyAPI_FUNC(int) PyErr_ResourceWarning( PyObject *source, Py_ssize_t stack_level, const char *format, /* ASCII-encoded string */ ...); +#endif #ifndef Py_LIMITED_API PyAPI_FUNC(int) PyErr_WarnExplicitObject( PyObject *category, diff --git a/LICENSE b/LICENSE index 84a3337..f5d0b39 100644 --- a/LICENSE +++ b/LICENSE @@ -74,7 +74,7 @@ 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 +2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. diff --git a/Lib/_pyio.py b/Lib/_pyio.py index d0947f0..2ebfb05 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -277,7 +277,7 @@ class OpenWrapper: try: UnsupportedOperation = io.UnsupportedOperation except AttributeError: - class UnsupportedOperation(ValueError, OSError): + class UnsupportedOperation(OSError, ValueError): pass diff --git a/Lib/aifc.py b/Lib/aifc.py index 692d0bf..13ad7dc 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -303,6 +303,8 @@ class Aifc_read: # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk # _framesize -- size of one frame in the file + _file = None # Set here since __del__ checks it + def initfp(self, file): self._version = 0 self._convert = None @@ -344,9 +346,15 @@ class Aifc_read: def __init__(self, f): if isinstance(f, str): - f = builtins.open(f, 'rb') - # else, assume it is an open file object already - self.initfp(f) + file_object = builtins.open(f, 'rb') + try: + self.initfp(file_object) + except: + file_object.close() + raise + else: + # assume it is an open file object already + self.initfp(f) def __enter__(self): return self @@ -541,18 +549,23 @@ class Aifc_write: # _datalength -- the size of the audio samples written to the header # _datawritten -- the size of the audio samples actually written + _file = None # Set here since __del__ checks it + def __init__(self, f): if isinstance(f, str): - filename = f - f = builtins.open(f, 'wb') - else: - # else, assume it is an open file object already - filename = '???' - self.initfp(f) - if filename[-5:] == '.aiff': - self._aifc = 0 + file_object = builtins.open(f, 'wb') + try: + self.initfp(file_object) + except: + file_object.close() + raise + + # treat .aiff file extensions as non-compressed audio + if f.endswith('.aiff'): + self._aifc = 0 else: - self._aifc = 1 + # assume it is an open file object already + self.initfp(f) def initfp(self, file): self._file = file diff --git a/Lib/argparse.py b/Lib/argparse.py index 209b4e9..b69c5ad 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -182,7 +182,7 @@ class HelpFormatter(object): self._root_section = self._Section(self, None) self._current_section = self._root_section - self._whitespace_matcher = _re.compile(r'\s+') + self._whitespace_matcher = _re.compile(r'\s+', _re.ASCII) self._long_break_matcher = _re.compile(r'\n\n\n+') # =============================== diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 28a45fc..e85634e 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -11,6 +11,7 @@ __all__ = ['AbstractEventLoopPolicy', import functools import inspect +import os import reprlib import socket import subprocess @@ -611,6 +612,9 @@ _lock = threading.Lock() # A TLS for the running event loop, used by _get_running_loop. class _RunningLoop(threading.local): _loop = None + _pid = None + + _running_loop = _RunningLoop() @@ -620,7 +624,9 @@ def _get_running_loop(): This is a low-level function intended to be used by event loops. This function is thread-specific. """ - return _running_loop._loop + running_loop = _running_loop._loop + if running_loop is not None and _running_loop._pid == os.getpid(): + return running_loop def _set_running_loop(loop): @@ -629,6 +635,7 @@ def _set_running_loop(loop): This is a low-level function intended to be used by event loops. This function is thread-specific. """ + _running_loop._pid = os.getpid() _running_loop._loop = loop diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py index b2f5304..4c85466 100644 --- a/Lib/asyncio/subprocess.py +++ b/Lib/asyncio/subprocess.py @@ -24,6 +24,8 @@ class SubprocessStreamProtocol(streams.FlowControlMixin, self._limit = limit self.stdin = self.stdout = self.stderr = None self._transport = None + self._process_exited = False + self._pipe_fds = [] def __repr__(self): info = [self.__class__.__name__] @@ -43,12 +45,14 @@ class SubprocessStreamProtocol(streams.FlowControlMixin, self.stdout = streams.StreamReader(limit=self._limit, loop=self._loop) self.stdout.set_transport(stdout_transport) + self._pipe_fds.append(1) stderr_transport = transport.get_pipe_transport(2) if stderr_transport is not None: self.stderr = streams.StreamReader(limit=self._limit, loop=self._loop) self.stderr.set_transport(stderr_transport) + self._pipe_fds.append(2) stdin_transport = transport.get_pipe_transport(0) if stdin_transport is not None: @@ -86,9 +90,18 @@ class SubprocessStreamProtocol(streams.FlowControlMixin, else: reader.set_exception(exc) + if fd in self._pipe_fds: + self._pipe_fds.remove(fd) + self._maybe_close_transport() + def process_exited(self): - self._transport.close() - self._transport = None + self._process_exited = True + self._maybe_close_transport() + + def _maybe_close_transport(self): + if len(self._pipe_fds) == 0 and self._process_exited: + self._transport.close() + self._transport = None class Process: diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 5a43ef2..4d79367 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -487,7 +487,8 @@ def async_(coro_or_future, *, loop=None): """ warnings.warn("asyncio.async() function is deprecated, use ensure_future()", - DeprecationWarning) + DeprecationWarning, + stacklevel=2) return ensure_future(coro_or_future, loop=loop) diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py index 99e3839..b12d5db 100644 --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -449,12 +449,15 @@ class TestCase(unittest.TestCase): self.set_event_loop(loop) return loop + def unpatch_get_running_loop(self): + events._get_running_loop = self._get_running_loop + def setUp(self): self._get_running_loop = events._get_running_loop events._get_running_loop = lambda: None def tearDown(self): - events._get_running_loop = self._get_running_loop + self.unpatch_get_running_loop() events.set_event_loop(None) diff --git a/Lib/base64.py b/Lib/base64.py index 58f6ad6..eb8f258 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -541,7 +541,8 @@ def encodebytes(s): def encodestring(s): """Legacy alias of encodebytes().""" import warnings - warnings.warn("encodestring() is a deprecated alias, use encodebytes()", + warnings.warn("encodestring() is a deprecated alias since 3.1, " + "use encodebytes()", DeprecationWarning, 2) return encodebytes(s) @@ -554,7 +555,8 @@ def decodebytes(s): def decodestring(s): """Legacy alias of decodebytes().""" import warnings - warnings.warn("decodestring() is a deprecated alias, use decodebytes()", + warnings.warn("decodestring() is a deprecated alias since Python 3.1, " + "use decodebytes()", DeprecationWarning, 2) return decodebytes(s) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index bcc4291..85b4c3c 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -189,6 +189,7 @@ class OrderedDict(dict): link = self.__map[key] link_prev = link.prev link_next = link.next + soft_link = link_next.prev link_prev.next = link_next link_next.prev = link_prev root = self.__root @@ -196,12 +197,14 @@ class OrderedDict(dict): last = root.prev link.prev = last link.next = root - last.next = root.prev = link + root.prev = soft_link + last.next = link else: first = root.next link.prev = root link.next = first - root.next = first.prev = link + first.prev = soft_link + root.next = link def __sizeof__(self): sizeof = _sys.getsizeof diff --git a/Lib/configparser.py b/Lib/configparser.py index af5aca1..230ab2b 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -143,6 +143,7 @@ from collections import OrderedDict as _default_dict, ChainMap as _ChainMap import functools import io import itertools +import os import re import sys import warnings @@ -687,7 +688,7 @@ class RawConfigParser(MutableMapping): Return list of successfully read files. """ - if isinstance(filenames, str): + if isinstance(filenames, (str, os.PathLike)): filenames = [filenames] read_ok = [] for filename in filenames: @@ -696,6 +697,8 @@ class RawConfigParser(MutableMapping): self._read(fp, filename) except OSError: continue + if isinstance(filename, os.PathLike): + filename = os.fspath(filename) read_ok.append(filename) return read_ok diff --git a/Lib/contextlib.py b/Lib/contextlib.py index 7d94a57..8421968 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -105,7 +105,7 @@ class _GeneratorContextManager(ContextDecorator, AbstractContextManager): # raised inside the "with" statement from being suppressed. return exc is not value except RuntimeError as exc: - # Don't re-raise the passed in exception. (issue27112) + # Don't re-raise the passed in exception. (issue27122) if exc is value: return False # Likewise, avoid suppressing if a StopIteration exception diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 1c9d3a5..f870968 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -324,6 +324,10 @@ class CDLL(object): """ _func_flags_ = _FUNCFLAG_CDECL _func_restype_ = c_int + # default values for repr + _name = '' + _handle = 0 + _FuncPtr = None def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py index 8eac58f..f622093 100644 --- a/Lib/ctypes/test/test_callbacks.py +++ b/Lib/ctypes/test/test_callbacks.py @@ -244,6 +244,7 @@ class SampleCallbacksTestCase(unittest.TestCase): def test_callback_large_struct(self): class Check: pass + # This should mirror the structure in Modules/_ctypes/_ctypes_test.c class X(Structure): _fields_ = [ ('first', c_ulong), @@ -255,6 +256,11 @@ class SampleCallbacksTestCase(unittest.TestCase): check.first = s.first check.second = s.second check.third = s.third + # See issue #29565. + # The structure should be passed by value, so + # any changes to it should not be reflected in + # the value passed + s.first = s.second = s.third = 0x0badf00d check = Check() s = X() @@ -275,6 +281,11 @@ class SampleCallbacksTestCase(unittest.TestCase): self.assertEqual(check.first, 0xdeadbeef) self.assertEqual(check.second, 0xcafebabe) self.assertEqual(check.third, 0x0bad1dea) + # See issue #29565. + # Ensure that the original struct is unchanged. + self.assertEqual(s.first, check.first) + self.assertEqual(s.second, check.second) + self.assertEqual(s.third, check.third) ################################################################ diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index 8f6fe5f..3eded77 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -3,6 +3,7 @@ from ctypes import * from ctypes.test import need_symbol from struct import calcsize import _testcapi +import _ctypes_test class SubclassesTest(unittest.TestCase): def test_subclass(self): @@ -391,6 +392,28 @@ class StructureTestCase(unittest.TestCase): (1, 0, 0, 0, 0, 0)) self.assertRaises(TypeError, lambda: Z(1, 2, 3, 4, 5, 6, 7)) + def test_pass_by_value(self): + # This should mirror the structure in Modules/_ctypes/_ctypes_test.c + class X(Structure): + _fields_ = [ + ('first', c_ulong), + ('second', c_ulong), + ('third', c_ulong), + ] + + s = X() + s.first = 0xdeadbeef + s.second = 0xcafebabe + s.third = 0x0bad1dea + dll = CDLL(_ctypes_test.__file__) + func = dll._testfunc_large_struct_update_value + func.argtypes = (X,) + func.restype = None + func(s) + self.assertEqual(s.first, 0xdeadbeef) + self.assertEqual(s.second, 0xcafebabe) + self.assertEqual(s.third, 0x0bad1dea) + class PointerMemberTestCase(unittest.TestCase): def test(self): diff --git a/Lib/curses/ascii.py b/Lib/curses/ascii.py index 6a466e0..5b243be 100644 --- a/Lib/curses/ascii.py +++ b/Lib/curses/ascii.py @@ -53,19 +53,19 @@ def _ctoi(c): def isalnum(c): return isalpha(c) or isdigit(c) def isalpha(c): return isupper(c) or islower(c) -def isascii(c): return _ctoi(c) <= 127 # ? +def isascii(c): return 0 <= _ctoi(c) <= 127 # ? def isblank(c): return _ctoi(c) in (9, 32) -def iscntrl(c): return _ctoi(c) <= 31 or _ctoi(c) == 127 -def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57 -def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126 -def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122 -def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126 +def iscntrl(c): return 0 <= _ctoi(c) <= 31 or _ctoi(c) == 127 +def isdigit(c): return 48 <= _ctoi(c) <= 57 +def isgraph(c): return 33 <= _ctoi(c) <= 126 +def islower(c): return 97 <= _ctoi(c) <= 122 +def isprint(c): return 32 <= _ctoi(c) <= 126 def ispunct(c): return isgraph(c) and not isalnum(c) def isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32) -def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90 +def isupper(c): return 65 <= _ctoi(c) <= 90 def isxdigit(c): return isdigit(c) or \ - (_ctoi(c) >= 65 and _ctoi(c) <= 70) or (_ctoi(c) >= 97 and _ctoi(c) <= 102) -def isctrl(c): return _ctoi(c) < 32 + (65 <= _ctoi(c) <= 70) or (97 <= _ctoi(c) <= 102) +def isctrl(c): return 0 <= _ctoi(c) < 32 def ismeta(c): return _ctoi(c) > 127 def ascii(c): diff --git a/Lib/curses/textpad.py b/Lib/curses/textpad.py index 2b4b4cb..2079953 100644 --- a/Lib/curses/textpad.py +++ b/Lib/curses/textpad.py @@ -43,16 +43,20 @@ class Textbox: def __init__(self, win, insert_mode=False): self.win = win self.insert_mode = insert_mode - (self.maxy, self.maxx) = win.getmaxyx() - self.maxy = self.maxy - 1 - self.maxx = self.maxx - 1 + self._update_max_yx() self.stripspaces = 1 self.lastcmd = None win.keypad(1) + def _update_max_yx(self): + maxy, maxx = self.win.getmaxyx() + self.maxy = maxy - 1 + self.maxx = maxx - 1 + def _end_of_line(self, y): """Go to the location of the first blank on the given line, returning the index of the last non-blank character.""" + self._update_max_yx() last = self.maxx while True: if curses.ascii.ascii(self.win.inch(y, last)) != curses.ascii.SP: @@ -64,8 +68,10 @@ class Textbox: return last def _insert_printable_char(self, ch): + self._update_max_yx() (y, x) = self.win.getyx() - if y < self.maxy or x < self.maxx: + backyx = None + while y < self.maxy or x < self.maxx: if self.insert_mode: oldch = self.win.inch() # The try-catch ignores the error we trigger from some curses @@ -75,14 +81,20 @@ class Textbox: self.win.addch(ch) except curses.error: pass - if self.insert_mode: - (backy, backx) = self.win.getyx() - if curses.ascii.isprint(oldch): - self._insert_printable_char(oldch) - self.win.move(backy, backx) + if not self.insert_mode or not curses.ascii.isprint(oldch): + break + ch = oldch + (y, x) = self.win.getyx() + # Remember where to put the cursor back since we are in insert_mode + if backyx is None: + backyx = y, x + + if backyx is not None: + self.win.move(*backyx) def do_command(self, ch): "Process a single editing command." + self._update_max_yx() (y, x) = self.win.getyx() self.lastcmd = ch if curses.ascii.isprint(ch): @@ -148,6 +160,7 @@ class Textbox: def gather(self): "Collect and return the contents of the window." result = "" + self._update_max_yx() for y in range(self.maxy+1): self.win.move(y, 0) stop = self._end_of_line(y) diff --git a/Lib/datetime.py b/Lib/datetime.py index 7540109..5d5579c 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -1053,7 +1053,7 @@ class time: hour, minute (required) second, microsecond (default to zero) tzinfo (default to None) - fold (keyword only, default to True) + fold (keyword only, default to zero) """ if isinstance(hour, bytes) and len(hour) == 6 and hour[0]&0x7F < 24: # Pickle support diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py index e7c6440..2296dbf 100644 --- a/Lib/dbm/dumb.py +++ b/Lib/dbm/dumb.py @@ -97,8 +97,9 @@ class _Database(collections.MutableMapping): try: f = _io.open(self._dirfile, 'r', encoding="Latin-1") except OSError: - pass + self._modified = not self._readonly else: + self._modified = False with f: for line in f: line = line.rstrip() @@ -113,7 +114,7 @@ class _Database(collections.MutableMapping): # CAUTION: It's vital that _commit() succeed, and _commit() can # be called from __del__(). Therefore we must never reference a # global in this routine. - if self._index is None: + if self._index is None or not self._modified: return # nothing to do try: @@ -197,6 +198,7 @@ class _Database(collections.MutableMapping): elif not isinstance(val, (bytes, bytearray)): raise TypeError("values must be bytes or strings") self._verify_open() + self._modified = True if key not in self._index: self._addkey(key, self._addval(val)) else: @@ -229,6 +231,7 @@ class _Database(collections.MutableMapping): if isinstance(key, str): key = key.encode('utf-8') self._verify_open() + self._modified = True # The blocks used by the associated value are lost. del self._index[key] # XXX It's unclear why we do a _commit() here (the code always diff --git a/Lib/distutils/command/wininst-14.0-amd64.exe b/Lib/distutils/command/wininst-14.0-amd64.exe index 22299543a97ffc1525a3b1c778cb158d6c6430ad..253c2e2eccefa79393827f44f85680536906574a 100644 GIT binary patch delta 117970 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

)t?oHVn5Sq%T?GqR|24h(;z`zbGppoRWXDn~U12 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 Q;XT#&G~W}hI31h(Fa4nPXaE2J delta 119901 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ൣ9WtThL^xVv=M5*CyxlKISW*>{c?($n7~W?&*%Tas z6R(A7vgPl8QIrhn+r7ktB8=qJU*l~Bnn(tSOIr~{B)_3BPjbaVQvlW*FsaU)uEo|s z{-zrIzcGfWy(ty#V>I)KRIE zjw!-aYEC*M9pQ7a=}t9=f-ofIk+(_mwDoslIobeRb+5T{HRdne&1^-u@i`l8iE&lR z-TCr&ghuJo4id@Pz(~B$bEgA?@CI@Pn4E8bUlKe7w+SGrZVwHITT#qu7=vy!29|ho zDS6;wI=1wwB+%Z}a(vm!hJ}s8MWrnNkn<0CCH9VqB>`f8Z$}q^Z2|U}t~_LbQRD68 z?PUL0VtOAu3%?VqzsUev@@Z%dFLj~Ad>nrO1?d3!C|sskp<}1B;cffs-kZW+Xq)0% zLoHw-PUR9v!_43H7VR^z>M24t3jO-RG%Wq9e6FE$e6RU1K=J1@!3%b<(kXekpBgr$ z!$E_Yu)K=+7vF4fq@XYl+UZ$;LGE?n+zfWti027|=|#FbgHH zU_h)QL>;na)`}u z0bys5aAt=9NmP3b)#T5v)$c@Kf}aDTklqvQ-}YT}6N^|EYin`tr!<7;DEP#Et+~`U z?EfnfQ2H1}!2lB1BW@m~T11g_iqMYNRQ-|GpR!ff*yc5#5V0ygq5t6Na!;RE*06GG zyEfgoabN$A<01Iso!21aOvercI*}tI4jqJrA5r~NM8adZ`Wo%JHf?8vI&_<` z_tE<4t?njFgHfFLizFPuuT&QQaKpRt4;yc}e{P4hodG6JyC8;~M`k8=Bza4XJZ57q zXp1E&FL}w>-c1pc^a|&_>_CSelPti=^e)tYL$07LJ_>F`e6>gT2TMlAv`{hrocu)x znt`?C_T`f*keE`*xF7qFhQ*w}62MGaHiTEaVF-_ukk(@wm_A|;b!_j-{(;7r+w<{R zAW6Nfl<%&`bWsDssYzYKoVP{n6UC59`M}H69Erij&=*giao9;HLQ@P0cT)V=BL4$v z@nu(!2IV5eN&>TlR$YwqvdN^48>~~2XTNvs7&n4O3|u8(zlza;wSf0)L1~cP1lr2x ze9CN{Vs#bc*_2MrlYRiAk0PYh;RT8?8F?N)Lubf}zN`{Lf2GPjPt2S-^R^Fbt@slA zq|@+Dr{AaXtVTx^VHMKq(2`wzhf3T>luU1*^jBG%xb`!j1f&?t6?GdvFO@6hw%mcO zHO^bbbSQvWge6TX%c7+K7y}4Hg5QU96i-8C`%r=y<#y~-NJ|w-3F?zbzGB;yHYviNK%R-|*&6flCe#LIU?(skV`#)4q!ghHC;x4!2^cQ#b~DP* z*DMy@rCYa4V*?W>&6-M*N#Jhl+fZ6+u@t|1NdagH{_I2cOqbya34n1EPDI|AKn+cV z|LoqMJ*7N#%$`)RB&T_T5*#p=UGLIO7xD^g8Q;d$i`NA^<9VV|_Q6J?&(FNf``pL_ z*{KRx`2h(7o3CP-2U$?(9}Y6S_$mzVKS7|Z0wV~hAp=HAcM3p%CtKcg;YrXKXDdbU z0b<*0B@d9>`O4x2+;ooyTvdSt@J&4`WEbPR>RRToMqS%9`=F54niw2ap;jV%r91Dj zl&%9C7kgo!99^NwJG`u*YmauRKoq@M7{z%|vEU|pvDoFx^*wH*m+U3a zS3caD>ANMgw5Y&@Ow>m+#knZs%WIGK*{E(Yrbw>6+=V#tE^~J4*5UBGs!jQZI}(UM zE5a)P1-2(y+0>6WSw**$b|q6F*osp0J693f11Ir2sSaw`D6j}y-en!Tx6wU2g{60I z=NbcSe@}IB#i*Rd@gy|yTl^@(?yc~0#zLI8&xtJ$iMP*-AxA`y$wCdd)x#{wuzICY z@;qH{_l2M}r;41)@QS9&!)It1*9|<9*=dea+A~_*{pkMt9=*+a_1LlGd zWHUX6eoRs{;cd;sWhvcp((VWqzFkV2QfEe;j(OPs&KDe#)UaTB~tp}rxx zq9xAXeRTY*2vblI+m{DgJ%ah5a&FtR4s2&lyDoj3CE=V2E&Yo^v~!~nD=+pu@mM?x zjX;7bCQd{f#=^!r1mE*raCft${hV!H@pwH|kh1Net#3dcAE87kAvaprLXUp&MfeG7 zkRmg-J)V20dAxN~FW!0;#Gkr?583#9tgzR=Qxqt_vmHV{;bVY;!J-1hd|Gfc)4msI zk^TqMFatZ=%?IIKw<7U$D|?=F#`FftACQuq0WCz_BJt#qm5tl6lwJdLqn~Hb_3A^) zxb|JPtC#i3CyAUooHUk=6`>FiyLY6{kMvTcZ9IleriF|i_uc;UPSEc0IR$&sad*!gZ>kLjS1n@Sgm9Pak>cHE*VmK6+^W@8gqA9|8;6QO9 z;!8wWs>Ciy5&i-cqrbF(7SL|Oi$*BV(JW}CSEwd5tQ`yF)#uax;4qQ|d4g*Q zUlEq0gzW!RgfW3``x?w@()v5B+0IsA>eFkcE7S!XeXc%>uqvwyOxzCz>t`bs~1 z%WC^t1{MN1-nf+p{yU-T6*-vHUzsh${ zDT<96_ww0=dAXf=`t@`T$^fDozMz$aShvV+5#3Q!D@uZ?Wk{)dxDQ0@^)Nx+kF5)O zC-4?&dpZqG0iY)UKLhMYvqVxCF7hB6W+9)qe;nFl{gX_McP@d*xm&zVWTTTZ#%;#5 z#-UZ<7z}>)1_1oc`Jr7V9l&A&tEY8KP#`z`_5RIfz}*^;i$rLIyv8Y$C&528D7mye zyLu9Fui*uZ3naA9rH)quLj4=4;GSoQc1=F5aJu!J52|bkwXy2qwQfgP?vil+=L<7aVEOtC!ak{|8f@FP(wiZ&WeK8T6aWewZBI{SRKJ z)yg*kXYcaQY)Nu^-2^+^l-y%zHgyE23#gKt@)u6ukogQ5avwzKjbR)b0wa&%ho)yL zcfoKzf<_bRPDI>t)^wn?!Dy7@?!%bnZ1BKVnM*+^@uY2~KD!t~n<(lJ)Qmn%kk+w}kG5^s6McBEHZ5!Ce`pYGPX~aj>TqDs1aD$IU~1@~b8wo_#;I&A z+nyqr<55ccq^zlA8D_B4DLpN}4?*|ICfUP9sg;11$rxF2mB>3}y1eFb)?tvP#lpu) zBos%Og<-|7RRazcVH#so1_|AIU&jz*U_=o`33Gs=2$icLJu+}XY_w2|u`;r^2Q|}e zSk1l|)J3;oHM=sXi;xCfkhiazN=oCg8x`U0)vWE{-mVa$B4vdWzh~_v?hV!iQjNU* z7W}}Sp$mL*m?ixoB3v0De9RkM*};A$4o5`7rX`Ra4dWwJ<}sAaAq6OLTqFchsS)$8 zZ=+@k91fB1X#wc_`4g`%()rzIUWWCP*9NgYjyNXr{XE7~| zux&Sy4ea7x;*^N{ztcF^)Koc|tW=xal3L&7c0eGjICKj`Zkjt6t#HpDEniYwu7rb0 zni;(YT2g0m^-!bJefM(5leaw?MfF?1iyV$+f+{_X5?UCj9b#xMJC@q2XOo41^5sB( zj}^X)mJAoLh0n8=wiwq`5LSfHSJBpN+!5;|-9)(lYLakbOrM}Q(cpYr=`YAy17%n-edMmn}3cgQZKS!QJ zpxt8B%ao2#yA+?|)m%+b52#y#ilG`u`&W1kr&?p?!h1Dd zxL1Q8QB%J@QL$-T3i^xbj5|PoI$`%y8>r_em(Z0X2&LsF@6!SES1w2(OOS3}3Rf*%ND>Oxc{O7^@L1qG7N#w8s zqN`&1o(1?QpyXn%y{6IZo5jZ+ZYq>J@uXb$C@V|rtvmSyt4nJ$y8*fdY;v!V=N@h!*jFQa};;*v)v zzThQl56R*dr{EFn;W{d$IxiEtWXc=HBGOyC&Li51eq*=t7DTCbW;3n3Bsz4a6wn7c zvk4X65B6nFeVy^NJOt`^`JnL7-b!FoUs~*d6cKApr3(w$bR&Hn7NUeH?345+T8vM6 zw6z>J*D)Dyl7hJrl*9cN4J4snLN6WwuH{XHIB>=P8}T|d0~4!8xl9#kq8lC1 zdv_V>Jsl9^LRs6~!5SLYGf+xZe38K6qQIuVj;m^wyy{c*KmPZXjS3sLMw4`)88F$I zkO?&Rb}}_V!Dz^4K~bmChNkSXj9Ax_C($#$Qa#--Xacek1*e-T4_n2y6Ro`yZzU?| zdjjs$r+Mczbl(Yaz=0O>7UFpD4&PA>H?GtUFcbn{E~o)yr48BVdG-X)>IN9*@@yHh z8Il-|`c433*H1rC=!~?DymDa%fWFN@+KUOJkzd4VBTbGZ+^QiII(C`>6r4;qI*Sv; zmw}muJv2F;#hP%`FfM^0NDU8@8iM`QOz(6$My0b<9GXBlsY$(~owqZm{XW$EwJWo? zBFF3@&2Tgy>2>rTm7yG0j@Zm!H<5K5?EIB(t)&ogvwIZUjI`r9c{*x3FbKo$G zUVXrXOj628QW+k7lMMGk+?_|6E&1Zo_BQu{h8feo6-%##$WhlpB+w}r=QR#f*B_E8 z-F&bwgPvFWQjm&rii)*@o@7q@3yasgbp$zU+k>@)JHQ8@(ZNHpA_vDN;~8j(R~U^S zGT=L*=I**se&c#FESWv=mRMnkhKs7Rs3EEGk7518^`e)z!cWSSrdyNj-g&xFlKv02 zYJ}DG2lwhRaroX6l-q%_{AVfl%ZHgAebg zsC9z8nTfXv_wd8zo+|!u<)Dx5Q3bXr@TtN09W*U>t;cqpe4zAqDsAGbFLuVrhah?X z1YBu-5kf8b7w?2D%2X=+;sf2ZF3F%dRia*aR)@PmAANcGA=e>0^5Z%UwjysZ(A&E_>26T0BnI}HvNi4SIj zX37dQK=(}G(G|kV;s&*F6d*-dgsg3EDwl=fGC<@lW|OMSMTtD(7N*wcbeS8mH`wYn zuseKLuLxNv4;U6NnF%s2kFlz(4z4GXG<1uao704Ss{bGidx}C~Lo(@)`kwj?Rop30)Be`k zQGNz5gSnHsX_v>!3y`GP)Kvc4Ofsq!zJi-nOmAMnYx{gI{HCSs?UBvf$?BRaZ(oF3 zUg0vbXoQXtLeVlz%oKKEWJgzL^B20kHx)zyLn`-}H4t_3p=Uynv4@;UOFm(K;YCa- z-*WO0@NSjSJ4DMfHg{e4!eMq$Y=&2cLNb(cwTjJMqBwt134)MOB?;0`=Z59lZeJ<= z**vGrYzryFoo-vBQeU%PpuCqC=GAQ%V1-`LvNfZslCesd3({a2q*B}M%cwTHjB^)K zNdTe~1XPRe8#n}N3|#PI&Tq`#%RcY=Z*2YFq->>E!tISt*yv@lrB-9PdQ&+|s+KOK zN$0b0Bi4vBdEa_S+r0abxaZoHq8AsSXBoGDww3zB@#+OGj^Os;U6(lxFKS6;0E(sZ z;JngWh*(5%$f4O~B<{VuH}Tb6Fn05&WwzTjyi-(I%m*a?+z_w6r7gb9Kv`QzNm}yZ zXBvS5{bGm?rCd?8nr94#)|!8na=iu1JS zo$$BK{g=i3!VnC(P5MhLyMe)ihIJ)}&d4K(r>@|opt;InI3WvAl0fg5V8Uid!;(&2CD$Ze zIgZR!xG#%EkKRf(qgkhk9Y&So4McytTV>(S^jl@A=7QtUROv9yY`!X-s!=N2m)kO)AHvz`&mJr^TOulAf~Xf9EX6>rjMmFO2prWwnn^x9F`>??NI9dVM*)(qDt* zM5(crEt=R`Tglc;%9lEtVBz(0{iOz!FG2-g%0K(LE#g&K^oc2V<{HXZR)i0gcrl8Q~`8OeVyv}Gk9 zScrEc(S6???BQ>fSsV>)6`_sLn%@dzVR#9zH^7@U{3IcPwZpIvi40G=1z4?sg~77N z%cZ^$TiyY!mVGlhhc%mW#Q0n3zgWrLciGh`o0}E11J@oKUY>m}NrUSLUR+#yb84J+ zD65$IQRH5PP%CV+@Om#HjYH|y7ukx(yt=y4Eb4J<^vThon)n-z=6C@!DNQ<%5nqdq zmHg%CU85hjYjqtW*^W6a*sf_!n}@BydfE~PleXIjH8qGqz~MG@S;4-aHc97h#?f-7 z&(Z$PN~iy!4a2i7J3HeM-47#K!pwB7oh_c(TGugx4SFJm?U*@5dz3{y5s!DTQ=WKA z*EAf}+q0@CHtMFnz~;@GYif#PFMk6%z%^9mv1_x+bxoV_CJxSy)-B3oHM5hOy={Uo zDph1iCo%**JK6R*Em_Ao-Fo^EHP3*8S}MXw zy8Z!sFl9BKFn>=p^d&Y%wu&%SQt2eA50L=*ZTk)_@t z5uPw9eL<#I*nx**)7ox*V=c$>x1Gytv$qiNy0i-VeNsa&~UKorNfb(d*j zg*J2}Ht@becEQmxd^X||zKLL&OXw>d?`hV;7&g>7H1r4t(Km{{C`vzv=LX@6xg&pzIG74CRe zgu%>fdSFk~b`T^)M!=ay_r z7xL%x{5h9DC-Y}Ee-7c#-t=^J=*TnC{MnE{{~kpouJY$O{yfZ|U-IWC{JDugSM%pl z-f$FuM)PM2{*2|%*8FMV&vyK2<5Ah&UHG#re|G231pe&BpK8zg@^lh^4&cwm zFnmgfEf3LiEq_knkWBs@#GeWL*^WOW`7@M1>p1?;F8=d9e;()068@aPpYQSK>-<^B zpU?B>T>hNQpV|C5gg<-pXGi|5%_O$2@aJj%JjkDW`11q)+>kkekdE`rEdFfApH}|t z$e$vA4&cwO{Mnj6!})VHAF_Pj3Y)M=FmdWACJKbbizz^Arl8!h2h@@Mh!JvVW>k2Yc*gxpizoPGQ>G0 zv`M>*Qn5l$2hsPzB~#g5%m`1W-V#LCBGCAG5QvIx^RT7F77hEu{YjWe{1}TZc(JwX zN@w03BN$4MDtUkYLM!qM++(0)7?0r!ag0DwT%bSC@E#bB(2vJ35a<<#c6h2?h(${6 zLdQTV$Q5;=HDGWXa7+`4_r*=R`MJ!z!kUwEkB!s-8)JbfUqnxXVoeFK5ftk&AV91g zRW^!@#Ktl_RW_bA8d>3rKFuBh=j0xM?Ij7| z6r>s43f$D2CR5ZK^cDQbgRmINTD9hxst}64X2~YxWf2dof^a}g7YWHx0lH=?X+n?x z0EX5s`~v8sDc|9_AB#3We8iVQ_R<R8LCP#8R=bYG8?e?&!jHKzxi zi1Y2kEyy75ZuYOIwd)Ue19*N@^hjC-PEg;L3B7sW;RYUV*crinInu z1&5r&D-6w1Kq7!~-;N21{ydEzdHeU&TSvn^*eoJQsv?Y15t0a@IS?ug=P{%%QgXjB zb+?u`x$=k{4Oz-9(FDbi-ANipJ4{!3COi~KI7*c8PV5o+6#9h|1DiKnhgixf`FHp& zL43UBUn%!h@ex;QBzH$p7V(TrSl{J#5Ej1cBA>ZH_q$5cT+$JK3-QMpxIl0fk!R@~ zP>(eMD$ayRGGS=0Cn%)mD^7#_%_Yz}xkD?zjs~Q1e_LomGZoPY#O)|PnhV)!fa^wv zUI?MMJVoOJ=gRU~^bjE)8jo$`j)iCtXyxmkFZnzl9W^E|KL;5QtKC#qA>6@WGL17# zhRc^kfpQw5f3nL`RLDPngcW_#C^VKuy;P*##XfndUHk@22zVCU>YKJio?vWmH3|!B_ZcG z_W8@bTyFzA(_^o}pKK22zqP-aBTVZ6|IHkpRcnqgtl{Yh+&m(~g)dit`_xJ0dok)7 zxddYkiIZiH#z%+tWZ{IT$kKr=+n z_{}5i$ye-;H@`i^3VOK?;<+KlF%-W#KCIEWYY+04mFH#LgoC!Cw~es%3=>xf>kVAy zFe55XZpt@+XjYzg=<`oHn_&8Vgu%d%*Tf=LMY?{h#gZePN9-n1cm$a4%Y(&Jheh{Y zg+4!UM7{=l;y2SPDPB`Ql*^C9Iwl?}C=tzRc)y3fbwnRCf&kZn5<1K&b$F1HF+-~K zc|j=yFMN1SVJP*r03EF2@2%>W+>LlhE_cqyE&6D@MluwJMzTkX{DoE#IYc#j(#x&A z)wDOuqUK|VvZz=4N9?^peV|bC?P@G!J8!V5uf|VK(L)kShp&f_zkpV|A@8FtKp6&z z{89k`Q^`Sl0n6UC&Ffs(dr5hV{X`_q*#ZAm}G@GR({JP*S8ymBFuN&;2s$LOyfnP^UCWZThNE!F+q1ajJoJVT5CLxj z1gyss_t5dac{eV2=3dd_t4+A_vKA0nro<8q6O0LkrsY)j0()3DB$b_G{dC>_Wf89l z4KCo21g`t3$5@ZohBkOp%@sYymb}*6)qtePPY7`aeVvrgJwt{bB$iYda;}Hb`LV|Q z4kDfvh9St(l3~lMo#&V_Hx1#FyqmM<&B(ylo9vA$rBivorO%k>Oq0%~H9E|rDmF+t z@8&dHR$AWgHm75jE$_D(^Bl8njV?4gkFv7FL;Z;MAzTH*=cv*=S#@cW;UnB7k}5ru z{_y1d?HDb(O=tWF{oCA?`VO^&@p`1kuu@}WGuQO%nGH;P{z*qn-erxs)|_`oW1gy6 z+K5nr)eEJ3SL?~C0qLL8lFzYYYud&9qhOHI+T^k#HCW ztVMbmio-8gJG5e$iOLI7=-hk=BpylXq_hBRe+*0$C@#m=sM zr2SXXu&s{Pp!6A1a;N6p@HPot7sb`5jnV9(b2WGvGwD4|Yqq zKe`Qa$dDFUY|?TuBmNJc2YI|hiI4K69nohd*FEzb5=JBzF1Tgavoq_4nR)?&PoUt$ zEV2*lUk&lfo151ABhBUBY9>tn9SQ$+`6C3{174I`Zw}a^ zL-92we5Fw>vh3r2mAdu>z8i?u-Hpmv*CXWCASSxlNeiz^Q~}XID`ZW4 zEKW~Oi0_E{OR+nWeNMfA6$g(CRM%O%!t$3qVQOyEyNA5dNv)xEu_hY^MP&AYfA;~3&(J;cpG zO1{Zo&^;pi*p`h6ta@X*PX2?%y!r0KO?Kdmf%xl(zcBno;?Ih|-uTnwZy^4n@t2Li zRQ!eG&w{@M{Autv4u1&mqLWdh6lJKCpSNK<3x8_?-r*J2{Sa2Pe7ZhHx9kUU)pav| zU@7k|axI&Ic~9@QEIR?vt-F`w^ZCAP`aR#)3eWN?;@r7#}Eqh|1w| z5(6n}`5-FqA1KeDa?E5Z@1vIYrSh0Sxot*EAYd*NLN^tmJ0Z{(@@UbHHTZH?&3i3f zn=?sQ6saGEH_N=^%Rg%0BUk&J0|A^m#o_eN%aT6(qa+Fo>q%UXR=*2^cYPBeQm$0a zworf`bS>l&XESbj_*<2K0t5tqNQQI?A2oC~p`{{YMLwtR$NRbEJY%NTpob0Mr71%H zZp^cJR@A2>=yj~0Ye#{fo8g-&>R@=|I~KNOuq()26EV5MobN?nd~Q6lq%Usd;x*o7e>YTm6qWot`1J~#RN}4~9A7D(ssi#5j$Ai|a$_cx5jrtXYuEy#XEF z^?o_=H~Z361b>JqT_ov*6U~ejFYy*|0XtS5Ql5>tH>4f}|4>qN)2DCA#&7HA3I}UJ zZF}#};CSAzZGQ$wvYxqouyc>Od64M;(6(tR0%_a#_iG!cAJjIUX?%~ht({rR_v7@F z5J)T9v0vAUO@F^x#}gn96w>Oi!8)}Q$+a4TNj@cA_WL-VZG1nW*|aG%vNtima*%?7 z89jy7yf5fR_}T6E$9Mf>a_Pz?OcH)@2iw2W-wN zwTc%%vdr)1@=Ji&9#+cZer7*^Fu2(Wl&Q_9sK|pRvwI&brb2!o~b(BmCci+pKxYNJ}~P5j93{-8&rfs7Ki9AI_0;X%cN@M~N$@w2d4&Z|u_lRtb11GO8(6tzb?>m8&cvQhh zhH*oT$OSB26QXkm_omd3KsX|Znc1L&Z8N%b#*a6yDIsLVv0pywCY+fFBA{kCfCPQB z*ejGzWIaBPj=6(xa^Q@Ue+z-?sR^O16Px;Rj0<<25bhEzr!i^0DV?!TkjnTp}_?LTy^#1N0=&i6uL!SYXukdWncOL685-+ zl6=mI*c{*5Q!s=7WBG4cb=^bQ2XBqluZ`AgidGfs1-*+>H?JBjMJaC^VqJrgRf(x_ z0q*LZkW9%4T*@E71$fZ)p=;X_X!LJ#?vpF=HOhaR69L+Ts{srOPMH2ViR~7+P2|%^ zZUQ=zNd^%5ip$cYkw*!>o)UpiD{xY@R3Ln@qd9Bvb{kiC4EKll4hE6@;3uQqDJwxk z{kX|<`0OGCA(<8fB-P5V;$SWjBgi$}M6VxzN^(L(a8&VP2-!Q_BS(O2zyj!{PB{&VyV_-i^;V8*dF$)o@ zKYZBJM(?hbrLQp;+|w4c7HJJ5n%+|`C{`!u52 zUq3;)ejdafYX_J$b(z7sf7XWiKb@ny6~o4DPtm2%WkuTu=%i!p)b{+iKk04@MQ(AW zl{R&KPC$X&fp0qVuBT$hdFd!~?RYX_+W$a)x4Iq~-Sj>Vt-v>PCB8%U8vc2l#q3OS zC0{`_%wy<^9~f%>f$ubrsSmQEN9c$je-jk9LIN>})*NiOaT$XQ=hkD0AOMndYNMv{ zEniaw%F_xBb@-te0viA4u~1FnL(u3z`}~vIcr);ER=u;6F6D7{XJ=feT|nX(c#-Wq z-P*DfJE`Kdvyjvx5Cenq0^mGJ$RQytV5$tRUvN ztP+1t?p>>MEJftAYURb_01Y?JG|w-cX z&e5_U#SRo_W8hi{7n&7@9Yt0(uDVEqpc1c^uajAk3?|BB){PRSWz}?L9ebWIzU?_8 zkN=KPux#NiI0NwLTLN`ZQhb6g%wzZthd-kGTAkbrXf74cWB8h&kmYzpv5G0}&8mjO zB|o1kzp)T6D3&5isLpdM zH9(LIQ+aj7TFCw{hEh*e!xKhUusZ?={g3WW)-Gp7c&^-aYWFy8`&JP!B|S+=y{6~B zL(t2c9WGDrqmFkI0H;67M(!Q171_GIvCaR2^T#o+_P(bP9Up~8#4>qrX7k=~3;cGK z+5#0fT7I-Q8&TX&Tg2uS4{v69oVtk~ACV*Aci^md!yaw1C-xMWcq!t>ZYAx zMf=)^UpW`1xm~>tpPPeWG1ZP@hxc`E@fCpJ!Xj_$rE(D?O1Keh>M)*}z8vkkLa)H3 zYVv+W1VAx&Ua$xD77-fJ+3o*k9kf zg#8a;H?f(+^;RnKy$oQQRA<{uSMlKG;<||~@0unTTAWWY4m&!;eyevh7!N&JDQJA7ZI00|+AZaeX+GOE)$zVK7iwy2^ose&zxLw`8@>VJT z7I=a=e>dbHTTo-C1?svLi=Mn17iRdmK-LPicD#UKSwV=Y z@?`FK8hV`JGv_Q>hOxOxHb;LxSpHG+Z1fQ)bYh4(e;$HAxr>cjFkyaqIx^-jQjJgx zq#B(gjqqXHPXFZsme`XyWF`$~zlFJ*iN5(8@2Zx7 zTj^1uk?gx^uszNyv)%qI-Nk+ZiUW{ihIFulhN~TXaA)_Os$$6>S)d0L(BTr@sU-$) z%dZEals((P-;5|&rGqTBB+@nK{=#cPLOC3|6yJ=ZIq%n-}# z+vdE&htxe|g+~4hSFv)JRfRZOK>L!k%bS_Mz&#RM-c?e!v_`cg7Rls+Bdm_=HmxJ6 z)Th6F0@KXVoyI}l(~J!+jf$Cy4@w4`!8G#Y7?Tvk(~Qk4ZR1M(E~9^})sZdspJ+{W z47zOyqe}tMPiHT#3M=HD{2QORaE)5(+=PVXTHN>xCH7ejh^hDF!LO+sKrKV26`7nnk zKpnYu)teGrly#}s7yTHm2NVo8M0l4j{ZRd}^zlk>4nGRGPadamz3)EV>k4HfG5viH zoP((i5e5q0y;lI>PLA(Fg`+{Zis$c2+B&J89n4U;4ql-{ke$lwXqPV)T<>$PsiSKT zlHpmEJgCnD_`XqVgRCDrCgExp^==4_-gd?1HZnITJ^i>>b*O(^&Xm>?YC86dy~sph7+ zs8nu7*2)nnpXsNr`5Y+=NdAs;8DQK@W4^HU`&-5}tFLAZR691}zG@n^+TIat)&BOY z4;XYqTOrlKwV^6ZQ!49t6#?Iw#((QWO82|X?9y9(E4b?6H8pP4W`kd@Rn(jLSh%qS zFC_zo|Dh$YK+eK&H6?+k(z?IoA;j{mwD1C@aR6ljI(>1kW-5nvaX!Yu$)(P5e7dZV zdtg=PJg6hNBp}RGR(&Aabq#O#1SBoEN6>_-;!Z<6y64-5qePPJ-&hNiOPo0YD#DAT zI{`!;5cxPh7Z57gTn(Z-ml4C2^zx8o7=N7H+EjDFSWu+(&0`n_kT2bZJe-U)>8dU7 zCt8KUeBR&WX29Q2-I9IWD}l#RaFhP)3!H(MqW3nl{aC#VlC`hk5SH{>tmux#iHD?v zxD=1K^^!}0d;3Dml7dpiPQAkS!?E$rB&0DxB-dHh2YCSRBH?u)yskk!ppk!4k4Eo% z{R%Wy&omf1zd&OW9vG9wK+bQ8C6=g60hKfDPuZjjcpBvKfXq4K${E!WA4KEe0Cf&_ z^Z@mLGKf0n$7hJ#Fk5M)D*+3?InH5Cpb4igl|}OIHlP=tVD1c^axdG5R-eLJAsKGN z<0_RKsLS)m5F2>-0j>rtAwT5K`-|L6RhFtt)(efM@Ghaz1PT|ajRcK0%Puw8KZ1|J zdEgDA#||SXp+!dv>S?;yt-)UYeFYEa0F1q%9s%UMtySa}s!?Gs_<5vB!q zL{4%nJ3jpmYB6~Il6#`W-TWYTT~zKOdu)OCa(_Q>(ZZH@B)G7l&cI-uYgg6ru}*uS z4!qd#h24M{8ASXvfEXPgM8r(%N1r{dMHdi9XL}B}aY=@&hiT{_3U>|ur!C2FhUejF z1@Z@ZKBPYX1<#x7^ILenX?^~6o`*#W)PE6qa^!dx^cV4Rs0slh0GJ6t2NGquWSDT6 z%{tQep?S1NpFz9zso2-V0Rb=EX&r5`fMVs0mK$2p1C;jSpKZpMf-2=lphAADiV!aQ z+N%f=D`B67YZ=UcBysechp49!^_;!T^RUt?r>5n|CziM`PtCnEm98cn1#?ew9GK)l zZzdq$L1W>}jy%K`98K2!S;;;=+O9!=T4yE0;YxPyXl&cpDrps zr>P~cZ~_fgtwT1j`GJcdpx zsl}XB-vFr~CFuz45#O?;s@Qi9QiSFTNd^Bu30@)P(IISa5Ex>e{%#hFSb*UmkZ_nJ z(trMTGc74e{kXsU3j6hVRF}Dz@lpOq;FD*S1omD}1?3bzus5VnAKMWY03W9By!;r~cwnw{sZD#*Ljv2Ry8Cg|T^DZknE&SIH_t83x z1Auy3&RAPW6>OtS%T*CjX-+;zS1qDoyKr|8Yb z`S%ey9##Cftb^4={=FwnGKiCCO(rwZ4vP9zD)oy%TYc>SGuH<-EOI+O0zw$BeW@q~ zKDO~hk0#aSVVafNLVHp^_I4N9g%d4ZTLC&~PXHSuT{F!2?_!m6*9|ql^cYXrmt#(+ zFCXBp%UIskT{mKRYj<51-s?pnSZK-VLt4XWa^Ma_*dzkD5QqPq^0{47sQF&A7$!u&;yDkvSel*-+IjWoZqACd>N z>VHE5=3LLY>xM0x0}USTuCqGYx=X%<88WZ<4R~mC722fXm$zbu`G_cTwekUet3kNn zqGFs9P|UN}4_v=}rPLASkSb4)X+;?s22j{S6gF`R!Vv1pHWG`4#DcNQGQX0mHaUpO zUP9a5DB(sT775?8FmOoMVcdLkkmhn=%TIOG>C4!bQ(gPgB|u*T73(*``bTB*45e?X z>0(O%M@_#;>GRBZy4yqXXG1j&Cduk|aQMutm3MbSkYQ3C4pqIv?*q9MYUSftRBU?4l z`WJ=*SuLoM6TjzEgr6%eMjP@DSxjhA0NiUl&a)NqIIU~t z&r}}3TF@W=6{<_$xkRuFH_z}TZ1(%N-3PAthUW7fEGFuwI?P{3tHDI2#O=4i#LonR z`>$~GiXD8+X&UwbZOJtI8#d`ovTJc)hz4K55nPn$jl?`k#3PYI30#^N22ui{Pa&BS z;YhTj1cK8-1QI;5aK9OO5Bg~iSC^l#V0_Dcp`QO#T0L-!U6l5-Q5`~AtFzs8lfGtI zXIp8_Y|hypO>z;u;Qj3Q`4Z%P3IBTvS3NWr*iwRmrI;FFX_A zrAkicyez9ScV347b?2!n|8$j?WRMBU5q0ySqg0F-Q*d<)=v3~;Rm5p_T5&C1$x0*=HRl zj5*GE!`#_fMe^>hiWhaVZpdHqLi_(9F!K_deW7Qkv(Qc6jn~ic$@~9s_T2$d9Pi)k z>@Gz)4%DMcQNdoYfT*CLpofCJcVlnSC|IMQKol-$^whDJsIf$2iF$TXW7k+?k7D1G zsAv+!dhh4iJ%r?&-#_mkcRMprnP>Vl&ong(dt-m07(fa+AMZ6EzG;ZL3^lf}rmg@w zH9WgeWFmf{T%|f~7b6d=^zyR3q=HmVBCW%wn9W|d>X+(*uq@~FQ&=HZmC+V^&3$iq z_HTmz0kr2$atsi(%4<526p@ze8tIzcpK4yl6Sb=Zr_QP&M$3;PVT;FJN29BzMqCN# zsZ*|*tKSN&68-uFOQNYsN9^rXp|yVdkCgxPySd!$(t~OgB7L~>A4rpbFG_E0#7K2X z&cHx|GD_Ame@8K)fO42NP8uFyPh=6woIB>lw?nILxvXBZ1Cd^QPSOk1NHj>5m1Z%1 zq4@o7{_A%2F5Oi0t9hjp8`Mgwt{NL{O034Cke+y{Ed<3xJkBfQ!O&&OHAr$ON!ITj zc})lQ=dI<)GUFa+vwEAy|6VQe?q^Y`jHzsGI7Ot2f(|~>rio%xn%To>N1*8p>Cs9) z`pvwE!amxj%)4xU@w;c4uRjZx_lpWthFv!M+zG{FV7F;ML|aS?60=+3I1o(04(H5Y z+-c!b@{(Hl3U-;d->FgM)GoBd28kDv$>8>(4vh?F6eCdbzC^$^^a_wHR|&slcE0N$ z)99?~&qwDzfe4|%D%Z%8Yu63)rWJ~qui!BadsV(rn2HfM&4cb%WD&c}v+jB|2m}Y^ zG3uUvZ;euL>*z2FrPf-8lnax5f2Whf_9j`*4NvPc^3WG*75nT?^PRgs#%%!R;ktFQ z`>chVRybegtw&!1fiEPxY!{UFwa~C=Iti5NK*2VO^O%9=xv3^v=;DH6ZeVVb8yQjq z(AN%!^yw?9m!Jd(2EdUvB^P5Gnb%XJs_Znc%=He@0~2@s-ca-K!44dsfMQR5#|4^C zwNhy>n19dpDLIvP>Jh6NH_gJmGHl;%CN-j6Y<6cM*&|Urf};;VV0$1|aeuV;Y`Gz7Uh;09p|JxgA6ek0u-9(9ML<)5HcOFkkV55P20;;jGD67qril$@x)V?wjA|8}Szg+->w1K%0MIlj;SuW=D z58diarrM{?4s(^q=p%_GnuZfpAsdPnFXI^2ZKVci5Wq~Sb=ItZR7ogruK&oNb=+$1 z{3vQr4eYN3IuvVikN_pgK?1z1VHe&((g?s%0e#KkkG)urE#@|lgIU-XbMoUB?Br?l!N-2={7>dv zk87t4fGVqLx5^aIP^z>Fp*EphWexQi_Q36pDGzg%3kXAJ(C;U;t*IHCOB#b~yokF< z<#>eW1#R!GA`>%ZMIjTDTpd6aKrPNS-k?%=6NM{1-cH!QSIjG)1hSYQ^Wi5A6Oy6n zCJ13aYz9gUE__L@V>GeUh>Fxb%1R)zjUHIneFL}(sHy^9d>AL=#%`KFK z5^)Gn*MUOK%an#J^N9I|Qp?NvVo^GwjA#k{`GPsn+O|@IO?1fYeuPhQ1zZgY8NC#C zQeA&XB`eg(BQKa2SnIJnKbp^4ec6#8&5E^aO1(;Iv3e)5%09d(CuG#%N{T z>_@6LiC)NN+7J?VEy6n~MyZX3J$10dX7cOGpT{W6$%s)zUY8mpXix`KzC`P!_#?FL zt-P{OsE()nSF9h=&WX&fQtOUw)Jo(U`ffF!b|4^2pt&}gd?R7cUx|LtB=1Hz2Cc*# zTDP9&r=B#>fO?x7-^w>=AD z85_(oe}u4M=gdR?h-rTLsD`L!ur?-oDW%S-Spe3FUfWfZjhE8c9;TLnIvnZ#TyL)_ zcg!#T2uT?Lqdq8{l-1DS)U_YS9$QJ_r2}^7tPS9H71_yAy?7Q%1vM()C6J zro+faEc$wr%^M32v@!>THY!3C5O7=Bn~Txuzxt81Nu`zT*h{C{Re)6$Sa}tc73QCw zRjB;uI;|ezejqisfxC(9v1Ee*ZZ4WPa2HiDZ+RAE_IX~8wLEH$d_GW0S!1*DuU<-} z&AXpRxP-!oI&HhG?m#t{eo-pr{c3vZmVYb&*-RpR_5JpqcP#XBu^Ja7^ z8OIr8+;JSee>-=hDaJV~)*bJll7Y~E)#qC>*O8^D|10EYUvfvQ2D==4hGKe3wZV^; zNQ0D$r;(>LkKA6Vu+4QiZ9e*FwZk3q&w1V1G`=k{#(9b?j3X=X{2Nbct@aYq>aNgzU zvTA|kC=OJ;)28HrO=FOw6aR_&CmONl90CZ|Ie3aXad-4CDX2fW)-pgZmv|i)pIk`4 zq`l0jl9lvA?+{5ulw;Wk?KxJ=l6vmMXT}$l9P*fwv61X`QU#+4Cq=Z;piW_O^|FHY3!xvHI+6LVb%O!^Q)Lq(RsV+%D}c%JU4oX>Y@)R!w^wp`U$#Ix2g4 zrWCx_3be1kCdV4cY>g$o%8qfZ7=ra8bxGAIa%C0T_f;$Az=fFDbeHYFp%}K(6}&J% zxvsZK#O=M5CU-jvO zf!^rXbd%k<8rN1)LuY6RSr|h=MyyY*?I7ieFYgJW-!)Z#We&#qzZ2t>5 z%q{EFhLQ&@A(S$XD%2L0SeLU>(-771=I51Wm%l5gY(pcl9#Hd+M(asH!SQXiAB7OA znv+AFbB;2DniDmi0Ca`4FRED6`B8;+%0*y~(z_7xZyfmh7vl8dh+)6jQZ$xl{};1c zaZFcu)MbWz#pe$+lq&y-y=HOLdl(qdh;xeiD?Py0TOU4iNP$%x82Q9QGZaC)%G1b@ z0f30TO2y+TSy-+@ca|xqgS+zN z2q;bR1h~~n(GB3?asX9b?2ka2nObMRFJey(t9)_x7x$qzBwQ~)IXxt4U)!~GOLZqL?+i(ExIOm<0m{!&s7bvNA{Q8Z4t`VZ9?_gTnOmYQq4 z4M^FE4#zqcykfGVg~;F}Us5ld5pUBOwVzVFb|bcS2#HV2VIZsqhB$ieOmFA8V;sQU}13n$Ta_w6{2)c_w*9ye%aM9B(c`K4##oiZu_o zs)z9LlJhFyS)z@0OZt&ZopOTJW=o} zZDI4mgTmCNVqh?M)56&y8bd2hR-b9PmanYe2{HaXS*>(X?f-J~Jc%Xgs{UJiwVV?LQ$eFs0d}YrL^QsU2DK*hdj12;z zb%Kn-{V9N!YOwk_4IOq~$0B>!&K-q@$b6+8M2T+@fGMecHvEt(IyjZ3P_44(D|+H) z=X?|h=!Nnj8uY22!F`R`D;o8&nXu42?V}-NA&qdM$fdOBwDJ-Nf7&NeKVvzvH9oDs zg5~;33(fmJ`c(e~gL-^+D@7R&?k4#or@CPnqyOI(*_H?9e)5m6iy~5u1{LAZ7D~NA z`Q}=MH@MX(+u-#%SU_;z9#jUciM9M0-ikD2(ZbKkeda-*A_LUeuu~zrut+@+qIhoy zs;oRS=X`44YJuGpcK|&`Y(&^m_>**S?1Mv}UJfHkLWBBA{SbA>Qfg&MRZ4?i%_zGL zuc`2J_L_Uyyc!2@`!C=Z7!FkZJ|^om8CFm~Dq3*lk!t3lTDd=S-?(@F zO2M1e+cST!P|Gk+9bWVqNzjGVT?skL(k=5p37%E1qsz1J>p(WC>-99z5elVJbHOHO z&f`&n5KsY(sEt7+NRy6TblZEWsnJ?GQEr(ZDtM)IDP$YHOR&-#J;+HvmDnhdv91k{ zsWeHBhmIv9R8!e=p)Ry~@n6N_Lfi_M@4)Gz*`A(DsL0m3NR-;nzWLo=An5B*BB?(S zFSQVYisUzm{7*AQgJS^5#yb$H9nBU z^5eNYmkCv)?^6SaQz?}!5+vI&7GoO)L>DF~TJg4LH4=hwRCu+LMJsD|@s^^{C8ZTs z#58P?whMv3$6RdYZ$rkfmSk>jsb-!7DF%2WP^YFmSEGQ^H$=^^LW|sGO%r@W{i0@k z!~tYEXO3DPI9H^0$lKt}8%q2=ruFARk`NI56PjCIV>O~KS{6tDJEAB2o+y-I<96~1 zl2D}wc#r`o*}gdgGp}cxC_Cz2ifocxUzKMDf254W*`&`$ zQ$C=d&4abzyi($K{y`FgS2fx{#*WsqtK1LG4U2oV0+QTM>+{(+E3g-j0|_O zkq){g9Jbj@a7RWbrxf~+kiQQW9|2V*&opd75SoEby*9T?uzCdsXLY}O4w&-+~fDJs|S!iDWTk6o!#WqRC!^t^hDW$cL^)M*p z`BPFeN9sPxCpiN!^VNSEz!lWL#bBOh%$&lpx6frf zY$-Y)5|Fl2tMmBM@F`ox;FbW$0>IiAxRJrhWf5J`Nhn#^hI6nC`&!3sD&M?`K! z#R3W2V^HI=X7Y_Cgz{nGPS9(n{D9)j?zE1?Eli!-&7eJTG{9qyY6Ild(74iMD;G)% z9!<2V*ZX|M%dOZRN?$XKpPz~)mfi@@FV)O=$TPrYOKeNro>8g zcGQ0YbWZFk&2cc-D(T1jdJBFox#*BlSr?35;3|~Sug@d}#K$ONWkRC3F?TI zbokT;(RgMa5n(|?raGZpGn4Y@SA~p;)*u>!=%7jWOBA2s@;ezo`+*K1ptC?>J@ICm5NoS+62#>JcrA60jOe+Xgo+bb?6gJl~>Z zZQ@IHLb<*tUKfG=iok8*RLR#BgTF@&wv&ez!e_S{}G;;{I+zWseS! z3i=<4r#=-=YBKNaCWNKD{hN0CVgZIy3Ew4Hgcie>(KS^D(w-WIaPadchj@$!44OfPk1n)D!6ukTb+|FGZzr z?0;0_bEIb3^n32E7s@3z0vd4EDW2bx1gL{36MHL|q0HZ?CT#}Fr#DmUqFTl`sZHNR zYzV)J@Vo z{dJ~p1VYnq=`$AEWr$X$qA`#~RedPux?)>FCylB`(MUqOfe8?#)P$GbCJIV~AvHL@ z$dEd4I=|>HllJ%m6Zi!bpI$}?LUKjeXexSpn>3wgtkWx2{d znxbYKnyLj!4J}`3xdK7zDn-#Q*wgDU+*Aaj4L^10&vur`bZ{l;_6%iP6@)n+@EZqv)>^7`t-;6CsP1z&Psa=f|YQ@XGaUE5p5Hy z=wow049bhsq0vUTCw)y(G++NQsUq07Osa+dR{B}nMeb1=iUtKpl0Z*2u7R`aG$ z=h3AF-;^N;R`dwg?^WEbPl1lf3Dn(wsMovcFs}6~!c?N77=1=f_@>>r z{e|Xv+TlCk)dIy{qKLPhw3del;iz<0)pBiZriX%HH)*IQG_q~n!~ru{Ids@es%1*d zb^%HIZ5m~qb9T&yNLfGQ2P7X^M7f*_Y$Y@X@5k)3L4}XWxQOQzDqPm@eOfZl5yGHM z=_W!~{oYs3h@I4q5^%e~jbmasD&+`N9ZoOqeWgpwbxf+4mQuiyeA5afeMVnMU^-$t z9nu7u0bVel8Pfmt(qfg3fX{0&|i1@i>1Gs^yjTUMKA-Lz@r3WoPhFh(ggcc6(waf zLS9p0-M8hbAwv-GNDFwN2J}V16^(@(WuNtg=Fy=XtaO2_Rxnf;uHXVa23RhIb2gcZP@kljJ`r)Y4F^1Pa7nA+$2F`a!_dw+)iZATRgQadG72M7#oFrB#yG zH&WCZ>zDK9x_H5wkNk|&A9UB^13^sM(-@=@BrQM^gWZb7YfwzuJ8ymVJ`nxi)e+CH zq~&@iVSl!BQV^bWqC1_bQOy7qWlhTee|3vVyYHA310h&aF#e^aQuudFUWqcm1P^6U zBCi76Z&kN*p4WdCkQc_=Bk0j^A57t;BLRp{MpP;{F%HdPdM;u#38oSzM zDgt-+6hfQjeW``3g71`lw}4pb}0B&U4IZV+ZPM8eQCMMJg}m=U!bCOp7P@J{*k zwKh>tKZ9IFC;#*V$#q^CrbT*}z$wmxel~R_*lLwDK^+3l(87FQI3X)m7CA{s`wog` zrRP=_MXH)r5a(NjL8pKa=atRmHU-O5H349?S7)Z9>=C9kq=|0^BmRne~fL$mT2?(g1PO(*?z_ z7!fa1OBSKo2E%LFL2*E!X20}ORz}WOi^K_JPwZ;m6D4rDT6RxBq5O^d02obno+w{n zlt2LjfUN>=m+^tVLitXcaalNlujTn^#u|Du7#LnSzzaUwc8Y7H;~0>MqX48?5Nx=e zt|`aB5LNRUsgcDr<1vHzZLntTCob?4eql;7Kkg^Qu~o@jS5|1sdL{FAWrfnrn9K*2 z6{@E+oZy5JD!EVEN#TSnz=N#D?Y0%*qE$G#Q~|X`!>#dJZf=!N!-?LWoaf=hh>ek49A8Si>|-W^jE8e2qj>nJQOcG#jOPY_;b!%Avu(ET zFg+bf^Knypusc-??5HPiTF5wj9Q0jskXpINIPMo9ROs{*@`xILsIqVY)v|m{OnnI* z`h8tY@;u3%>F=cm-AW3g+e9)A4&+5E3LQ%{RP3gxhskIF=Wq?DIGfK26axA703ob; zw^^D*$$%D<=u7gZg-pe#P@?|HymX*YrPJ2Ag%T~M%ArbBmeB1Id6PTS-$xDlED<9w zB&su}NTSC{c8TO!BvCZ$qwvdt!WZoQ6J9?^sK-|I!u^w_d1{bQrR(sq#K6$A7iu)F z{63;y_kGfSS9sk^xNgy?-)4wYvHZgc>x{APbrtIj-LR$J34U-iG?2@RxJJG89Xh72 z7Z=K5+FLM&xXad_mXLD7Pcjp}skx=}M4g62Tom^|L zGgYOio$yfVsuW^wBFttQ=1Rhpab06xa)RkkY}Opy1=!g&jOr(m%){E?@m3oz=|2#UqEr1ArvYyjdJ%`aldBwk_PyaBbCE<#It@11-R zO=%OrO0y+EO$%8uf;X-#baM*<67=iCSW^fox52WuvT#IjGoTzW{lcA+4g5Wlcyd*t zF}paH@2n~`ccZst3t>~na+hj=g^lI$)nGwuvYM}`CNyN?YJRJlU}W3Y@{sC6b2fA> zA6Z?vC=9YRsUcKlZ0rg?ycUWxY6V|aOQ_GJ75ru`6!($kylkj2g*95mmxO}v`<47w zDBAIkmArgyd`GV2Lu(5ygnoQmZQ&(rxRkG{BZM-C75r))p#pobgukyN)L@&I^Qv`) zx}_=&NB^rH{lu;zV*^<~oR6w2T+)pnM*A6(-SqBq<<^$g^@I|VK79c)tA9R%aiw#M zg?w;?P~WvN0uj>6W{?*0jS<2+*R+Ld2yQ@Y$9b;?fj$dmD3`=`{zMasGk8UNHS$sG@&|YZ5 zSGEz{-BVwoMNIo66?+CyrWg;odxl_t--8E z8)DX&Z)+|5#GcjR{n`kB7qWOc(sbxXjzjR=x zYuvO!@a4;X5Z17gw|J|Kf+j(vzp4aR=e-x^)v`gIdBVk^(wAv(GW~}uf9<)WM$pY-( zSp#|M7Sxs_1GVtE_Aj%ChY#ctTY>Lr|Bf5L7n1*n0a`fxD*SPOOXY1so=f+g-DUOW z`_1<6TKjjI{X5_O&9;9t?B6N&Z?gS6(*7N2|Mu!`8M#mR+L5Jou;d*U42+Fv$9JC= z)>_v6A~44Kx3>IvTySJ;UxMZ5lY+?Du9gLictjH?xd~X)WJ`S(|w3M+GgDA8dzu<>Z|1T^r{n$5*{no!2Zo57jn@WMi z#-(2|P)1J;^k+F%hY6KLlcB zl_h-DBsRfs-{N8f2WJ)$ELhCzO=ih{)ruq3EQa8?nEx^v9A_=!#;?J#-y%NrYjFH? zVKI)c@s{mp5f<_fU$Zf6&_X_X3JYQp3wgs7Hi(B#VkI~-E0JYz-fk*#s1xVOQ`stZ zZ~^yD0p@oL2y+d4J)h^2|K$8)lw(psX_(Isr-Jg)JpL#Zl&$CSnbUw7G|#ee8uQY# zk~)534y(`KeaFrSPL|_ySV@7sFF}Dp{Li`UIm>fVJr;2u^K~q-<*`gV8fH2=@=A-@ z=g-?H{{1*fqyO9feP;hYnq+yom^BdC{d>InQns0m zeZ+4qWtCV7)!&piU&e;BB@ea0I=TGzG9Vp&p!vJsC8DPM^>QHP-PZ!A-{Ie`08(kY zf8*~O(hn?w?A8d~vbj2Q+K$mStiMKt&4{m3Dge{hUpINrRR-NP1_OL*Hb_bg& z?mlVfHGU^}c_}I{4qkp1_g$>MAj)U{hhge*KFb1zcP-B?Y>vRrog{{Tu@*jj{9d+) z-9EzW>|^KH0WU7>XHjgb7mucI6EB{!pLJkQJ^7XWtX$9u^_ovQt`uXtnvpa0zOmXz zW1~;wJk>j?H+XWx0XCF1_T;GtSUKkB$yXm>E1AnLmbim#zR-h}LJiK8{eF}2y4gn$ z)#C|I;q9Mi&u+!F70|#RUD5jLd;iDRY7f8h8P3CUSVgw&3h$M}!r8PdmiaksjU-&Q zG(5&S2&_*Vj@`7~Jx}bGaW5W>#=)5p$`2hF6f6HNySeQ+t5ZJZGfbVOlhsk_LMYGy zF#V8w?B*R#p!ch`o6k7G8nQeKKYD^SV%seXPQp9JVu?J-@Phg}OT`!L78A}`*eiBX zWbr1;Z-2AJGK*i$zk1KQu#Or0^n2vbx$pTi@?THq%|F23?t4D;0~-<4B3;JACuO=; zIIX@)6OCIC>^FJ#zhRP(t>S-wU>(`zG~VhXy4-fF_|T8=_kr1#{J*c{zkg(1N-EPe zF4OLN@irfrH|w{Ocl!jyQPcUBPe6ROf}i^Y#DZysh+Q=?vTHEwD5h5tY@ET6wt?81UlcYYG1MfU4N9xaJ0 zgl9Zg5_>bZDVAti{Fbrkar{>&F@@PC@+PigMIo8IK76*bIEZzb$lExJAuK{qcK@5reV7G0F{tjL&A8Urs4tD5uZbn!g%Fo z;)5Vz;|E)8_7uVNF-C839MrT?dZo&Qq*tAxVZ2(b__S0+QIHW%ea2!Q8Y@=dE#t&J z%w;{7n~UX2rE5qrjnX5&RgqTk&=#VRr#2Ut>lPLP*Mn&b@p@&KA3k7ucN3Dsiu1Pa z>ntavzh)32QclziR++3+Q)`Jaij7&>?A0G^Dq4xJ3(-oXs%R%Qv~4ZL){N;^aUoIk zEY*>a)Ra{0sbVc9vHdKuiQ;gm7R&jzHlk{qdtIq-9Bf%bPBaR~F@vgCse zFLKlEAa7%`oEoOrx7M?j#2D%^k$nK^{Q0bJJVILC8-ZBVm?Qoo&OpUq^A0 z|M*447^-6ZQYhA0RjfdMv7^}B|L=vLxoNVwf0oT#l`WblbrNd?4F}%mWZDJHC5|OX z!2B>0a7@q*{+U~$Y?X^-i%?~2ZCTY>Y}}9<;di2qK6Au$VTfhmT(P7e^yFWe#Y#dw z`gmEkn#HLiyYrZba&dqV!RK?aJsbGcV&!6{%ogYJq-Ekew!94=y8)0I;E{c`cP zF02$@?()SGc-YNgwLDxQ<_c~`_oA>5@A;)wVleYe;03G1@~of^FZ;b{VH59Ke*0eZ zXKdpX%U^56I|4gBnP2%q9P9aLq6l013bM9j8;p}MCC=8Zn#6mp6DxXdP+@B|*tZ%C z%EY2|VzQ&>r}G%J$OxFx7Z+E@nmiJ+{hv0m1pg%dCg>@-cszSYT7Ni9H+a-e(Yx%X zXKI=sMg2#b`Byu|GQxh|ZmalOcML|O!ctWE=ddxuzueTv}jJH@gkiwVQ)?-T>dj#pGcwnqG)g3RFG z>=ZxgX1*_qG}1C>m*~iJ$#09os_-?t#U3uYFjT-7iX_%kG+mTzef7p9pU%U>!i`Yb^I&ty z%=ixfO847pJZ2F6cLgKdVijzdW%Xfkljw4wa$&4pkBRji*@0b_IcLOoF3cm*lKq=l z8`IMtEIHT2<|1pp&fCkb({prE|WoZKVH0|IC7`o#W(J5I0KaDPfxF%MIBTQ zS={c3c*A&yj(5)$%e#Mf@gLwA{%x-4#|G;7hFq~J)rx1ikhkV4OVB;h=qU`~L*IxU z1b54UH{z3$LS@TZQTiwdRV}M!DNrxA94he`N%Z5nWuzIxKt9AE^%lPw@qx$4Vmphk zr!-yAjb4lxA?y(}zhJ(>OG*&OyNY~iSt)>fdP`}nw5w%_w-n4uZgvsXIo~4}k)QUJ z`iN;RqNTc@G*S>RJBb!h3>4Up(|Ma9$&332NVSD&JRv|zW_i=Ju$vTin7aldteQP+ zaUjA3el}2=#`>fZo{@!3;fVo~ujS_;$wgr9U-MPXBwv2LoK(*3=joEel(u*P2%8wz zP313xr4U}dyp%4K<=e_jjol7RD}ryELhz=%Nd;*jt2~L%iIohvsadMyb||$7>*udE ztf*jVFsnR~u*&jZ%S%rDRIudhb}FR^^}u8c7`h7;&WuNeio@kDaai%jGKYtw-lMg9 zW^;9o|7UbM?QJ}`qLj!c|H#Kyl&T7~`0|QUMRs8W|FyCdV0lSjsTxS7&b3xe64OOM;tnPc> ztSTsbuH$p7A{uvopsG}dtzBz*SyeLPnS0)_x>TNdzvaEF11)APMNpOfJz8ToZ?z^) zPz@Tn9oA_P z?^YiI_D4njPXXt)1dFo#dVR^2Rc_87*Ow}JI%&wAaa#%QRlw?lVl(6|;uRvKmbIHK zWb}qX*IA!zFyj^`^He-~owQ#@tIy&^+jqo|CIfC9UmhV<_H4aKjlWBAmUR~K+YwSL zpA4?DT#my@>Z5P=taFREL^qJu2+mvQV2G-&Qkx~WfZm=E%{0fHu}LFbiS zS`h688E+3-tp$}vP|_p*w25@NIKzwY*+ zZ?qud*X5zbDMpGD%H%Y%_si+Qunp4y@AiQAZ7MBh?`H82O{EZ4tqHHtO!``=!B;ku zBHb?ZEo#8O^rW^Pz@1~!9U?g;*UvqM2mdh+olkD>BGfD0 zKcfcovdyLbLLyXa@O$2?2E=!8(NYc2V)>WRE+YpG*}I|<09-SikF zR69b(KwPHk;@0-cj8**O7MW#<;h1G-8zcvxGhi)+u=LY}>2iKl^YZY$Mrb3TJ11GyG@POGFX6QlcM?3j?yjPLz?Rmz@??Nat{Oo^_+uXmPuIa{J6tgdd3;!$0sw)!6Mp+C)>f_Lc+ z?W6e8E>fQgU;Ue5vE08ehKbD+Wj)X7Bb8>W z)Q}piWn-SuSMp^Q8}lK3rD|2JC@!iBh2I-?f8qC@-G4EPALuLnkm3Wsaz)+SsWXuK zA-S;~oZKgAN3}^O!%dlQ{h;o!mLH)|DGu$cm4+2zT8YucL&$>b6!6ayJMbCjy@s8xh)A;8p;6q{U+Tz)j^dpLKv$dN!>0_8e0`JEx0C+2 zXX@ocJyQUS8pbc$zb^-1;MNV}fl|AaR}rW<`i$*rFN_Wa z-S3GR@;QW}H!@Ws zpm!A14ncU$yfx@DUdQNTPt25?M)0IT(x8YjxQ!f2fa$W$&}0~furta$h)-Q-=y0{$ zK?g1%qYob~{&aKCVZ78}>D&HS4>7c2o8cRfLJO#*y=9bbpm3X^?O@`qye84I%-DHYiD8_tCxQf>X1a1?jpZqjoG9y3Jp z_h^m4ArhXqK(8{kUxMjPg2@(t*ye~i zUZwhc#!zV%TqF%6cPQdEQZzOjz-g5Y}%x(o!$_6KJXg> z36jUbZ8Xg+AV{Vz2dH?E0ImR-*iA;~Or3|PW#R~_tjJ!J(%62i$q$SI+s3GGLUNZP zw#ShKWy5rp?OwQx*h*^EB(`6`^sch)RLT-ITKYj~_gqw)AnJBK z31=+#(54n82!;5adfrZV48h8JY{f=H+*6Mm#z-yMvt7L37-&2X(Hkc`Pj9ammv*tHa|bCy)xM`jYXB3nCmW$!9NoyrPL&ea#Ety$RP?Q(8~Ed?(jTnhCw?VG`iebS z&s(HQ5iD#SpOz|xdiGz(aG3IhH=fX)dMrNeI5v&&pC~iG=fl&b=KA;FQ*ADb zwt&X*sWs0@$4utykGw>NG_iI(PCXWtomnib5-&f9TG>5>L%k6hEy*O8@Zmc$q+p+i z-Y8lcVX(6hS#bki@HhAu@Ru3VQkL?D&;AD5>R+$9?+mGhM~?(FtE=&J+lo6Bm8Gxw zm>JSJcJ6N;GgI2k0{-UtGo`^L2et&-WoSH`{^DO`O08MXzxeh{X)ZhYCvTo5t!3r@ zchTz$(MaAeOb}tFJx4vycboKR)4g2fPuFP>qAOMsIPEu_TaU%QADfr`S5HhA;s$Y z!DfHh4c*_CHzJ-ex8>^(3%Kq!IS@fh5rh$79BQihJ{}=^z)PhcFL3{DhDKQAcs#T`{4o8VMnTn6 z_Vd*#j}uyBt%bbWTxlB{%`JE4O3niNW`RX9OP+#PZ_EP;{a0oEoI>=l#QEGXU*c@d zJj+k>rC=d!81l{(*7ud@5Su+*z+0{{`lf$phP6RJW>g|&tTFVH%@l#_$q^JIp3BtL zeZ`%)bRz6acOo6|@?WGK5Re(w4nQTLmPQ(lAeFTKOD-;yHnE*^__l@8pJlgxSD2(D z*{Xss$7eRiMNrxD;_rCQBB?uT|DC1mVyUE1Hf(kwYKrNfsDZP2vn8l@muGSF5_C7S zXIbtpky0eq{gb8dN@;??u6*J*S4q2A*-w1#_tGO4_K{CqP1F4kmTqe#to-`Ex6E5B zExCEes&3YUC3?68<8G_5xu$A1-W;m^avBCA8CuZ^e zy%MscEcyJ+7U%#eLELLACfuF#EnT;w99hLcK6;xJ?$I1Hw1tDC=N=)6KD=eeb5zs`h#!%S!%D__=kwa67|gXia)r12hvyj4?bmw zbe?(p@zy&rNokhHhwqerV&M38k3qA33E6>@5TKO`Z`&%S` zwsJd=(%1yN6B_>B*2vT)8qKV9~@Ej4n5*8_F`Zk^N2_8llHP*3NP4) z;cNCoOW=Mgk?{|B{R7f*w&gyz9e^qxT!#A|lxnzsEUlJrpv};u6z_0QYR=Ah@FfS) z<2}8{e>o`KWiB3k?ICFi8tcihY_k~ea8^)bp$oO)g2-X;%P^u@_{dOh14J6GF?Z1 zk$#{0FPfo0{hj}EL~1eM?L)G^7T$&x1TA9)j@Q$P!epEY*0qF|WHUs%p~L53ZpCyg_7Z4U5JN2NgDafr!g*bP=F zA1`HvNLQ6yw;3FDeEm@=URN4$80c|1sG+MH|8!J(=yiV|x)jrq7(B;zI<`ViY)L%! zCZF5K-~NJ{w|O7;J|<)I!K!(O) z+DS)m=x|pwwnV5hY(_X`W;mYmQOn~G#2m5KZxnwhfYgj>U)Xm z0c!zCl*if0Zt{`oqXuo|W2*K~9Xj=SyXHxSQ;W8#r=d6^SB3GKrME z#BZLJHUykvl))$W;z`>a(llT}m?e^G4+UZ5R=(<- z$`k1u-j$EOBn@Ye&RBlGBpnr)YiIub6)B4S)`{P{0)!)-xbz#oTRQPdze!t|+aZ4a zH}rSC4_ankg)xa$-_Q46hvo0Pee`WqrC8JOAGL-g(kwrJ9=GQY=IT()q<4Jp4b;l8 zHKam$^OrYZ6Mwmy``?s&{00FxyTf6$rv%lw)*4UVoAQwl2UhcTH_`jmJI;sQl;VB6 zt^V&y8?%};EkB;4b9CnUH_le1(^iaHbe6_0_u`%`JNxX1&%e3@zJ-? zC8d4OO}C^<`lr88>${D^L_kW^kWzj@AWeVh%?vUjlPZOcR<%1)9YZG(3WkR``)l9;0H<8jOfp4@NWn%+u^4OjxFhcr^q`sgkAVp zA3-Wg!C^wc;6n^HYw({4j*KpXV>RX9@U?dM9-^lwib20tqo-X%){NrxB?+GL&j<$E z5mX6r$2l=5E?``7xbA=9A;lxWR^WdNDBIx&NI)Ffbx8SF3Ll}|C+MhM;-gJl|gIl+$=hvOa=qAw1o zEdZbCeg7ApVTW%Z{(gv`7|hoqSU?dBv?Hhzmet^y8eA1H&JNEe2L2j+iUyxb^dWXQ z(d@xh!NfmVgO4M)TpaEm_%8&WdsnKH@=o{OW~v`=TKXn`EA9%x!3R1JU`tBM8<}X@ z@g_Ht&b(l#irGysr`Zf+UXmGs%q_`5Hbc*R0XML9NiMD0k7Eo&hLV$41NcvH$|7$!9Cw!R(EE~)2nhe_7wo#zm7v1;lwU@z2`C*kA)a_|1`vMO(b1nbd?1CUd|$#|XZ|WIkm7abum7nt zzD1Iu&Pe}|Osz9-DX&b||6ONP_Jw6(kLz=tX`ILNA4rv?zn=;Y{9=17V>Wy!8NL{( zWqUHRpgjbqEGVN^PNYR0{h*n|00-7lZ7kF*_vi+AEBip01qV7Q6Fy2+^@1MNx>!b4 zc6BfKwue%anhAj7c`3BGh8lV!eAKa0IiOmxRT>!KpfRs}&I2AvQ`v<-`0__mOtoZ~ zPCz&aA9eIZWM9CoT*P@=t>(f~ON2X~@e+@vVGSGz6CFBH{SmK9Hzg1RkwpYB)qo&S z%}88klLw>c)29NTrii{iH>i^XS>Z^#Ok>eFkmo*@%6ObaKA{y}%X6l-xY174n5g;@ z6_iMdI8mc|9e{|lag^0Q2hgh#kNyXbrW%hj{9_-fWOLI^a4HFE(_5r;FX#)0?B_=C zs-g1Ar&?Z0<>jtcxXZBNUd=0sRWq_xKeX~APo(hDS3sd<`w_Un?x>NMRG|7S%;Oam zsVlo<<*ABPrCK9^3kT*(8fs;H6eqfVL^Bs_1^VZ*2U;bc zpmbEQSgf*|j+=g?+Il%pw`T&f#Ae8PLiLEhv_e@M{7mv$V3k};?+3NUXQRgFM;zh+ zA68)H$E}zZ&Q|yft5m}<0$_DyM&9<+P@(1jPdmiy~e@OLeOa_+P5Qk}0!|~Ze`hc<-2kVU{g=!XV zkVfHOoEQWl>+5I;bz}I^ zmr}5yQ)AFVEh111+=#4cWB%c#Un*%pMbEA3nS5mnSEr?2+M#yzFs(Sb+ z{ht>mO z-Ycozz&Ba&k`*F0I2sI$#K5lOQ@oHY3?JoN+!3YaY_haf$QuXLwS;Qd#^-3La|yMd zidsNTK~qm+bNQq{VWlgd%a{Hs)ne0T@pFGlekuDmktPE)XL=cKUQS+5aNQCKuJ&2d z61XA2Qhb!3{~!TWu2>;IiPMgKF(=2%(r0p`BG1;<$$=wB3ZIb1^C@Vs_ z8;}cnjWOGG34W)w1Hlfs?*T>UVUv%n}l8UX(u z)h~wlp5dDu<>pb}!Xl-0#l7Pjok;2y9Wh!+FyUmd=zu49k0mq;OC{&b5y7LAOJSH* zhC=N~K%QmFZ8)#xBzv}vOpRab7yR($}+~zC~X5pv! z5EprV_>6g2!qCJ^hf|Ym5HvAOvLOhgYgb4Fea2xpP<2|(<8@2OU-@4*Bf|5zV+0YN zh1)LUDw5jF50{XA+%^)*BA_5_xtS{^eKs9N;TT%gx!~QT$11 z`3Kh*umKx0(I#~}zvPR`$aexd%|V68jLXezhxJ$88yL5ZrZ~JQKsb9w^7#gNIg8ix zFi-hCOK{_LyyVyH;SgTcTdvA>58<7?{ldKHW#ISFiJ6Sn1x{)HfKciRWyEOMqC#(jZAym2d>xMLb^5p0|r4dXA&TzH$WHF^G5fl`A&riBS6s6L_zeHV%-2+#I1wFWg)PORDGI2!-AQQp-+W$xp7v_73D7{p6a7S+D|8&*rLB zKZ85Xbra#YeLn1lGL8QkWs2`2u=u>5DVL_v!gSNvfF*gFrqN648S>zf{JftW;5lRH z|HA5yw1{QpS`wR7n%4`G+c8@yJ|jr(!hR^lbA#j_EMEOq<3q~HVeE+qUr|m@XZ<|Z zg_M^CHrSn4svtjPQ}kRHEC;dSdP}Wf+<3tHyYadqawLm#<6niyG3<_xxK-pgL*ytn zQOA8M%AJ`(XZfn4d>egPNe!A@8PKaGD30>{YGpZE?EFdK_k!dQ-nfb!CBFP9@RjA{ za+VcU+`PcE{1qzB;fb!eH-PLmnc!IWkK|4f!r(>k}=5Lgm#=?C-$1 zYhA#c9hhZ&UD<=NUlJ@?Ve(5+Xou7Iaw&IKwG;m?9yRS#N4`H^{)<&l=i6JNK0i#e zylW}96oi>PE8lu6L083BqOGu#;R{Sj9(lk`p{SVmE3+{}X#d)sEtvB3Vv#lE20_ z?uxuc7aU{0QI#imkt=jr2n7lH$$Wf_nVs&UhELU;Ptc$a;fGz_@+dWk4jji}^Nu`P z^J4iyPS%{b;ZdHXIRoKLxzAs8k+-^y>;|s17r;8Z(R&-;<|vf5ZEVV`^_K%nZYYnT1Ix9#mF0QO-f{wa)rx=J zTkg;xDv%b7U{(-}4Ri%9Fhb7Dp{)iX_VCjPH{@#JZ*Cae>7u-fhiw*~A$uxD@|ggz zun~OE06CCdX~b_1koT~d5q$nYIhgey!S@YB%?%#G-wl+*eZL+iIAp?-g5=@FXRNuD zEK5r;xEzza?~y%u-$C+Mj<<#q67Q>*gZP_4a%Gm?fR`IA$Fobr_=v%%FT*_fn!#vO zN(4VXSRTi6hw{clWM8k2Lq2oIZd@2gDTcc~*m@*4VqX~erXe88to%Al8}|R$ zd-L#`uJ(U;ot^A`w#aahL=wV55F~LB8bdhdAP9mOO4QJpQ$j=438GB|Ox=nDUPs_>N zd#1cVYB-UX`=(j)NEazDj91Q){iQ>m zyw)7~w)9!3&i8uQ1Ln#vN>ZQ)UocN@Cpp~tr}J>S@EF5?m?sB%91X@54c707!ot)w zxyyXHt;_dD7alQRz9{vm$=zR--|U}W(*?`+3~uehQW8<=>2e&@b_FM8D^T>olX53$ zWq(%U?-TTzP!KUQu?3;Oh8c3B*8Hbe<)+e|Fz%Wxhe=1nc(}k7VSG|D+Wn<4zA+gm zc_qwVo-DUF7`E`Rh4S0da1%eW5P5#d#BVQ@Z%Y5hY9O!4G1Bjzyu~7f``yz%VUe8Y zGPaHjE-2hPht>mnr7F0l?il%VGojBzHm7uqT-Y2QCVAOCUWbDFZ!f#gE6}{`@+@Hh zjn^?SRx<|<)~QF&=6qg?+|CvNo^ci)BRzGOrmi}MR)}=$fxiPBeKz29y2|5)nH80( z1>&lPt=RwRzgw!@#{6J=#x|4FJzfV{;O0_T z=`kDHE%(lai#%HuR>~8=(mlqDedLfQ{P$E`Pvjrs0n2d)UT}!NxLjT$HEYC6m&=1a zzcr(YdPRyW9*VR(hr0Lvu{`I1FQ# zUaR^TrgUuo0D6Xx0mC@{lV1yxJ}@{*oqn{7OCdCP2!T_QUxwVaAzzb*j{kB4elQIk zxh#s`NRwMOo`f(_89i0p7>X6{GtQsHyu5B=T);gp9tv-Z;%(Dq-l6AxTqlZg882s` zSKz+`+?Lsk$NRo`M&l;Rll8Wyz5knh#kOzw`0n730_DgRQR z|7!&}>e%=^6SO8F~kz+c=2FOW%69lmQ7?9x5^nN@N_LyfC{ zisueK2Wr{xua>#NW5^zZHbh{3YW5Z1{hq=5-RuS`-R?-zd& z;kvXVe|4=qP)g{?Ppp*(NS$x-I$WOUz9YgJb4W+Nl*=XVr(bYdq9XW|EP0QoD=h6q zN5;ZPX)o|*>*V#GlR7-Lm3H9g*2yR8q_r1$!(_X;m*5$hHFn@1u9v6Q@qXSRqdjl3 zLGJCcH{8I_&sBU}w}s<@kts`V#J6vdTexFICQ%oNqBxxYxBkEHpwLhuUD}cYP7a;69RND~xN z-P<3n?O$fgGqBV~YaY5)p6B6)F{*RfqR#jSsq!)ZY^&VR{fYrs^95Ecnu@{Z$E|X> zwD~bNeIVDB-wVU#yJ&m=fT)Q-L}gSgKb1VabKn>Rm^)FNQCGDe{FsmbK<+P%X~jSO z0M|kX9%(_P{h{1r8^+AUN4)DcoU%G&xSG2S7n6@e4D9c|5e9tdSv(;BJA@Z)lUI8V zs+8E=X;B#u5oeEwe8zU1J)&Ch!`tPTJXd1SnA0I9xa;-{|NcXqPu+g8yXVM54bq(w9{-V?D0M037eA5* zOZQ57lb!HzxYQoEQ=V-QAy0iQ&z3G<;hlELqfHUwh2cgSvIUs#(ej~v+b-GU;+unI z+eObw3dFxr^k-AFnV}&AP z$?RyLC)2Q@{ng!aU4z#ff#N1xzu}$}Xy9#H8|v}w&*YksKHafo`U(dgG9#|%ixrMw zT2{W)vhtD0%F3?Jtc+{0_H((1bf7+u-z)oi?W`{{^EE047p$RyeCp@2%{K`#JRhs6 zK7aB#Dyv5z!Z+q!_u>%Wj5nP`B&)I7YE>k)>f4v^mA6UKFDLA+?BZ^$_bGdg{qjsn zT6>fyACxyY*mt!8Uu-*-z9=X-8Z($IQP9j7t;HXQ2kP+BL$VL=moL}x&Z>jsSi8hb z#MmK5mn)ckl8>uxk2?H9J_fDd3V6^VMCn%gU!ugMNCkJChvZ=I+qImrrQjMy#Mbs0 zuYXvcC=IX0mjGQ=_~7}6<=}?JCQ&4M+VLfb7|)&jLlbZPrF=oU?`4+?-z{FX~W4h*q zD}FU9V~GfWMPl5O>fXhIly|*q$z9-_VO7)R&QNYO#NeAQ2SZJlTVn5cU3y%3l8H~% zJ36R1_44z_(((($sPDumgnoxxY(eFvNn zozs}{mxjkem~ibXpphkwZ%osgq!8B4^O2;Yn%oK84KAUzng zX8fQ(yEQw~WX$Gi=~(PvTCb{2(83QXb!6paCS;jsEU%B#0L>;NK4 zmt$eM*#&>f)44t+a{px%U|yX)hW)tQt8`#)a^(qm+hsoFYux1>JH+RFEx%y>8vny4 z^%KKTW4(r5#GFW9RBbvU6z5TkUcWoE&!fp3;6Ez;O|2Vb$gB4An_tTv+-4q>v{U`? z1H8o2Gp`+ z53hGtUJ*EWA*$LR&DK>Y=&f?7P;j3o*I&qwp2c0|lOOo)vvQ#6tMe6=8OH}=nxF}z z|71J&KPSH#7`s4^pnXrFAcFR7g@Op$H(J0Cox{b=(9ij!b8>=5&NVEDO>gp#wZC#6 z%fLu~J>vT>%3=P;k!$_YyFP_XyOgT*`Sj7+Z*c4nf5azzgCf^?!oT_kkI;U2%pZS) ztiAb=H!qf7kVZV@@x^jX`>{WXR{l3u6+L`M^i(_)yNU0s(Ni{j${;Do8kI4l>Q4c* zfX_E}Ecb*LMpl1lPx(#`Hb~y(_MP9$0j{Bi<8h3quM?dzD&25c^i2e4`;unWCR(O1 z!8jp|o3M`EB{@LqzJq&QmNRVbyU^mYuojoMoa#FVh!&3gS=I0CDf*#;; zN4I>STOwe&u3O&LEml~5)GapM5(P_z01HB^j2}y5$AU zl93_`*V*IH$9%|7a-F)lx}%5gn5jE{@G*bwCpk{qztjHhPx3(*_eVPk9 zZ?k{)i~Os>QodFEpZTy~I+ov+?}7A7?}GtTF4I-5`+lHV<6v$1f&JL8c$_9Ri?*lz zOTOzWwe4$PbX!&o(uz!;`a4c0#;g4M-{qYR2YiN;NyhnJxO>2|2Dm{O8)QBp8eE*9 zx|Z_nJNSnnC8zQ49>_y$=f8-D#lz47IGcCJ zKSO(89HJckT%nq^d%~x9C=Za8 zMpE~)JW^I#`FZ1uhPbfQ-jc?dzyckA;O#qu^}mz=Y4lLOQC3DtZ=SLLTUKftB$rot zO`|fV#*{udcvpG+(TmSEDlxTJ^%9Rl-w@NS@xl959y6`{f>Bu{^*xPMx0Je4v(r35 zRr>kWJ1J80O8rpuh=JF&o`EUXr}!yV8QoyiDJ`2FGX~=8h;O1b@I>U?0m&pzWs#@w zbt5HIx{}NjYbd9T@4j1s5#a>ye%jy@pz-s$PxM zO6=qDipXKO=l6+Eleo2>_w-Pr>MeoopYl94QR3%*bZyKZ)s|IWs9nWu%3em{@=M6#JRdyg{%ai~Y!`S3fXf-2f$G5M(2ZBu@!p<_Reb^VjLe_&EJ)XKv`RARmE zelERH7aqI4`Sx1q`+a8c!dl7@zYmU}XI;cf4cZ5EZq>q9bU*v0Dw8ja!F`NyzYCD?j#d0Cyor#@?@W8|6a|2%K(7rv3p`;xq z72cc1>(x<~bSlLKa&*UtdCicKjkR%5*38AIj>ow0w;BG@VCyGl_7pmLZ$|IMU+Ni0 zU{9!R|E`YmuiDb!k^IYMN;mhlIoc76$v@jZ;%?2A{!;m9KBBpD)G&kl2P@k>eP`gT zF(hiDC`|1c{7kU2Mv8uwztjS_Z@#^}g>uLseg6Tsw^ABP-)-Y1trV;0nq=H`PVa}+ z)K+<S*%v0tAbNKyG<(l-}E4(C3nbWdU zww6!a&d0rvUQy_H1&f&7!nfbVI~U?cu@IBS(1kj^!joDn0dt(<_@#vnVOGM<9pk(!Y<`aJe||hjfoVukuG0CD=1< zF0$7wY9bbV@mVyRw{4?zk^0ZHC$>@W`oRxDynQ>Rw{)$meNj6l${ zGRfDU>-eD#N*~XU@W!?C)u2sNd94=|EUWplebEbOEotFoEDEC>c9A^0uZ>hDORv7o zUyfA1lJ;cUL%J%spbmJ4=XX;&OT&BEA9Pbz7!2t=wY$%M}kf z#gbOEc$+J)5vBa);W-sYJS|~%)Lye67DD!@obuH6IS&}1giD9F@|XciOR<2}q5;Y- zm+S98;IC}PSkN_EG5<$idJWO?^7{M#!@R`u{n5&g9t$QtO*hn@Jy5x8@L2fLQ(G9{ zGFWLVRwDXluo8^C*dGs8?n}~`*7kctm97SHcN2?q?D7^oJyzK!ebwIHdbqO6RV=GC z3TL~&M{>W>%D0A}`JK^9s9`s+KL!eY>0W9;$ZvY3CiyVkN5FXk+Z3X^W=$28)@PS{_#ZgJXB@L zMCEr$>KnvQPEi7_<{&X@opWTq_(VJ+>Tz=e&J0l*?^!Vo3&-|@Cc5)0x^t78Z$IOF zu?Y`)SqYOW0(k7p${CN_{g5)<*ks#76O>_w#vw0=^Vru>cv;_ZI}r~}K{LkH<515XV@kAf{^y!K$d0(!FkjoxCndj~phy@Zb?w+p4Q)ep8 zr6Vu#Pi89hr25V6r)Mg~2G7Ou7@^8=q+_&_Ch%RemA9k|9y~Hp$@P3;{8P8j$Mc7Y z%3SG+i6_3Iv@5s$&lJ zbCnTwKSq4Z$|bLNzY_m$(j(+M9`^VoWxBzoyNc8NJSC;plbYxl%Z|l;)i0yq)=ft} z4?cdr^0Ui1{2|}{Ri&XpN*X1u#sm1GWSkCm*WjCym2j8Nc(<)M8MV-FB%izh2hTkt zAG1)&@MsV!Dph-P?6p{aZ=urK<620SsaveQ^=ryONt)Bre*1ML!C>&_!)?lX!*E_^ zQ#SgRi1*c=zP*Kqtg9loHRoGXlpa!YbABU5$&^kE=E+NxWzvLZ{P7Y6^GOEsj!Tuk zQvM*mbg8n>y;eo#8Jay~u=iS~;J?I%{``aG%9z@H8Y3sGT#wK+D33vnx#-*Wsw5{c-U&Cp|1^2Q@ny5Q@mnBdun>?(9Vzf#MMe;+soj0y~Z~EL$|ko z^$G3_Q%i6g1>a3ifkoqTt%*Ds?$J#=;sE_FTwFs=wmBl>ZO*3>j#i_R2U{FwjvmeROK zik@U>mY&Q7BykOL5hC>85XPsz9?!2x`UZIWM-R0&D4F7QDKOa3v~7Ulc*Tu- z#~)k@9WV3;twTowy;8g5iuCw}KYoYhxYrxMphLiqPloXGaBR~$$R=FcZvc9wuGU>W zUe{u{6u4aA)w%Z!$FCNjI(GHJ;=b>#R%Q=q?y=AkL{D*PV1_UA`|<)nnZ1qGE; zs#!0B9Dg_pg3L z(zxZ{dMsZZzZ6$`{L(0o5h5#>Ml~HL@Rw2eD^tV3t`B(GJ4#@a*@E91>+`a}3v(}q zAHR9Y=X5#9gW#jbFI0rydB832D!w)Pz=pnHtKfs*Rho8-(CKg_=U9pN439sUjnP0G zmNU@>YQPx_=5&_J{!M+ME-c#7j7XYP@Xy~>nn^Ad{L;Hh{g!`4qLtF+L4V=qX4$bQ zjAyv##n~-V7*=(caB*#zkDK^;UF?n4C@o$6YW!(nNnQT_%9`{7UP4BdvRff1=eZG2~vQsMlg?C!7m}}2*5f>GB37YF$gkKpHgI+2A5_sod_WboYWlN8*@>&~}GHJlC++`E4VZJRDydjUe~jUOup-bpCGLK(e9`NAboSMXYXw(_^+xXhcquh^y8 zrTpjjl}M@V5^t~-%0ieq&*GK)co4Y2PXAZo*z5>|R3K2hD4w zyv5bPW40+3E?Zp;_JP}#U-15Ob9>ty#n<5HiqS3O2jmR@v2`>h)$NY2r>*ih`~?5> zDNpJ?zJjJrYWnvPYm(XVCnmk$s(V6qT(QsFiAy%y`X;#BZMsq0Z`StN+J39H-=^(% zX!{&(zf;@q()OQf`&@0mN89h!_WQJbp0+=r?en$$VQpWa?T>2vV>S&=X!}BKe_Gq0 z(e~%GeUY}msO^ij{dd~FMBD$U?JsNlE84zP+h5c6*R}l(ZSTS(s+e}I5pQj;X!~-r2=JS>zpU-gY5M|gzen3|)Ann%eVVpksO@KH`*GSn zM%(w$_Tk#Tffm1?rn_P9UfJ|fLy_2y28{8pxymGecdvcjU6z%WMP)_16h^l@-7n+R zn442CKB(j`e})^?e9Uh6Oqtzbl{^)r5uV)B_Y2H8) zrrK$5?D2o+D!UA=__p0jkiTEQWd){N$ES2hr)@H&H;yZRSfpE@^BcRdPKNIuJU823 z%E#_e`VX7m`9WpRjFn6HF$L=>pQ^lC3Z)Wq74iq9)p3PcAXZ2W!~t6hFcV^eWJ3}l zxsW1=eBAzEkAi>1|2$yazwfhvC z-Pf+HG#JM55Au|7zq9urV3IOkC%uge@ZZ{R(CB;y@ZX7R536K!&fYQj&QV-#! zfy@1w75u^hr7q0p58%$ibQ50$!JW@N2QNCH_;vWf@#L8p4H>HAhmRgROYt7-|{e^En zq|}$*u5L8zMtnHy;2~VTn{Q~@a#ir33-=NkofoBB#zc|Drw6pBWkW?KI7Uw6%2B0( ztC#R({ZjD`Xo#6+Pd#Zb7U>mmh5vaNB|WCYP8~8e2%X>extO*0W?sDc2IinWjSMM9 zIp$&(>3${9JN9`etD`$l_!32#d!1*0iAuc2w|t5EI;BG{zW}3uLBew}Qc5}8P@wn) zyxgaHMyln05N}tYH1ba<#WXUpJknMC2jqHGTN+8^Y9*gppqLG46vQI^*qeLgBL`^Q z0>#Jhu?Et6y|oGrc&+y{X}DB%k(YSGBWUN|yvq^XR5pco^mWNyM-lfC6z4}B5Vc@A z8hF3et9q2$QMHZBM-j`|UV3*sz`GqqH~ByVY2{VTD$UW+P|Dvwir7x-@Tm^(@!K%E zWz`h_qYbn;HgM0cl)LZ7xR`Bi(^ce}vFs%}?jbx%SbwQ*cPA_-`whZk!c0OfGVB&E z(!(VXI_(MMZ-kCE)`tw82*U^)5V{d26FMVuTdXHgpD={bN;raW3gJS+6@*zD;;fiM zh698r2#X0FgntvNHa+10!Z5->W8O4D>aBM|Acd@^h!TuHc)FrKgv zVJE^c!uo{ngpc0T6L1g~6BZKY5oQBL`fLRmk_h7oqY1+aOQ{6s2oDqPBwS0FLYPE& zpE5Rycr;#CMMYfJ`jLWQu5I!`I#Il`ladkO1P1|`C6WG{Pzs+{m5;Tr19IZLU{ zj*{U!!n=f~WqJfbgjT}Qgo%W25M~qZBRoxbnXruT31NUORZpNT;b_7sgh_-;30D$s zCfrAOj_?NIBSO#Rdi-X>Fv6~cwrEnu5-uiOOSqLVm+%B(5#cq$yM#{&-KeVT6NV95 z31f7$v6sj&hcJzBGhrT~^SF&Yk%fIAQ86bH7>hXHTCzDGWx951pJeZ_X^u zQ0i;c!j}_9)YW-%UHke91QI z;YT$>m_(RNxQH-?FqJTka3x_T;Tpm$!i|L40>uEmjSM-2y9jd$_Y&q2<`WhW9wRIy zJVRJSSWH+#=pZZy+C=|l{?vwq!GsZnF@%YPnS{B7MTBL9egS%X5rpxCDTFzMg#kvJ z)!*9b~B;Y z8M%*ae9OS>11l9wO57$J-;wNnRO23l&GAV0p4(O*0G`MA$GZEOP~F{HsSg~iuFgxz zeNmXsOUS*P+~c3<;fpDJFLL+R-3PK#@=!<~!pTFvuO4B1r5=Ha5=bHUBuc>Ct(#eN z1hLuk-Hai%+gdv6LB{G<=E}qhYq&|Pvg2P5Y!Y0=7T=Kv1R6Wo%$@Xbni0FAMf#9u zA$#%~eHe4vqn@)zJM_Ub{yF=iKXiNYbM~=+>Gn+BUXwW!hh=&n9b@Y2gZ2zUXT00Uza>=nH$%s!n2Vtsg4}gHc0tm* z{cXaapJe^~(6&qVvsv3kQHB#n5V|{)+QKUu8h6-IBK1lyB6N=Vrmng@hA^9ubt5~W z^W2b0yok_bC4Yq3gsi)6kJqst%O!*Jq?1f18`i_#sgbdnYKxE3Lrfw}Ae=#%NSH*J zOt^?Jl`xYqi!g_9FJS@U8NwnRZLF9KC4`p=O9`(NItXtQmJ!}3EGK0B^a81b-h}lD zo$&{09OHZlIfN5h31bN32ongC2$Km@2r~(D2(=L$eK3!B0bwCwkw9^tDIr5Cp@XoD zkoDI~WFj;ZMi9mj#uFwJrVyqPW)fx*W&^eJOb!`x3G)aG2nz{|2ulbZglqt1kkFZc znYe|}N*F_!Fu>SNJK&PZkV&|Wa2H`7VG&_Dp()xP5MrF~ZnKQgb6_QmBTObtBg`Qz zAS@*;Cp3-J;|V6T5+)F)5M~kP=xAekWGEyoA#@Oy6RL4~0)B)R!WhB?LW-DW63-^g zBP=8=)ez@`GBU7H)E0!!h=QNvQN-g3lL@m3a|v@s+JEb4+~E>XMg}&T5+F2><~t*e zeQbr}b$f3%h+&QkD}9cu@z1(js`2jdA4Pl+i)KB*X*G95z|;wP21WQ-a0_u~hGK|23z%GucNb3-GOHP)5kYP> zE=o{Xjf)bNRpVL)UV2(X{ox*5jgJPmR^y_8iPdKPDRWY|)Tivq<}<01pe#Cx&c%qH3}tC~SXP*9DF2prY8h(Mk6w8WwYf{FJ- z0|@sh;)B>=WC_A`n$vO1w9s(-NHQOmLXy9$bx!3`SMsgTWK4 zaZ#YGYP=VCQ5ClhV|`#Kt1=8jr7-3<TxJ>Q|#PvH2R3&lD^3%3t;&`H?Z7IZS=+ws2$RO5W7F#B9 z%!SalEaL9Ovx$q+h%JY>r%qWeaWCR|#PP0xwiOVsr7^TgAsK3uha%#2h?fw@Y8u*B zO5BIIgSdD%P;6zy#UGzyD<|%+Q^pqPH69?i7?V{p)FTfj;`NF95f3D8CXRn=wJn%< zL*f?VX5taV8xgk>ZwxNduj)Nb$U_u)2qGRsyeaWG;?0Q16K_sDfp`nziNsqHPbS`q z(q}1T2q6z?#6yW^64!5AF~$<_Ka)?I|&n4cGcpmYtdiik{B11RwP)OWL zyok7Sq$(jU27IxV5*LGs*c`;gu`RYT;$k=yTRHK5TKx;lLcLRnle*Yc;@V&VZXzy* zJF)o@7YD!C%)~KiSKES#i}6})7UJTms@Nik+r$Y$Y*sQ%)+vi}dLW+Vt7p(a13?VA zOT^=emPp){xOuc5UM%b`wiMmn#_+WrZOfzpM&jATRpPnCYY;a@>k-x@UO?{d z#EXb~5HBU}NxV$ssDFGHOW$78Bg7YQw9P~uAJfq`=hZE~cBH$H*8SHZZYKZU#4W^q zh+B!{^IzH)Be-aPe1b^Z;>iQPlca5l!~=+@5U)o(lQ_OCrfu281BvGnZ$P|&cthev z;M&cdnGB`mp%L*i;*E*3MS6*w5H}GIB5o$$l(>a>GvZd_&56e>qKAkr$PiB+S`tqr z-imk%aeUZJ+cJrV63-#tns^>@d<9V33W?)mXWCY>$flR5JsBM20pD2DwsPVx5LaK< z{YMb@Bi@mCFmZhPP1_=ffygTtU;ysCH5${Dj zmw0dD1;qOhFCyNTxUG~7_|mJkl@Z5BX!UKeUSfO#R@+R(@flNXGZP;~+(LXXaVzl{ z;xWXB>fFZS$uNREBoZG(s8N>^SFCkt;+@M{N;P@*ggRAor zg^p_@@iKC+;dG}y<3`*>+?}|YxQV!hcpc(a;@*Ob<3ENBzT_dEcmVN4;(^4|h=&l* zBHo#JF7d9!3yAk5UPOF4xJaKl$Y7vrta9S6#MKnN4;YF25wAf!n7AA92;%Oxah`SSyCmvuULn0YE6Hg;CB!=uFC%ULsp0+(g`sxS4nWaSQRz#G{BC%%Vr(K7n`*vqo70 zaW~@0I=8XTWJq&H5Tpmlaz;Qr#~A_fJmQ^+7dpcS>)}hB;fXt(;fa@P9PMui(F3T< zs0N7p5qBdVOx$46{YN| z@gm~cI=8V>GQ33|%7~vQ&fe8C@GWr@@r%UG#6Kc#A-QFqvx>;WM5hO;V$tYgD$)>zYxEkj6OWC?y_8{2=iJ;^&Ab6TeD4jrb+v zS;Vgp&msN;@jQ*A{!fr0j*d&`^OZsh;Jnv%KHhLXA1NXC85BN|!aJY0ILJML+_R{O z+=!P8chUaQWXPom!icL}uhO~1vnhg_#Qn&94e?;&+lfaI|CD$X@qxtSz_mNeePl== z5BbC`bTi(Scrv-C5qCZxaX!#VBX?(~&Y=vulm9GocRn7;TR?Y~&L>7WM@dXoiaJq(`Mg}W+Xh^)ABA7rtj}q`Cu4d^? zM5kU>K<-}T?nmzL5f3Ilgm|Hi0+`4UK_0{dbg|`7hC+49qR4#?@j`NMLp+Y$lZl(C z2|E!_Aor!jZAHm?32KqS`N*jo@ni~+PCSkHFycj&fwsi6$bA9v1afamJcrz0);aDh z$wLr%$RiI^h!+xHO+1VIw<2Cb?lXxyh%Y1Ve8v_@yqw(M&^WrP^C4Yl@}REMYb2F; z0VQZ5?nmyMhzApYm3Rd4dBmfL4<}xdtjAwlaB--_k%zV9A%S=-@nqthcqv6thj<#f zuOeQyKu^H=+%=2b7n8g5QMfm_NT2192j^qRGD^UQ0_2hVNaBUWvxt`vUrF3Sd<*e% z;yF%E@%uW@|LS@@$8qF=Ezo&g;(p{liny72br<5n zh4^d4lPSXH#G}Z4D)Bhtvxz4VcX5U%evNnB zB^&KS=NnHnwV4j+MRiuKH*sh0wdCpU&dwE1ydg#8NB*57oSAqdat|i%JPlij(|O;< zBFNx84_k>lPqR_PWr{F{xU;R|h-+gs{EQ`TCjaroomV!Ki0hYTXw(^Ga1NnK#GSo! z5pm~$lS#*H{O)Gso;soJ+OnA8LwiT}>p@pi_w+u{82U4*sLQGxkXgdH5H>^cgDRe6Y@$e-- zs&%Ndn&B-CLF0MpQlqbkIp(U-wOe+z*z%zNN9>461T_G~Ry_qoS3LzQys1x&tn}Fw z%rH5(2d^~PEs4DUl7tBRPe~xY>Pe)DLR6v< z&n01o&ACND|EE%ju>X_<;;WuSt|$efh_8IE6xEW*`!7j|u>X_<;;WuSkthXzrB9O( zeavQt&AC~s>B1($IJfGpEaIuY^^P5BL3 z-KnoOxHN4^Gf|N}JB>xaX_F@=%^f>(_MGWsd&VqCN|-%s?8HP3x%Ij++V&xag|MW_ z$w>&2i_x3g6`cpo)K2_(^M{E+UGoE5kj26hVKZUm)@{jn;D&e4F`9)5-Gu?1z#wK#pPfNtF$|!6xS|VoH#2G~o91|x3M?C8uwuYrZl5!HuMJTkHw7;tqSG)E*FhkDYgQ}YwFP;^ycPk{YZ zAo&$`?auaR*h8MRw-x?tVh}e}v)d3ryFe6Yh0>>qE?l^9(o1MIR)+r%wRW46G%=`O zcdZoV&)7z5rDbw8f3dnh^%_Mc z+wzzhs?68@%Q!|FdxZb}FXL%}M;*oyoyH!)It~bhkB~8+@X^f25XThcLfCV0EEM>YK*VZH50LWWv9p%sj&1VjhN-Oi9$^5r0bix00E^A&u2etQBvv z2s;n>&Dd3hAN`xLvB1T^mRhU_KuRM*w#{GLrcl0tWIgIA}xu=w~WnfB6x}-qLi4?&`K+sR^%o!tA*%X6J6q^ z7(J_Ey!CHUgVnp=j@7%~merfohSf8KF%!ARi>flqtaf-aR@)F%RaIj3Yy*~$aqZzu z$45&ild?mA z5x0%av?{u7Y|Y>AsMg{6w~cp!-54vM)TjkaYH!1retKqhPGhchh_x;qeGJGLN=O3{UyP=pCkais9%KL#s-f zf==c{W+sdefFy0gF}FBUk-lLf|lu)uKeIsRpJOMMD>ytnGlul`}I&xa`R zzp0sO;-5S=s>0UUVBixX)p|U?%(&brOH59}R}HLx8W-`PGUE{bdSg}PzxPoa^87!I zezlziy^hb6EJokoahl)w)7Y%aei^n!Z44~`G;eU%_>P~brwCMxzmLR}Ig-W6d1fuu z-+uKj(ie5w;J$IQz{B^oj%mMk-*{1~4GFWYGZ}Wh% zH><+fUu5qsFpeM%FS`1H&*Z$FKbN>5dd7|0f(Ift&2=@MpI>Mlc#OUXYyU>=jtI+ZFaz&)E;a zehe~4w^ucN1^l|k8rTEAyE6)H@=yz&R+>dtYYd*CLF*6EPvKv@KFqC8mb=()c3S%7qO%74Fsf z(=fcNkJ{K~`rU;Mg2c3g|2hh*lhhTj8Fa_v5-WSgjp6hFxBsc#KTyVHLocQc+ZKJ; zF2iuA<@0)XmVFbS7y8WwZvu&g`>L#OY=4aBNVK>IQ;+o&j%>;;7gi+PQIO|3MWBag zZsKfXX5mnP<48?;B-@U?$S=*|Htk&I{*J4 zNAUkLJTB7yvxN4x4b`nK+QDeS$%~ur8U6WRjn%J3>)dIgw)`*X%f)AFwJW3qRH1)e ziPgA>C1EiR30})vVcwHGm^V&t-tU+atEwK;AU}cpc7|UGQX5n?)fG&aoM>@n>&|e` zrq%4@+PJbikh9PE-weM^VE_CKpVd?yC%VMBrs`0su}BEzU|+xL%3375GS{=n5b!hb zS-^&8xn~R2m&XOG-c_luf6bL0hD4kd$NM<#dQDse)$){>XInRmGg8Y+S2hOnJt7s` zeCV4YWm=>|MOD4jLLH~orWqY)ZErP@|Jp*Wr(L;;+aEOuqbAluG9JAT)A-IdjY3_i=Rv{Zeo{71sp2Qu|J z{|jJCMLa9C0@vmJTB&oZ0tIHdvgVK)=lHo+>eCB`DX<+_hk8H94|h?U@v=L{T0AmD zt?TD(-Kh6n*>DI7sv$RZRDJl85Y=84c|ndVd+{SzWb+6g(wKMhqk zSJ{_*?#e!e%sI!$g;nbq9rwDjDUki=`0B7~XR=mbpcWwP{Im9&`&?OT$guPLMwq&z zD*onYUD-Iuj`MtTYjsbRJ@6v(2|0A${*nb_jcD7=ZPd0^9=epevT2a-&)cuHQFlth z!|HH#-!x}sNVi?tSV-CVXGfV@ZsOuyWo|>2s^;IL$gGV~W^P5#`NhO=FI;tcwXIp@ zH>rlq7DGl9@lV^UovM2LMO9{gus5MN-UDw29$6%MeBDNRkF!wE)B3b%r;3`m(07;F ztRivcRnPun2h}K5mGUZX1O9{@EPA%Xt%L0|$otRPJHj><^5%2)MnN*e2cOxuMWTN< zXBe`sa(<%OM9Z{g`mXEoqy!Qo+c zqRfmJ^vatDeXYht1>q8_uIkPsyQp=lqOFr8vj&hx7sT=2kT2 z8i4z{{NPg5r`kZPsh;W;tzLWSB|A;np?9?dam7zEb3o=?6pdMr zzt>x>Cj#y1t#%OjTW_^fRkHiPmDy29+(q7@kGdA__H%vI0PXPpt#7qU#@Vh4TMo&% zs2vu3V3ev|m+p*Gn+1xBG2`ITPp6G=!O)=Uf}xZTd19=ywx8-Q68G$nBW6;(N%)&Mu=kZl*Az4O@)TQTIoMZUIwwUX@%Qdq~P z3Tyrizt+FnHSW)i74}0Dg}Hnqs>hdy3{c&x5~*ycu#skk{dSS}A5bk&W7s1gMHlUh z2dJKgssJCgQP^I{oNu)5T4ncXiyDDse8W#ftIetorqp)0whc!qzR{1(M$kKGoO=$e z?hiJf_6j>h{+d9K(D<|dPK7FLd>HO^$lpxpOEvzizq7DSYOSzQ;dFE3bzBg+*x5|-|#Dg)G1Zvjf8C}q((6xF}T{G5YSCw z{UJ??`HsQW4g;eV<$-i67Wb=%tK!+-7xfaQup!0#(-?KDHh72!mpr$x8o=iaQGG=R zSusS_Zeq_3QJ>x#uUo9J4HTlkuxbb9m9+}9b2NQ1zdKCrQ zp&vAFjLB?zsOmOSomCan=zN7ufHeJ9AYVOF4d`N!u$U@tg`AgOHMH}u!raRn7JimIlicw%4Bedy)d%b&Q|Y z{JpV6Wr^@7o{l=VmP?_-7GEuF6l^&N8>KIlC;solGJr5<{;Is)$p3#=h5X-DA^&$( zNcO+0LjLcnkpI7|3K@#g_mQ&Oy`;{qbv}>IJmthO$CQY8% zXWp!dNmFOfvb5`f=@|#t&QL9Hw^m(CnLbSeb1#fdKhC^8u5rPhUfX|q{K~Y(EuFJ& zw9|svC4Pv1sqCRM)K&)9)SdClroSXou&416)T%*6Fm^;|6_ucCF{DT ztfv_2#OU*0QikZ5-TP^(4I7)@)z@gVzNaIe3Tlr8QU>b2mk#Bf64f`{GM#I=t+Ag@ z#2u7mea{{+SM_zVnK$Sm%l7|&gErcNDBk-N?|;F1?7uj$l=b}de6>$>$w9p+e)&2& zp5tZ2ofCq}i8J!=PAJ^9={Ou06soO^%=%0#yn=s7k3N9f+K;$%VpTA46S+qb_ah!p z+&O6^nYeReRT^>e#0*;8~w9; z0l9}a)7|la=9#UC+{gZNcpEDv5840hft8bcQPY3UfV07z4dQGtC;z{1F#J38A1!7x zJKK~>64tHzh+bko$)MSjCR?rSpWG)VOqfH?|LC4r&BH&1PkfpHZ@o~hA(;>IP784( z^^cw>Os$rfed$8AwZVq2vJevOp|VB5O^~tBvw?>oy`TqSp56_}BFuw@Hm8hQxuU@OcPQE;n}4`m`wBJOy*dlImB7^)0< z6tIs484@}$2(uItpbNym?JNblz)vv6A`5yhut_*3xC=kPtC-8PSNH)2b-+X%VF$kb z0%{BT8lcJ65mf|Y0_H-@Dk1_N>4Z{1KL$L|1^1-T^MSP^kqPMDz{QXx;UCzu2V;w% z_X6(jgXV+27udBgrV2r~0+;niCZMMR??5oRby z2s==kg+2v+BQRt(`Ve%1e?d~ArzK+c?6Oxd7ZW5Ec>Yb~6nYUbAPv18dVOFPLrFCd~=&r!U>rqJPDL~sA>{3Ct0gE6jp$ohQDTSW9fidx&Ml;qjxD9mQhzj62A-COyP69m~I32PV`V3$Sz>0fc!XPT+Wm33>tW5=4c58TfCA%@4%yDM-xBnWyM z&}}~o4BdS{j{or>u^{olzajC^%Yo4c&_SRJ%!Z^w7kD3%30>frgJ@UiV}aj5c0n%& z*2qUjpt}S6LkgkC15+VU$Xq5c2NL6j@jn;JZb+=iHSh=|4*F%_zabl;*FVJA3y^Kl zBY?4xHP8jlg{*|01Uv#sg?W10@ZTR13KSdY(XH&`rRBkQvZpfGdSS7x)dN6nZhxQHY+6bxQ;` zK80F=JqS1sk_|l`xE`_#`bJ;@!~|X7^;2knKM*KPJ&leAU0?`Ag)T4#5)55nCS($H zf!<$Z%z!TNBSkAPjTATgBE3XJ?284^11wX0|ztm3i=*zp=N1-%P!&JFYx=t;m; zkUaR$1itkz!~=UKu<#BtVFMA0=O5^3&`rR*kY3R51E<_YhLDK_;IVsX4rESXv-=2) zNP~ghA-T|d0k{8!euJ<%z%L>7p%(ym{Efp;*nzjp(d5tt+73TJ!U$Xdyz&Iq4!sok z08#+`5wJ}qst(oF3y8JGSr9so!0#Y&&~F0=Fat|~|7f7mU|=z#dV$5NfdwJc0`Edn z;paZEb`1kt>5cK<8_I~92!I^L0T<)bk)_a6fV({mtPuKM;Mb5f2z&p1|Irmu6l)xE21{M!p;2ua4!tMpS`Qnx2`^c%guYnzeltRZc z?D*EEfmu*8fqy{~pj-S5><>s80-OC2DWn`tBd}L}1KWrM1m0|jNmtNs15Y$EuoUQp zK(EG_;D@j#;5QH}^kN&7L(L7$9VI9b7>o&aa1hu8QUW~)xEN9jJq0+hC29qF4DeQn z0T+ch7lgtl1O>pl^2{sD!2FPDED_HZLV7{pg_(z2G0QL?h!r{(zGuHdQV`hM4%HiOU}?}xfUVl2ZJ~z%Z4i?$G6x)p8HL+mj{&xM!N4v< zPXm@hRzklIjE*p{Ea;OW@JgBuBm#j~0zZUUq2tpV>|{p+GegJ6G}sHB@Ucqh5kMQn z4|*YR0Hz`?f*uY00ulqg09XmhgU&D|u^Z$%bStnJVycT80wzQv{<;|dh4Kp|2M*VP z^STSSIwCUIsQDk^(&$xCxSlgtLL? zA=%K2fcGIe&;>TJ^)|3vkObf|NE!mK0iJt~A2yIwDBq7p z)nRq765#7&kzf!GCt&zElnlDSAI76O;O8*gtlcutPw)!>=POx zgyv*I=o}rVeW3vp?!E>#}GF_}{y*m8-xL-`cmcd1@c-ic>j=A6o_aPK`n zsx$uMUMRTSq`5-Zcp-3D8k7fKeWllUBOY0=S9lwqx>753V>#~hGbiPl_!pVr)A*qC zr#oj#!;f-@vAKkG9EUr;gafr1$?|wYm^V+%AdRalsDkv*Xlaug}CfG zb3%C;?%br}$}{n=5-Fd-{_72m^1!+q43F{&yz@rm-*2Ox{Gi#mYFP#Dc9VdE-ZugU&N-lngS@QTe{^TxWZq2C1W$nh;u`zr=a(O2na<_?Q{{nnd zGL=u_W%sCr@;co9UTZ^+^*@dD$%38w@z@TF4==_UDRDqx<9)i92WH;yVmxq2MpP)U z>;aS1v4QiF%>!FH-6{4D%vo(tC=VQs`>VhUqgc7dGVDZw(Ss(4odVk>j|XOUxkwme z?3J1@uDI1&!^czb3Tfdp-OkywBwDm^1#XgZ3tH6cT~oTPAMqdy65HFP!(01I7z<7- zruJ*)H{JJmizMx=1(@@&@w0peu9IoYYB%ovD|5wpa&S~q_s}pr>Jbgt&FzOxQeYwK z#+M&4{;g^;ZsQ*^=0x+jvTLw%2X&HepmpTVD-~%$DHJ$i^bh+3lejtl3FpJwf zrp0_!r65;-tYP(VkMS+p`0uga^itdE83pfLi?V z6JB(&YCP>pt=F1LJZVVFbXPeZ^OU@^cj zch%vl-#b`^+VI;GTBbsIc+?+#Rii>hc-o{Hu0rMb!CNMy3eDn&Q)asg&EZ9V@m8)v zwYbM$^{Cco)Wt}6L=D{d#?}u(n^ll+Ovn(Mh*eR|Sta4a3Vd?fZObx;D1EiPI!H0LbRYl&6vEKgH7t6vlF6v z6-vWD?WNKxG=pAcoJP`r$M=YWK$LXGlp$#=C(g_dKZ zbg9HNEk117NcdkN8uV*~#o8D{%DUVMm( zYCtWf79_-@d@Uf+Ez+R{EtqwN@ z;cTu#N%)Wys8Bc7oug7J6u5I$Le!>0Qy7n*XCq8Hyt>-B>Y_&6?R?{^LRt9i1-ev) zM)3Iyjj;-i;yD*5L}Mych089{Vik(vmX|rF3Z>w>I+a$TZansigs4Gc;D?GX5&mgw0oLnFSYJ|+u> zY!HiXGBhd_I3dj{6!^276QW`jYQWT6Tv&wyUzb)Dn!xofhEIhCROfCJ?sKo^eaEC|ynx%=8j!6TC#KZ}llOaP8IQgiH z>6O6$ddw|n-i+bn>-Cnd9>TSQjxkK#c;DkDvWj+M&l7G}m5BF~^PY4O7pum-hjd*S zSA1E9ee-A>Pk+ko$jfn~jPe=0`00cwFMNXuzmy^#J(CdKCVy{6QV;TZ(qZTRg%lwa8WYjHp*W27WsxQ;`4aPgclt= zj9>YKMMHTi=1M&eERjkcc%wA)W_&?v`6wp*Q3H4qeow0T82M(*AwG-Sexfxz4ZkY`eBz&$+fP-*v4Jb3otNQtQpKBa zL~3}T@4qRq5iMwyWb(i|SxjYa8QPL;6_QZ(+p;PZU}f_g^b%LuwABk;Dkh>Cve%K^VmOz-;s2l zhv!HRufkOlFR;-@UXW5gil53jU%)*#xd6|`71H5iWq6$o@FrX@qkIrI$|Rq`9ly|G z$EM?nlKCIz3f?B!y!8wB|2MxhZZ@*;aY^Sx_=!Y(0S|~0qZlv3o1}`j;P0i5PvEZ- z{rWZ^z?YULM&&$xSz=Tnxx5PdrGQUiEN1`zwEhR#M~ePa7vb%a%3JXxX>q_Det(NZ z|3|C!*e?Y<@atQ;2+zQ4rHnV>lnjT9;Xzxegz|iBm44-cAI1HZ>4iBgN=c07yb#zS zQ#^1XZ1cdAxAwc>ycB;YF~^SMF<(iHnv@sg8?wMBuy~uqD9=8D!!oEm@W9l>C|h|v zpY%(Y7XtU%HZe-~LJoGwjPk&=?GmF29@r#pJTSp8ZjbU5JX+H7T@0_6nS(4!I3U^I zF*GmFa_Z9X>4c zd;njOS-t`PE{nYTYl+cGUpGuDREqzS3ciT$(gr4YkIPWth+7FLyEo zyd4kQ+1NX2A-*q}d=?+u!v**tR_B?RJn)zT7vRNs#7TOK7vWb*6Qd!XiqD*4$m8EL z9^}OpCLJHc-=1pr2FF9ojkf~|@!=nuvC0Rq>WsuFhX?NK33D|(7oU|4d;||VD>14( z#H7QwB#%#F)!B(rBM*#!?yn&SEaJuIxUd&$@vBu@$UrS$bIouS8pJ=Jr%U-1 zuDn3y4)pGa3w0{Z1Fv7Hhr&F-H?B3;_yk^cojc)s*8fJbWs`$lAO(Ld3!w%0qw966 z@(TPixRXXVBu1;H+=;rd@J4ry^1vw>R~~p(v$a8aBkp~ZRx8iJ7iCfT7@l{t@t^cU z_05SJ#3yfjYUmMI(4c<{YuHLt@*rOX5z#Ls1dFX90mCKS)ZizM9; z)Z(wCPWb>Xgz&)q?^AKU950YO`}g1PoDv^Az-{nAVzg7I7Vu15EgkOBlGTaPPbG5i z*5NOt!L2xj+pN*m)`{hKg0zO)6@Mz#jvdB7NiCnkO){uq(SwQ6H>6T|#)Izv@7U;f za2{4mJFmfeWx@rLx)P%+rC+V<@e@fhKccmIN@6M(_|u210m^gNB}U2JCaep@@G40& zhoYWDU!GgM>@(P#812{RoZpK(fXob7pj86S5F{-eCIj;PdUb24!-u<~Duz$zrabH9%s+|KSFn^OuI3VyL zNmt&DU;RQ?J0Klzk`Co9xcp1QWdFc-BuV)+-W(-GUG{ImBbFpZ&B}}LRw=gsIBu7a z6jjIVR7(C!O1&_KD-x5UF*U8gB|a=KPk9m!hA0m_BRMH5b8IDkZD~?e=mHsdmsH!o z9e4M+dDHgK#vW;~e?Jz)lA=oc2gWb-SD^!Hu}?-E(2pCX(g8EL*A_`pi34)*DCsg` zi|`CtaBL+$DMgO0_v@TT`T)L(Fc17v`+AwO&meBST~ajToJ~Ft?=LcOfc3w~hvB{X zRWI0S5+6@b@EnSFiADOx@2A@W3afJM4q?9zipE znAT&yN6{1?ZYXh?$J=D^7(OpU_8G^2O66g3ODWlTe-B{sLM9$5wY&(=msVbbXDrvc zL(O(v;nM-@cp08@fMbK>u|5^Bg%{&pGOLyCSn^%1=YjW1ihVlp^!Pz$t&MVACpo+u z8xKy3mh-^Zq?m8O+YYf#@K($#FqS-UQs#N!HHW$jRJsxOKFqN^2e&BHTlPu8kB)Hr z@%SA1^HCnmW2Y&6?r4*akK)Q>lA?CrfO*F{m6-6@cV8R9(ceCJrQ=o zz^vwh z%YKv;b?|=tL^kl;3KQxKtt&L4FyTydg=gVZr3HuwUV63*^M3rTl=Cs%D2=@F91~C~ zc?ZUy^jEWuA$(O*`2>Eq%00^S@mJ@%h)N9L?mscncpjcA8Aq7BxKgrs13o7yd=$5? zHoXApSwx`7D;#x~E-W6yK62 zK8>Z9Xc6zkuU~3^o`F>|z{l`!GQ$^fr^~GSJQJ787+)SI9d)|;NG-tkB;pHLe7Ui= zQ(&zu@W3gV}a5*fVzD96{NK<`Fv8W#6gzm0r+^G@T+Co$odzF6Q%xR*5Y zCVW83cqe{*msavceEn_};tRO_J$j2T$MdCx_v3;T@sxX2PI8X1{^yY*S#F~Q?~{Dq zjR$tP6?qf3O9l_@mMlJu~Dv#lEspf&FOEK@nd8y}tzq{Y~H`R;LX^y)`gE%32b~QDQe(>AFOk0*=H7Od-RI(z^7%1595}-D#%l?Sw?u^ z*ZaKt@zVZyQglIoQnctqHF%@cgq`p~N#VnR4;v2qG~iv5q`V#1OC2A?*CdT^zz?Ov z{&TqHuYB>si|`hiwoeNl{)js+Zlj2NDTT!*#ekDaEg!@?9@X`{4KIDnWo$1a9$^UgRlwj->D^j6deDG#i6>`P1I^#LVR4RjJU>d>G%A zS{|D+^ChXo%*T~7s(b=}^R~BIK8715#Xhljte(@(&pYv~jV54;^}mYjFk`ZKAswHS zVqWyVu97q!*zkdg!vjYo{bX+{c*(5E#q01M$>Gu8oLsVa4ZbR=eB$qV`D5=HC+TS{ zkI(Bm8|9e&iA9D7?)6VA6wkp6q=VPs<1(xgL%8l!E#}>L(t@uGcqy)x`cRHbKC^=I zBs^7Gc{z?q2agB2>0c^gqXplPloQny&-`5Lc_l7N4i79{G<$hq>LwGG2VNspyb<4* zIzEe)U#J8Rd{Nr@7_Ruz_z&AC`_eZSqU5NH7h#V~@P5o%;(2mBaGfmjZrnd1+3yOt zBQP#GyaAt*W>SZ&`Lgm zqdRIP4@^x@j%Ildo+x&DlggH0W!*~@jA(~Pe0B`3NPKmCkO1Q=R$?>Jz3;)n3|m&jq||dZzV@b z_K(HMCdsmqvX>S}4zI^;eGEYn&%}eIfal`_GT}sn_?ZmzMQq7296WHpee?v+#dF02 z-lA%}S=xCAz9RA13U4+fd0#c;wRlJHGUb@JpK(!yFsbumx>&yC=4`+9<&bCHpjA9^twg7gwHgVRH1Q#^bIr zp?C?FHo5>0{K3yvf>&VCwR*_0f&X!x;o!^hOewWbElx{0k2QH5>-AWKe z!Tl=DJQsf?t-Jy^NjopSG1>3ySTug%O$FbUG(L?t+@wqG(~P^^Vlm>`c(}~-ZoIk0 zn$O$t5n1E|82{2=BQ~O2wMII53AV`q@4%r}7yF^r5MPmY7v6yHNhhDhCBN_;U%>b(=TY8(zq`{4$j7nsE)(zv*8d=D+jWx{x^YHod0_h877ZSlFIl`FWB1y} z1p(a3|@`xt4%sSh_A~8 zpTIlUm=ixT1bF^~dWE;)*Sg#_JOjVJ)>;xAH%UE@9x`Oo!l&_ub(Uw|94G(Ttr9kt zW50Crz?>dK!)vju*Tmt0`F$o=D96uanlIve{U#%y#djVy1QjlZAN)#B@pGni4~9Q z2_AU=lkOVV>cp=+t+#pV)9(Kt*vPX{gZJ%3JZWUmGf3 zhqwPmr9(OPJ!^*Z?2+W?cuD)QNsX6E25-T&&zYEK#7#Q#-1BY^2h8DTqq^Qsi@5i1 z)tcvE{+J5!z~f)iy=OWpF8)r%!~WPk?gGjuUkQ&`b_|bRO^yzf+HfphDpPzMzaD>0 zSJ=qFvt^vu;B8Xq;8yICEaih3-(b1r4S3Y=jW=({4U%5zw#0u)D$jV`Tl0j9@;dxP z2Ay*OoBrVTCP_N73i}Vqc$GHTcnt` zVDdYbYZp%YizQhKdF!W{k#ZEzVMdH1K*L#;9pv9mn@A&c?&L0TpBI#Ts&J+&Q^|jNgkA}Jg`gBln16J zFO3R#VEj>kP1qR3pD*=cYP<=*xy)y3@lss2)zYYi$M9nr;`7**;sQJ{b?c>3bdHna zb&|%LaM!Q+zz6$e;i0KZqhel&9(*4SoMZhDa*K31pamb64SWEv+HPr7${R6b`=wC> zFT|!DmPQpku<@%)qh`JVuikNKG|9VhMfy@-F_xhvDGm_@OL6&t$}3 z?y2W^J1);wQ64xgRXni#TgE@fMv&K~m``BIUb>41z9UC*!zvq>A z^G>`XR}WQdC7$*ldW@Ij3)1KUqqx84uXpq1I3)9q4Loswm9T#)o*4I_^$m6^#go6S z1$HXMZ4NL2?UahYmu#N*9kW{M?O%qMNiA=~9r8Ty+CJ%cvsCdGykF{gCm#P@cMvbZ zA4?05SCWUN&BhR3;tA^=ybf=WdESgWd%Ai*&%`?<@24(|PfISJ#QpMBlo#MBvS|M@ zeC1&4gYpe{*Y~uZw`0>G#=qVMiRuar0T29#%<_4>=};%)EqKUbhJzR2#Zt>#@i9p` z-<^V=NE%V+!2T*`S9PDn8i{KnN54W5A)T;u(M*WgZ#?r)xnFUc$)$M61pX*A69 zakWhG2`szTEy@Gq*Q!aajRqU{NrGy?k%iAo*+njl=iO{Lcr~uS#rr)U#654- z8lH{6mJB|ERks=Yi!}yEBnssiyWJhc1IHwV2fo{?2VxGG|ApCmhuV3e5;v~0qYA~^ zmPWhC5YNQ#$OtdOF6rihzmsM@j>&iGULM1}rJd*D52ce=;4h?=x83RfKjoKZuS%5R z`*&+SpT$e=SsE4b7VMXL9=IrtJh1p)7v`xQOQR=OTg3Pfekz@O0n^v0XxJZ*f6!gP z)4LoiLl;~BTghJQw9E?ySR#HLE^5IYyLBH=$7dvi5997V-d1@wzAgED8n@~*S9l5@ z((fX?2B)N%M-Lk!8R3BiaesB$D8LFC;(`B^e!hU|zp^CrzyWCu<@nwshKbMO#{*_Q z&wkX3x!y6C=w5tA^7$}6|AY$hQT$kz^Y}dZ=9BJM8(Fv@g*#@Db_Y z1NfY@@$jK4mrFmd$2X*l=l*7Cv{DB75N?!d9zE;b?^)wNXQR@_oGgSFMwUk39yJ7) z^8a!xN{mn8Q7@_}ufQM6LW=Ii@WG(tTg5hW4Nq4dI3%;%xG=sdS*fwj+{DLrh(()T zbpL1n)&;(*>##s-dElus$pbHv*p9KyyoqnvE9S!%wJ?MSJ}dP+@GU9ffuBhh4@?`= zu)V#H;Jz{#-zTd)4Y%}wC2@i~);IBp-f#=F}QEW4B;3-GPd?cA$N%DB$(=uqE!0@?i zxjb-A(vI>zf?NE~ox%fmlMRjyERd9A^e&z%CC6I-gIpv7$Ld~uTq=uWn;E@q;_<+f zWta!9ky#%2lyn{!+srq3)$uBX;d8!bPEa8XpW{`2vd{R!@OfNKJn-OgJHG08 z--Zb+lS&?Vk;L=;Yd6S^(%|3jft`})-)VtQNR5AB1ddBP4}4!5eU%)T_?ofgfqO~@ z4-B6QG-Ln3@X0@&zPJs%NMY4YwDxL$^N;JB3V!0>T63*NN? z!w1^Td%p-gQCciq;lpYgWb%^Os{hDc_I5n{n>~CpAbg`Bd~;#E-cO@Q?!EqtRl<+n zESK=3Hu)X?v-nTGqw$JgNR;sZdg1^1!vEQX|HJ9DPxwb^_{VAZue9)AYsJdKkM4y3 zd<_3d8Gd{x{EScdAq0tUmhdRO@Cd!|zt;br@IO-F+hgI|V*kz2=Y6|G{+r=Ptir$l z!@v8(zuEu$pWea4zhWDF2RnSl6aK9b-fF`;-Iks^yS1c7tG<|seKk3F<*IG}5Zivq ziK}-1L+tHUU-@I~wL?$bB8r7w|KC4(r*9E?#M1x#nJC{PO7i=E|NUp`hg(Fa{o8iI z8SB6KX6(<~#iy*TcIsa}xO#N;)aselbE_9tM{8nhGS_6U$z7AT#*3-TqETpA)3l~# z&G4GhHREe0*5vl&^%V3J^_28f^i=iK^wjk<^fdLf^tAPK^mO&~_YC$7_l)+8_e}Im z_006l^(^#6y|LcZ-t^wg-t6Ao-n`y|-lE=kNpD$iMQ>GaO>bRqLvK@WOK)3mM{iee zfA3)LaPMgEc<)5-RPRjhT<=1!pReyr?Mv^=?91-U?aS*c=qu_g=_~82=&S0h>8tB& z=xge0>1*rj=YM4C>s#oHGM8=s%ykdNqo|{#W7XnEv2X4&_&+V2S~C+`pSvt-g6y>gYs=QQth)Wf*sc{N>nhgOtgBns zu&!xc%euC89qYQ*4XztrH@a?o-Nd@7bu;Vc*2TKhyED79yK}qqx~IBly63tVx}%<0 zPijwkPi9Yc&;NE{+5dE*XQglcZ0}VQAH|N`=KrqB+^T)%Vn=^Hvn#tRw=1u!psT2> zq^qn;)k>B{>BfFl%UrBz)$B*H)Y$miiM3N}XV$KonTuVqs(aq&5}x;WA8|R!+-U!2 zJXdx6J@)IQnq^Vy`m;WcB`!&gb)`FbUY94cM-5K6{?dQME?Z(TZdn$UuloCZ?1a>c z`)lrRxZgGVmqkUe>iAD$-;S?cSQ~pNeO=}{CBw_26iDs!*W9wrlPg*qTbsHzeQoC2 z?6tXT^K@j<+OF>5?$K`hwD_7F@;d4|y6#JTpzMLV2ihJOd|={%SZ8Kuc4uy9RcB3S zLuXTG>gx2>RSz~i)bvoxLv0UrJk<42|3iZh4L>yc(5iPnjBWShigi{0pD`IV8Z+w_ yHjhQNaVY98+dLLw9KskBn7|dLZ-c4Z@&7YzBa^kj{A@BG$9vbGI2&tP^8WxwV?jCq diff --git a/Lib/distutils/command/wininst-14.0.exe b/Lib/distutils/command/wininst-14.0.exe index 0dac1103d98db0af1e9027c41fe921136c5f6396..46f5f356676c800f99742deb6bf4c0a96aa166c0 100644 GIT binary patch delta 106589 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 z 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 maxsize) + # Use the cache_len bound method instead of the len() function + # which could potentially be wrapped in an lru_cache itself. + full = (cache_len() >= maxsize) misses += 1 return result def cache_info(): """Report cache statistics""" with lock: - return _CacheInfo(hits, misses, maxsize, len(cache)) + return _CacheInfo(hits, misses, maxsize, cache_len()) def cache_clear(): """Clear the cache and cache statistics""" diff --git a/Lib/getpass.py b/Lib/getpass.py index be51121..36e17e4 100644 --- a/Lib/getpass.py +++ b/Lib/getpass.py @@ -7,7 +7,6 @@ GetPassWarning - This UserWarning is issued when getpass() cannot prevent echoing of the password contents while reading. On Windows, the msvcrt module will be used. -On the Mac EasyDialogs.AskPassword is used, if available. """ diff --git a/Lib/idlelib/colorizer.py b/Lib/idlelib/colorizer.py index 7310bb2..ff40845 100644 --- a/Lib/idlelib/colorizer.py +++ b/Lib/idlelib/colorizer.py @@ -21,7 +21,7 @@ def make_pat(): # 1st 'file' colorized normal, 2nd as builtin, 3rd as string builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b" comment = any("COMMENT", [r"#[^\n]*"]) - stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR|rb|rB|Rb|RB)?" + stringprefix = r"(?i:\br|u|f|fr|rf|b|br|rb)?" sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?" dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?' sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" @@ -261,8 +261,15 @@ def _color_delegator(parent): # htest # top = Toplevel(parent) top.title("Test ColorDelegator") x, y = map(int, parent.geometry().split('+')[1:]) - top.geometry("200x100+%d+%d" % (x + 250, y + 175)) - source = "if somename: x = 'abc' # comment\nprint\n" + top.geometry("700x250+%d+%d" % (x + 20, y + 175)) + source = ("# Following has syntax errors\n" + "if True: then int 1\nelif False: print 0\nelse: float(None)\n" + "if iF + If + IF: 'keywork matching must respect case'\n" + "# All valid prefixes for unicode and byte strings should be colored\n" + "'x', '''x''', \"x\", \"\"\"x\"\"\"\n" + "r'x', u'x', R'x', U'x', f'x', F'x', ur'is invalid'\n" + "fr'x', Fr'x', fR'x', FR'x', rf'x', rF'x', Rf'x', RF'x'\n" + "b'x',B'x', br'x',Br'x',bR'x',BR'x', rb'x'.rB'x',Rb'x',RB'x'\n") text = Text(top, background="white") text.pack(expand=1, fill="both") text.insert("insert", source) diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index ffc03c4..f10cd34 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -90,7 +90,7 @@

25.5. IDLE¶

-

Source code: Lib/idlelib/

+

Source code: Lib/idlelib/


IDLE is Python’s Integrated Development and Learning Environment.

IDLE has the following features:

diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index e1eade1..f3ee391 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -5,15 +5,15 @@ try: except ImportError: print("** IDLE can't import Tkinter.\n" "Your Python may not be configured for Tk. **", file=sys.__stderr__) - sys.exit(1) + raise SystemExit(1) import tkinter.messagebox as tkMessageBox if TkVersion < 8.5: root = Tk() # otherwise create root in main root.withdraw() tkMessageBox.showerror("Idle Cannot Start", - "Idle requires tcl/tk 8.5+, not $s." % TkVersion, + "Idle requires tcl/tk 8.5+, not %s." % TkVersion, parent=root) - sys.exit(1) + raise SystemExit(1) from code import InteractiveInterpreter import getopt diff --git a/Lib/imaplib.py b/Lib/imaplib.py index cad508a..2fa9012 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -419,7 +419,7 @@ class IMAP4: self.literal = _Authenticator(authobject).process typ, dat = self._simple_command('AUTHENTICATE', mech) if typ != 'OK': - raise self.error(dat[-1]) + raise self.error(dat[-1].decode('utf-8', 'replace')) self.state = 'AUTH' return typ, dat diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index ab43446..9feec50 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1440,6 +1440,4 @@ def _install(_bootstrap_module): _setup(_bootstrap_module) supported_loaders = _get_supported_file_loaders() sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) - if _os.__name__ == 'nt': - sys.meta_path.append(WindowsRegistryFinder) sys.meta_path.append(PathFinder) diff --git a/Lib/inspect.py b/Lib/inspect.py index e08e9f5..4d56ef5 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1416,7 +1416,6 @@ def getframeinfo(frame, context=1): except OSError: lines = index = None else: - start = max(start, 1) start = max(0, min(start, len(lines) - context)) lines = lines[start:start+context] index = lineno - 1 - start diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 2590d65..b44a3b2 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -131,9 +131,14 @@ def getLevelName(level): Otherwise, the string "Level %s" % level is returned. """ - # See Issues #22386 and #27937 for why it's this way - return (_levelToName.get(level) or _nameToLevel.get(level) or - "Level %s" % level) + # See Issues #22386, #27937 and #29220 for why it's this way + result = _levelToName.get(level) + if result is not None: + return result + result = _nameToLevel.get(level) + if result is not None: + return result + return "Level %s" % level def addLevelName(level, levelName): """ diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 0e23987..39f24f9 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -313,11 +313,12 @@ class Maildir(Mailbox): # final position in order to prevent race conditions with changes # from other programs try: - if hasattr(os, 'link'): + try: os.link(tmp_file.name, dest) - os.remove(tmp_file.name) - else: + except (AttributeError, PermissionError): os.rename(tmp_file.name, dest) + else: + os.remove(tmp_file.name) except OSError as e: os.remove(tmp_file.name) if e.errno == errno.EEXIST: @@ -1200,13 +1201,14 @@ class MH(Mailbox): for key in self.iterkeys(): if key - 1 != prev: changes.append((key, prev + 1)) - if hasattr(os, 'link'): + try: os.link(os.path.join(self._path, str(key)), os.path.join(self._path, str(prev + 1))) - os.unlink(os.path.join(self._path, str(key))) - else: + except (AttributeError, PermissionError): os.rename(os.path.join(self._path, str(key)), os.path.join(self._path, str(prev + 1))) + else: + os.unlink(os.path.join(self._path, str(key))) prev += 1 self._next_key = prev + 1 if len(changes) == 0: @@ -2076,13 +2078,14 @@ def _lock_file(f, dotlock=True): else: raise try: - if hasattr(os, 'link'): + try: os.link(pre_lock.name, f.name + '.lock') dotlock_done = True - os.unlink(pre_lock.name) - else: + except (AttributeError, PermissionError): os.rename(pre_lock.name, f.name + '.lock') dotlock_done = True + else: + os.unlink(pre_lock.name) except FileExistsError: os.remove(pre_lock.name) raise ExternalClashError('dot lock unavailable: %s' % diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index 09455e2..623f6fb 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -196,7 +196,7 @@ class BaseContext(object): def get_start_method(self, allow_none=False): return self._name - def set_start_method(self, method=None): + def set_start_method(self, method, force=False): raise ValueError('cannot set start method of concrete context') @property diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index dfb9f65..4aba372 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -217,7 +217,7 @@ def prepare(data): process.ORIGINAL_DIR = data['orig_dir'] if 'start_method' in data: - set_start_method(data['start_method']) + set_start_method(data['start_method'], force=True) if 'init_main_from_name' in data: _fixup_main_from_name(data['init_main_from_name']) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 6965393..9f34721 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -192,7 +192,9 @@ class _WindowsFlavour(_Flavour): s = self._ext_to_normal(_getfinalpathname(s)) except FileNotFoundError: previous_s = s - s = os.path.abspath(os.path.join(s, os.pardir)) + s = os.path.dirname(s) + if previous_s == s: + return path else: if previous_s is None: return s @@ -1233,7 +1235,7 @@ class Path(PurePath): if not exist_ok or not self.is_dir(): raise except OSError as e: - if e.errno != ENOENT: + if e.errno != ENOENT or self.parent == self: raise self.parent.mkdir(parents=True) self._accessor.mkdir(self, mode) diff --git a/Lib/platform.py b/Lib/platform.py index e48ad0b..cc2db98 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -110,7 +110,7 @@ __copyright__ = """ """ -__version__ = '1.0.7' +__version__ = '1.0.8' import collections import sys, os, re, subprocess @@ -1198,7 +1198,9 @@ def _sys_version(sys_version=None): elif buildtime: builddate = builddate + ' ' + buildtime - if hasattr(sys, '_mercurial'): + if hasattr(sys, '_git'): + _, branch, revision = sys._git + elif hasattr(sys, '_mercurial'): _, branch, revision = sys._mercurial elif hasattr(sys, 'subversion'): # sys.subversion was added in Python 2.5 diff --git a/Lib/pstats.py b/Lib/pstats.py index d861413..2c5bf98 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -48,11 +48,14 @@ class Stats: printed. The sort_stats() method now processes some additional options (i.e., in - addition to the old -1, 0, 1, or 2). It takes an arbitrary number of - quoted strings to select the sort order. For example sort_stats('time', - 'name') sorts on the major key of 'internal function time', and on the - minor key of 'the name of the function'. Look at the two tables in - sort_stats() and get_sort_arg_defs(self) for more examples. + addition to the old -1, 0, 1, or 2 that are respectively interpreted as + 'stdname', 'calls', 'time', and 'cumulative'). It takes an arbitrary number + of quoted strings to select the sort order. + + For example sort_stats('time', 'name') sorts on the major key of 'internal + function time', and on the minor key of 'the name of the function'. Look at + the two tables in sort_stats() and get_sort_arg_defs(self) for more + examples. All methods return self, so you can string together commands like: Stats('foo', 'goo').strip_dirs().sort_stats('calls').\ diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index ad3fa25..2caab63 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Fri Dec 16 16:33:16 2016 -topics = {'assert': '\n' - 'The "assert" statement\n' +# Autogenerated by Sphinx on Sat Mar 4 12:14:44 2017 +topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' 'Assert statements are a convenient way to insert debugging ' @@ -39,8 +38,7 @@ topics = {'assert': '\n' 'Assignments to "__debug__" are illegal. The value for the ' 'built-in\n' 'variable is determined when the interpreter starts.\n', - 'assignment': '\n' - 'Assignment statements\n' + 'assignment': 'Assignment statements\n' '*********************\n' '\n' 'Assignment statements are used to (re)bind names to values and ' @@ -405,8 +403,7 @@ topics = {'assert': '\n' 'See also: **PEP 526** - Variable and attribute annotation ' 'syntax\n' ' **PEP 484** - Type hints\n', - 'atom-identifiers': '\n' - 'Identifiers (Names)\n' + 'atom-identifiers': 'Identifiers (Names)\n' '*******************\n' '\n' 'An identifier occurring as an atom is a name. See ' @@ -446,8 +443,7 @@ topics = {'assert': '\n' 'happen. If the class name consists only of underscores, ' 'no\n' 'transformation is done.\n', - 'atom-literals': '\n' - 'Literals\n' + 'atom-literals': 'Literals\n' '********\n' '\n' 'Python supports string and bytes literals and various ' @@ -476,8 +472,7 @@ topics = {'assert': '\n' 'may obtain\n' 'the same object or a different object with the same ' 'value.\n', - 'attribute-access': '\n' - 'Customizing attribute access\n' + 'attribute-access': 'Customizing attribute access\n' '****************************\n' '\n' 'The following methods can be defined to customize the ' @@ -851,8 +846,7 @@ topics = {'assert': '\n' '* *__class__* assignment works only if both classes have ' 'the same\n' ' *__slots__*.\n', - 'attribute-references': '\n' - 'Attribute references\n' + 'attribute-references': 'Attribute references\n' '********************\n' '\n' 'An attribute reference is a primary followed by a ' @@ -875,8 +869,7 @@ topics = {'assert': '\n' 'determined by the object. Multiple evaluations of ' 'the same attribute\n' 'reference may yield different objects.\n', - 'augassign': '\n' - 'Augmented assignment statements\n' + 'augassign': 'Augmented assignment statements\n' '*******************************\n' '\n' 'Augmented assignment is the combination, in a single statement, ' @@ -940,8 +933,7 @@ topics = {'assert': '\n' 'about\n' 'class and instance attributes applies as for regular ' 'assignments.\n', - 'binary': '\n' - 'Binary arithmetic operations\n' + 'binary': 'Binary arithmetic operations\n' '****************************\n' '\n' 'The binary arithmetic operations have the conventional priority\n' @@ -1029,8 +1021,7 @@ topics = {'assert': '\n' 'The "-" (subtraction) operator yields the difference of its ' 'arguments.\n' 'The numeric arguments are first converted to a common type.\n', - 'bitwise': '\n' - 'Binary bitwise operations\n' + 'bitwise': 'Binary bitwise operations\n' '*************************\n' '\n' 'Each of the three bitwise operations has a different priority ' @@ -1050,8 +1041,7 @@ topics = {'assert': '\n' 'The "|" operator yields the bitwise (inclusive) OR of its ' 'arguments,\n' 'which must be integers.\n', - 'bltin-code-objects': '\n' - 'Code Objects\n' + 'bltin-code-objects': 'Code Objects\n' '************\n' '\n' 'Code objects are used by the implementation to ' @@ -1074,8 +1064,7 @@ topics = {'assert': '\n' '\n' 'See The standard type hierarchy for more ' 'information.\n', - 'bltin-ellipsis-object': '\n' - 'The Ellipsis Object\n' + 'bltin-ellipsis-object': 'The Ellipsis Object\n' '*******************\n' '\n' 'This object is commonly used by slicing (see ' @@ -1087,8 +1076,7 @@ topics = {'assert': '\n' '"Ellipsis" singleton.\n' '\n' 'It is written as "Ellipsis" or "...".\n', - 'bltin-null-object': '\n' - 'The Null Object\n' + 'bltin-null-object': 'The Null Object\n' '***************\n' '\n' "This object is returned by functions that don't " @@ -1100,8 +1088,7 @@ topics = {'assert': '\n' 'same singleton.\n' '\n' 'It is written as "None".\n', - 'bltin-type-objects': '\n' - 'Type Objects\n' + 'bltin-type-objects': 'Type Objects\n' '************\n' '\n' 'Type objects represent the various object types. An ' @@ -1113,8 +1100,7 @@ topics = {'assert': '\n' 'all standard built-in types.\n' '\n' 'Types are written like this: "".\n', - 'booleans': '\n' - 'Boolean operations\n' + 'booleans': 'Boolean operations\n' '******************\n' '\n' ' or_test ::= and_test | or_test "or" and_test\n' @@ -1163,8 +1149,7 @@ topics = {'assert': '\n' 'its\n' 'argument (for example, "not \'foo\'" produces "False" rather ' 'than "\'\'".)\n', - 'break': '\n' - 'The "break" statement\n' + 'break': 'The "break" statement\n' '*********************\n' '\n' ' break_stmt ::= "break"\n' @@ -1185,8 +1170,7 @@ topics = {'assert': '\n' 'clause, that "finally" clause is executed before really leaving ' 'the\n' 'loop.\n', - 'callable-types': '\n' - 'Emulating callable objects\n' + 'callable-types': 'Emulating callable objects\n' '**************************\n' '\n' 'object.__call__(self[, args...])\n' @@ -1195,8 +1179,7 @@ topics = {'assert': '\n' 'this method\n' ' is defined, "x(arg1, arg2, ...)" is a shorthand for\n' ' "x.__call__(arg1, arg2, ...)".\n', - 'calls': '\n' - 'Calls\n' + 'calls': 'Calls\n' '*****\n' '\n' 'A call calls a callable object (e.g., a *function*) with a ' @@ -1217,7 +1200,8 @@ topics = {'assert': '\n' ' ("," "*" expression | "," ' 'keyword_item)*\n' ' keywords_arguments ::= (keyword_item | "**" expression)\n' - ' ("," keyword_item | "**" expression)*\n' + ' ("," keyword_item | "," "**" ' + 'expression)*\n' ' keyword_item ::= identifier "=" expression\n' '\n' 'An optional trailing comma may be present after the positional and\n' @@ -1382,8 +1366,7 @@ topics = {'assert': '\n' ' The class must define a "__call__()" method; the effect is then ' 'the\n' ' same as if that method was called.\n', - 'class': '\n' - 'Class definitions\n' + 'class': 'Class definitions\n' '*****************\n' '\n' 'A class definition defines a class object (see section The ' @@ -1469,8 +1452,7 @@ topics = {'assert': '\n' '\n' 'See also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n' ' Class Decorators\n', - 'comparisons': '\n' - 'Comparisons\n' + 'comparisons': 'Comparisons\n' '***********\n' '\n' 'Unlike C, all comparison operations in Python have the same ' @@ -1623,7 +1605,7 @@ topics = {'assert': '\n' 'restriction that\n' ' ranges do not support order comparison. Equality ' 'comparison across\n' - ' these types results in unequality, and ordering comparison ' + ' these types results in inequality, and ordering comparison ' 'across\n' ' these types raises "TypeError".\n' '\n' @@ -1762,6 +1744,12 @@ topics = {'assert': '\n' ' to sequences, but not to sets or mappings). See also the\n' ' "total_ordering()" decorator.\n' '\n' + '* The "hash()" result should be consistent with equality. ' + 'Objects\n' + ' that are equal should either have the same hash value, or ' + 'be marked\n' + ' as unhashable.\n' + '\n' 'Python does not enforce these consistency rules. In fact, ' 'the\n' 'not-a-number values are an example for not following these ' @@ -1833,8 +1821,7 @@ topics = {'assert': '\n' 'is determined using the "id()" function. "x is not y" yields ' 'the\n' 'inverse truth value. [4]\n', - 'compound': '\n' - 'Compound statements\n' + 'compound': 'Compound statements\n' '*******************\n' '\n' 'Compound statements contain (groups of) other statements; they ' @@ -2725,8 +2712,7 @@ topics = {'assert': '\n' ' body is transformed into the namespace\'s "__doc__" item ' 'and\n' " therefore the class's *docstring*.\n", - 'context-managers': '\n' - 'With Statement Context Managers\n' + 'context-managers': 'With Statement Context Managers\n' '*******************************\n' '\n' 'A *context manager* is an object that defines the ' @@ -2788,8 +2774,7 @@ topics = {'assert': '\n' ' The specification, background, and examples for the ' 'Python "with"\n' ' statement.\n', - 'continue': '\n' - 'The "continue" statement\n' + 'continue': 'The "continue" statement\n' '************************\n' '\n' ' continue_stmt ::= "continue"\n' @@ -2806,8 +2791,7 @@ topics = {'assert': '\n' '"finally" clause, that "finally" clause is executed before ' 'really\n' 'starting the next loop cycle.\n', - 'conversions': '\n' - 'Arithmetic conversions\n' + 'conversions': 'Arithmetic conversions\n' '**********************\n' '\n' 'When a description of an arithmetic operator below uses the ' @@ -2833,8 +2817,7 @@ topics = {'assert': '\n' "left argument to the '%' operator). Extensions must define " 'their own\n' 'conversion behavior.\n', - 'customization': '\n' - 'Basic customization\n' + 'customization': 'Basic customization\n' '*******************\n' '\n' 'object.__new__(cls[, ...])\n' @@ -3153,15 +3136,18 @@ topics = {'assert': '\n' 'on members\n' ' of hashed collections including "set", "frozenset", and ' '"dict".\n' - ' "__hash__()" should return an integer. The only ' - 'required property\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' + ' advised to mix together the hash values of the ' + 'components of the\n' + ' object that also play a part in comparison of objects by ' + 'packing\n' + ' them into a tuple and hashing the tuple. Example:\n' + '\n' + ' def __hash__(self):\n' + ' return hash((self.name, self.nick, self.color))\n' '\n' ' Note: "hash()" truncates the value returned from an ' "object's\n" @@ -3273,8 +3259,7 @@ topics = {'assert': '\n' ' neither "__len__()" nor "__bool__()", all its instances ' 'are\n' ' considered true.\n', - 'debugger': '\n' - '"pdb" --- The Python Debugger\n' + 'debugger': '"pdb" --- The Python Debugger\n' '*****************************\n' '\n' '**Source code:** Lib/pdb.py\n' @@ -3939,8 +3924,7 @@ topics = {'assert': '\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': '\n' - 'The "del" statement\n' + 'del': 'The "del" statement\n' '*******************\n' '\n' ' del_stmt ::= "del" target_list\n' @@ -3969,8 +3953,7 @@ topics = {'assert': '\n' 'Changed in version 3.2: Previously it was illegal to delete a name\n' 'from the local namespace if it occurs as a free variable in a nested\n' 'block.\n', - 'dict': '\n' - 'Dictionary displays\n' + 'dict': 'Dictionary displays\n' '*******************\n' '\n' 'A dictionary display is a possibly empty series of key/datum pairs\n' @@ -4014,8 +3997,7 @@ topics = {'assert': '\n' 'should be *hashable*, which excludes all mutable objects.) Clashes\n' 'between duplicate keys are not detected; the last datum (textually\n' 'rightmost in the display) stored for a given key value prevails.\n', - 'dynamic-features': '\n' - 'Interaction with dynamic features\n' + 'dynamic-features': 'Interaction with dynamic features\n' '*********************************\n' '\n' 'Name resolution of free variables occurs at runtime, not ' @@ -4051,8 +4033,7 @@ topics = {'assert': '\n' 'override the global and local namespace. If only one ' 'namespace is\n' 'specified, it is used for both.\n', - 'else': '\n' - 'The "if" statement\n' + 'else': 'The "if" statement\n' '******************\n' '\n' 'The "if" statement is used for conditional execution:\n' @@ -4069,8 +4050,7 @@ topics = {'assert': '\n' '(and no other part of the "if" statement is executed or evaluated).\n' 'If all expressions are false, the suite of the "else" clause, if\n' 'present, is executed.\n', - 'exceptions': '\n' - 'Exceptions\n' + 'exceptions': 'Exceptions\n' '**********\n' '\n' 'Exceptions are a means of breaking out of the normal flow of ' @@ -4146,8 +4126,7 @@ topics = {'assert': '\n' ' these operations is not available at the time the module ' 'is\n' ' compiled.\n', - 'execmodel': '\n' - 'Execution model\n' + 'execmodel': 'Execution model\n' '***************\n' '\n' '\n' @@ -4478,8 +4457,7 @@ topics = {'assert': '\n' ' these operations is not available at the time the module ' 'is\n' ' compiled.\n', - 'exprlists': '\n' - 'Expression lists\n' + 'exprlists': 'Expression lists\n' '****************\n' '\n' ' expression_list ::= expression ( "," expression )* [","]\n' @@ -4516,8 +4494,7 @@ topics = {'assert': '\n' 'value of that expression. (To create an empty tuple, use an ' 'empty pair\n' 'of parentheses: "()".)\n', - 'floating': '\n' - 'Floating point literals\n' + 'floating': 'Floating point literals\n' '***********************\n' '\n' 'Floating point literals are described by the following lexical\n' @@ -4553,8 +4530,7 @@ topics = {'assert': '\n' 'Changed in version 3.6: Underscores are now allowed for ' 'grouping\n' 'purposes in literals.\n', - 'for': '\n' - 'The "for" statement\n' + 'for': 'The "for" statement\n' '*******************\n' '\n' 'The "for" statement is used to iterate over the elements of a ' @@ -4626,8 +4602,7 @@ topics = {'assert': '\n' '\n' ' for x in a[:]:\n' ' if x < 0: a.remove(x)\n', - 'formatstrings': '\n' - 'Format String Syntax\n' + 'formatstrings': 'Format String Syntax\n' '********************\n' '\n' 'The "str.format()" method and the "Formatter" class share ' @@ -5346,8 +5321,7 @@ topics = {'assert': '\n' ' 9 9 11 1001\n' ' 10 A 12 1010\n' ' 11 B 13 1011\n', - 'function': '\n' - 'Function definitions\n' + 'function': 'Function definitions\n' '********************\n' '\n' 'A function definition defines a user-defined function object ' @@ -5516,8 +5490,7 @@ topics = {'assert': '\n' '\n' ' **PEP 3107** - Function Annotations\n' ' The original specification for function annotations.\n', - 'global': '\n' - 'The "global" statement\n' + 'global': 'The "global" statement\n' '**********************\n' '\n' ' global_stmt ::= "global" identifier ("," identifier)*\n' @@ -5561,8 +5534,7 @@ topics = {'assert': '\n' 'code containing the function call. The same applies to the ' '"eval()"\n' 'and "compile()" functions.\n', - 'id-classes': '\n' - 'Reserved classes of identifiers\n' + 'id-classes': 'Reserved classes of identifiers\n' '*******************************\n' '\n' 'Certain classes of identifiers (besides keywords) have ' @@ -5610,8 +5582,7 @@ topics = {'assert': '\n' ' to help avoid name clashes between "private" attributes of ' 'base and\n' ' derived classes. See section Identifiers (Names).\n', - 'identifiers': '\n' - 'Identifiers and keywords\n' + 'identifiers': 'Identifiers and keywords\n' '************************\n' '\n' 'Identifiers (also referred to as *names*) are described by ' @@ -5759,8 +5730,7 @@ topics = {'assert': '\n' ' to help avoid name clashes between "private" attributes of ' 'base and\n' ' derived classes. See section Identifiers (Names).\n', - 'if': '\n' - 'The "if" statement\n' + 'if': 'The "if" statement\n' '******************\n' '\n' 'The "if" statement is used for conditional execution:\n' @@ -5776,8 +5746,7 @@ topics = {'assert': '\n' '(and no other part of the "if" statement is executed or evaluated).\n' 'If all expressions are false, the suite of the "else" clause, if\n' 'present, is executed.\n', - 'imaginary': '\n' - 'Imaginary literals\n' + 'imaginary': 'Imaginary literals\n' '******************\n' '\n' 'Imaginary literals are described by the following lexical ' @@ -5797,8 +5766,7 @@ topics = {'assert': '\n' '\n' ' 3.14j 10.j 10j .001j 1e100j 3.14e-10j ' '3.14_15_93j\n', - 'import': '\n' - 'The "import" statement\n' + 'import': 'The "import" statement\n' '**********************\n' '\n' ' import_stmt ::= "import" module ["as" name] ( "," module ' @@ -6059,8 +6027,7 @@ topics = {'assert': '\n' '\n' ' **PEP 236** - Back to the __future__\n' ' The original proposal for the __future__ mechanism.\n', - 'in': '\n' - 'Membership test operations\n' + 'in': 'Membership test operations\n' '**************************\n' '\n' 'The operators "in" and "not in" test for membership. "x in s"\n' @@ -6095,8 +6062,7 @@ topics = {'assert': '\n' '\n' 'The operator "not in" is defined to have the inverse true value of\n' '"in".\n', - 'integers': '\n' - 'Integer literals\n' + 'integers': 'Integer literals\n' '****************\n' '\n' 'Integer literals are described by the following lexical ' @@ -6142,8 +6108,7 @@ topics = {'assert': '\n' 'Changed in version 3.6: Underscores are now allowed for ' 'grouping\n' 'purposes in literals.\n', - 'lambda': '\n' - 'Lambdas\n' + 'lambda': 'Lambdas\n' '*******\n' '\n' ' lambda_expr ::= "lambda" [parameter_list]: expression\n' @@ -6166,8 +6131,7 @@ topics = {'assert': '\n' 'Note that functions created with lambda expressions cannot ' 'contain\n' 'statements or annotations.\n', - 'lists': '\n' - 'List displays\n' + 'lists': 'List displays\n' '*************\n' '\n' 'A list display is a possibly empty series of expressions enclosed ' @@ -6184,8 +6148,7 @@ topics = {'assert': '\n' 'from left to right and placed into the list object in that order.\n' 'When a comprehension is supplied, the list is constructed from the\n' 'elements resulting from the comprehension.\n', - 'naming': '\n' - 'Naming and binding\n' + 'naming': 'Naming and binding\n' '******************\n' '\n' '\n' @@ -6398,8 +6361,7 @@ topics = {'assert': '\n' 'override the global and local namespace. If only one namespace ' 'is\n' 'specified, it is used for both.\n', - 'nonlocal': '\n' - 'The "nonlocal" statement\n' + 'nonlocal': 'The "nonlocal" statement\n' '************************\n' '\n' ' nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n' @@ -6430,8 +6392,7 @@ topics = {'assert': '\n' '\n' ' **PEP 3104** - Access to Names in Outer Scopes\n' ' The specification for the "nonlocal" statement.\n', - 'numbers': '\n' - 'Numeric literals\n' + 'numbers': 'Numeric literals\n' '****************\n' '\n' 'There are three types of numeric literals: integers, floating ' @@ -6445,8 +6406,7 @@ topics = {'assert': '\n' 'is actually an expression composed of the unary operator \'"-"\' ' 'and the\n' 'literal "1".\n', - 'numeric-types': '\n' - 'Emulating numeric types\n' + 'numeric-types': 'Emulating numeric types\n' '***********************\n' '\n' 'The following methods can be defined to emulate numeric ' @@ -6622,8 +6582,7 @@ topics = {'assert': '\n' ' "__index__()" is defined "__int__()" should also be ' 'defined, and\n' ' both should return the same value.\n', - 'objects': '\n' - 'Objects, values and types\n' + 'objects': 'Objects, values and types\n' '*************************\n' '\n' "*Objects* are Python's abstraction for data. All data in a " @@ -6751,8 +6710,7 @@ topics = {'assert': '\n' 'created empty lists. (Note that "c = d = []" assigns the same ' 'object\n' 'to both "c" and "d".)\n', - 'operator-summary': '\n' - 'Operator precedence\n' + 'operator-summary': 'Operator precedence\n' '*******************\n' '\n' 'The following table summarizes the operator precedence ' @@ -6925,8 +6883,7 @@ topics = {'assert': '\n' 'arithmetic\n' ' or bitwise unary operator on its right, that is, ' '"2**-1" is "0.5".\n', - 'pass': '\n' - 'The "pass" statement\n' + 'pass': 'The "pass" statement\n' '********************\n' '\n' ' pass_stmt ::= "pass"\n' @@ -6939,8 +6896,7 @@ topics = {'assert': '\n' ' def f(arg): pass # a function that does nothing (yet)\n' '\n' ' class C: pass # a class with no methods (yet)\n', - 'power': '\n' - 'The power operator\n' + 'power': 'The power operator\n' '******************\n' '\n' 'The power operator binds more tightly than unary operators on its\n' @@ -6974,8 +6930,7 @@ topics = {'assert': '\n' 'Raising a negative number to a fractional power results in a ' '"complex"\n' 'number. (In earlier versions it raised a "ValueError".)\n', - 'raise': '\n' - 'The "raise" statement\n' + 'raise': 'The "raise" statement\n' '*********************\n' '\n' ' raise_stmt ::= "raise" [expression ["from" expression]]\n' @@ -7060,8 +7015,7 @@ topics = {'assert': '\n' 'Exceptions, and information about handling exceptions is in ' 'section\n' 'The try statement.\n', - 'return': '\n' - 'The "return" statement\n' + 'return': 'The "return" statement\n' '**********************\n' '\n' ' return_stmt ::= "return" [expression_list]\n' @@ -7096,8 +7050,7 @@ topics = {'assert': '\n' '"StopAsyncIteration" to be raised. A non-empty "return" statement ' 'is\n' 'a syntax error in an asynchronous generator function.\n', - 'sequence-types': '\n' - 'Emulating container types\n' + 'sequence-types': 'Emulating container types\n' '*************************\n' '\n' 'The following methods can be defined to implement ' @@ -7318,8 +7271,7 @@ topics = {'assert': '\n' ' iteration protocol via "__getitem__()", see this ' 'section in the\n' ' language reference.\n', - 'shifting': '\n' - 'Shifting operations\n' + 'shifting': 'Shifting operations\n' '*******************\n' '\n' 'The shifting operations have lower priority than the arithmetic\n' @@ -7343,8 +7295,7 @@ topics = {'assert': '\n' 'operand is\n' ' larger than "sys.maxsize" an "OverflowError" exception is ' 'raised.\n', - 'slicings': '\n' - 'Slicings\n' + 'slicings': 'Slicings\n' '********\n' '\n' 'A slicing selects a range of items in a sequence object (e.g., ' @@ -7395,8 +7346,7 @@ topics = {'assert': '\n' 'as lower bound, upper bound and stride, respectively, ' 'substituting\n' '"None" for missing expressions.\n', - 'specialattrs': '\n' - 'Special Attributes\n' + 'specialattrs': 'Special Attributes\n' '******************\n' '\n' 'The implementation adds a few special read-only attributes ' @@ -7481,8 +7431,7 @@ topics = {'assert': '\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': '\n' - 'Special method names\n' + 'specialnames': 'Special method names\n' '********************\n' '\n' 'A class can implement certain operations that are invoked by ' @@ -7843,15 +7792,18 @@ topics = {'assert': '\n' 'on members\n' ' of hashed collections including "set", "frozenset", and ' '"dict".\n' - ' "__hash__()" should return an integer. The only required ' + ' "__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' + ' advised to mix together the hash values of the components ' + 'of the\n' + ' object that also play a part in comparison of objects by ' + 'packing\n' + ' them into a tuple and hashing the tuple. Example:\n' + '\n' + ' def __hash__(self):\n' + ' return hash((self.name, self.nick, self.color))\n' '\n' ' Note: "hash()" truncates the value returned from an ' "object's\n" @@ -9270,8 +9222,7 @@ topics = {'assert': '\n' 'special method *must* be set on the class object itself in ' 'order to be\n' 'consistently invoked by the interpreter).\n', - 'string-methods': '\n' - 'String Methods\n' + 'string-methods': 'String Methods\n' '**************\n' '\n' 'Strings implement all of the common sequence operations, ' @@ -9508,12 +9459,11 @@ topics = {'assert': '\n' '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' + ' characters are those that can be used to form numbers ' + 'in base 10,\n' + ' e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a ' + 'decimal character\n' + ' is a character in the Unicode General Category "Nd".\n' '\n' 'str.isdigit()\n' '\n' @@ -9523,10 +9473,13 @@ topics = {'assert': '\n' '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' + ' compatibility superscript digits. This covers digits ' + 'which cannot\n' + ' be used to form numbers in base 10, like the Kharosthi ' + 'numbers.\n' + ' Formally, a digit is a character that has the property ' + 'value\n' + ' Numeric_Type=Digit or Numeric_Type=Decimal.\n' '\n' 'str.isidentifier()\n' '\n' @@ -10072,8 +10025,7 @@ topics = {'assert': '\n' " '00042'\n" ' >>> "-42".zfill(5)\n' " '-0042'\n", - 'strings': '\n' - 'String and Bytes literals\n' + 'strings': 'String and Bytes literals\n' '*************************\n' '\n' 'String literals are described by the following lexical ' @@ -10307,8 +10259,7 @@ topics = {'assert': '\n' 'followed by a newline is interpreted as those two characters as ' 'part\n' 'of the literal, *not* as a line continuation.\n', - 'subscriptions': '\n' - 'Subscriptions\n' + 'subscriptions': 'Subscriptions\n' '*************\n' '\n' 'A subscription selects an item of a sequence (string, tuple ' @@ -10365,8 +10316,7 @@ topics = {'assert': '\n' "A string's items are characters. A character is not a " 'separate data\n' 'type but a string of exactly one character.\n', - 'truth': '\n' - 'Truth Value Testing\n' + 'truth': 'Truth Value Testing\n' '*******************\n' '\n' 'Any object can be tested for truth value, for use in an "if" or\n' @@ -10398,8 +10348,7 @@ topics = {'assert': '\n' 'otherwise stated. (Important exception: the Boolean operations ' '"or"\n' 'and "and" always return one of their operands.)\n', - 'try': '\n' - 'The "try" statement\n' + 'try': 'The "try" statement\n' '*******************\n' '\n' 'The "try" statement specifies exception handlers and/or cleanup code\n' @@ -10546,8 +10495,7 @@ topics = {'assert': '\n' 'Exceptions, and information on using the "raise" statement to ' 'generate\n' 'exceptions may be found in section The raise statement.\n', - 'types': '\n' - 'The standard type hierarchy\n' + 'types': 'The standard type hierarchy\n' '***************************\n' '\n' 'Below is a list of the types that are built into Python. ' @@ -11262,14 +11210,14 @@ topics = {'assert': '\n' 'the\n' ' dictionary containing the class\'s namespace; "__bases__" is a ' 'tuple\n' - ' (possibly empty or a singleton) containing the base classes, in ' - 'the\n' - ' order of their occurrence in the base class list; "__doc__" is ' - 'the\n' - ' class\'s documentation string, or "None" if undefined;\n' - ' "__annotations__" (optional) is a dictionary containing ' - '*variable\n' - ' annotations* collected during class body execution.\n' + ' containing the base classes, in the order of their occurrence ' + 'in\n' + ' the base class list; "__doc__" is the class\'s documentation ' + 'string,\n' + ' or "None" if undefined; "__annotations__" (optional) is a\n' + ' dictionary containing *variable annotations* collected during ' + 'class\n' + ' body execution.\n' '\n' 'Class instances\n' ' A class instance is created by calling a class object (see ' @@ -11549,8 +11497,7 @@ topics = {'assert': '\n' ' under "User-defined methods". Class method objects are ' 'created\n' ' by the built-in "classmethod()" constructor.\n', - 'typesfunctions': '\n' - 'Functions\n' + 'typesfunctions': 'Functions\n' '*********\n' '\n' 'Function objects are created by function definitions. The ' @@ -11567,8 +11514,7 @@ topics = {'assert': '\n' 'different object types.\n' '\n' 'See Function definitions for more information.\n', - 'typesmapping': '\n' - 'Mapping Types --- "dict"\n' + 'typesmapping': 'Mapping Types --- "dict"\n' '************************\n' '\n' 'A *mapping* object maps *hashable* values to arbitrary ' @@ -11925,8 +11871,7 @@ topics = {'assert': '\n' " {'bacon'}\n" " >>> keys ^ {'sausage', 'juice'}\n" " {'juice', 'sausage', 'bacon', 'spam'}\n", - 'typesmethods': '\n' - 'Methods\n' + 'typesmethods': 'Methods\n' '*******\n' '\n' 'Methods are functions that are called using the attribute ' @@ -11983,8 +11928,7 @@ topics = {'assert': '\n' " 'my name is method'\n" '\n' 'See The standard type hierarchy for more information.\n', - 'typesmodules': '\n' - 'Modules\n' + 'typesmodules': 'Modules\n' '*******\n' '\n' 'The only special operation on a module is attribute access: ' @@ -12021,8 +11965,7 @@ topics = {'assert': '\n' 'written as\n' '"".\n', - 'typesseq': '\n' - 'Sequence Types --- "list", "tuple", "range"\n' + 'typesseq': 'Sequence Types --- "list", "tuple", "range"\n' '*******************************************\n' '\n' 'There are three basic sequence types: lists, tuples, and range\n' @@ -12170,9 +12113,9 @@ topics = {'assert': '\n' '\n' '3. 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' + ' sequence *s*: "len(s) + i" or "len(s) + j" is substituted. ' + 'But\n' + ' note that "-0" is still "0".\n' '\n' '4. The slice of *s* from *i* to *j* is defined as the sequence ' 'of\n' @@ -12191,12 +12134,17 @@ topics = {'assert': '\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' + ' including *j*). When *k* is positive, *i* and *j* are ' + 'reduced to\n' + ' "len(s)" if they are greater. When *k* is negative, *i* and ' + '*j* are\n' + ' reduced to "len(s) - 1" if they are greater. If *i* or *j* ' + 'are\n' + ' omitted or "None", they become "end" values (which end ' + 'depends on\n' + ' the sign of *k*). Note, *k* cannot be zero. If *k* is ' + '"None", it\n' + ' is treated like "1".\n' '\n' '6. Concatenating immutable sequences always results in a new\n' ' object. This means that building up a sequence by repeated\n' @@ -12714,8 +12662,7 @@ topics = {'assert': '\n' ' * The linspace recipe shows how to implement a lazy version ' 'of\n' ' range that suitable for floating point applications.\n', - 'typesseq-mutable': '\n' - 'Mutable Sequence Types\n' + 'typesseq-mutable': 'Mutable Sequence Types\n' '**********************\n' '\n' 'The operations in the following table are defined on ' @@ -12855,8 +12802,7 @@ topics = {'assert': '\n' 'referenced multiple\n' ' times, as explained for "s * n" under Common Sequence ' 'Operations.\n', - 'unary': '\n' - 'Unary arithmetic and bitwise operations\n' + 'unary': 'Unary arithmetic and bitwise operations\n' '***************************************\n' '\n' 'All unary arithmetic and bitwise operations have the same ' @@ -12878,8 +12824,7 @@ topics = {'assert': '\n' 'In all three cases, if the argument does not have the proper type, ' 'a\n' '"TypeError" exception is raised.\n', - 'while': '\n' - 'The "while" statement\n' + 'while': 'The "while" statement\n' '*********************\n' '\n' 'The "while" statement is used for repeated execution as long as an\n' @@ -12903,8 +12848,7 @@ topics = {'assert': '\n' 'executed in the first suite skips the rest of the suite and goes ' 'back\n' 'to testing the expression.\n', - 'with': '\n' - 'The "with" statement\n' + 'with': 'The "with" statement\n' '********************\n' '\n' 'The "with" statement is used to wrap the execution of a block with\n' @@ -12977,8 +12921,7 @@ topics = {'assert': '\n' ' The specification, background, and examples for the Python ' '"with"\n' ' statement.\n', - 'yield': '\n' - 'The "yield" statement\n' + 'yield': 'The "yield" statement\n' '*********************\n' '\n' ' yield_stmt ::= yield_expression\n' diff --git a/Lib/random.py b/Lib/random.py index 49b0f14..ad1c916 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -254,7 +254,7 @@ class Random(_random.Random): try: i = self._randbelow(len(seq)) except ValueError: - raise IndexError('Cannot choose from an empty sequence') + raise IndexError('Cannot choose from an empty sequence') from None return seq[i] def shuffle(self, x, random=None): diff --git a/Lib/secrets.py b/Lib/secrets.py index 27fa450..1304342 100644 --- a/Lib/secrets.py +++ b/Lib/secrets.py @@ -26,6 +26,8 @@ choice = _sysrand.choice def randbelow(exclusive_upper_bound): """Return a random int in the range [0, n).""" + if exclusive_upper_bound <= 0: + raise ValueError("Upper bound must be positive.") return _sysrand._randbelow(exclusive_upper_bound) DEFAULT_ENTROPY = 32 # number of bytes to return by default diff --git a/Lib/shlex.py b/Lib/shlex.py index e87266f..2c9786c 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -232,11 +232,6 @@ class shlex: break # emit current token else: continue - elif self.posix and nextchar in self.quotes: - self.state = nextchar - elif self.posix and nextchar in self.escape: - escapedstate = 'a' - self.state = nextchar elif self.state == 'c': if nextchar in self.punctuation_chars: self.token += nextchar @@ -245,6 +240,11 @@ class shlex: self._pushback_chars.append(nextchar) self.state = ' ' break + elif self.posix and nextchar in self.quotes: + self.state = nextchar + elif self.posix and nextchar in self.escape: + escapedstate = 'a' + self.state = nextchar elif (nextchar in self.wordchars or nextchar in self.quotes or self.whitespace_split): self.token += nextchar diff --git a/Lib/shutil.py b/Lib/shutil.py index 90b7198..bd4760f 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -10,7 +10,13 @@ import stat import fnmatch import collections import errno -import tarfile + +try: + import zlib + del zlib + _ZLIB_SUPPORTED = True +except ImportError: + _ZLIB_SUPPORTED = False try: import bz2 @@ -602,23 +608,22 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, Returns the output filename. """ - tar_compression = {'gzip': 'gz', None: ''} - compress_ext = {'gzip': '.gz'} - - if _BZ2_SUPPORTED: - tar_compression['bzip2'] = 'bz2' - compress_ext['bzip2'] = '.bz2' - - if _LZMA_SUPPORTED: - tar_compression['xz'] = 'xz' - compress_ext['xz'] = '.xz' - - # flags for compression program, each element of list will be an argument - if compress is not None and compress not in compress_ext: + if compress is None: + tar_compression = '' + elif _ZLIB_SUPPORTED and compress == 'gzip': + tar_compression = 'gz' + elif _BZ2_SUPPORTED and compress == 'bzip2': + tar_compression = 'bz2' + elif _LZMA_SUPPORTED and compress == 'xz': + tar_compression = 'xz' + else: raise ValueError("bad value for 'compress', or compression format not " "supported : {0}".format(compress)) - archive_name = base_name + '.tar' + compress_ext.get(compress, '') + import tarfile # late import for breaking circular dependency + + compress_ext = '.' + tar_compression if compress else '' + archive_name = base_name + '.tar' + compress_ext archive_dir = os.path.dirname(archive_name) if archive_dir and not os.path.exists(archive_dir): @@ -644,7 +649,7 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, return tarinfo if not dry_run: - tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + tar = tarfile.open(archive_name, 'w|%s' % tar_compression) try: tar.add(base_dir, filter=_set_uid_gid) finally: @@ -655,13 +660,10 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): """Create a zip file from all the files under 'base_dir'. - The output zip file will be named 'base_name' + ".zip". Uses either the - "zipfile" Python module (if available) or the InfoZIP "zip" utility - (if installed and found on the default search path). If neither tool is - available, raises ExecError. Returns the name of the output zip - file. + The output zip file will be named 'base_name' + ".zip". Returns the + name of the output zip file. """ - import zipfile + import zipfile # late import for breaking circular dependency zip_filename = base_name + ".zip" archive_dir = os.path.dirname(base_name) @@ -700,10 +702,13 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): return zip_filename _ARCHIVE_FORMATS = { - 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), - 'zip': (_make_zipfile, [], "ZIP file") - } +} + +if _ZLIB_SUPPORTED: + _ARCHIVE_FORMATS['gztar'] = (_make_tarball, [('compress', 'gzip')], + "gzip'ed tar-file") + _ARCHIVE_FORMATS['zip'] = (_make_zipfile, [], "ZIP file") if _BZ2_SUPPORTED: _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], @@ -752,8 +757,8 @@ def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, """Create an archive file (eg. zip or tar). 'base_name' is the name of the file to create, minus any format-specific - extension; 'format' is the archive format: one of "zip", "tar", "bztar" - or "gztar". + extension; 'format' is the archive format: one of "zip", "tar", "gztar", + "bztar", or "xztar". Or any other registered format. 'root_dir' is a directory that will be the root directory of the archive; ie. we typically chdir into 'root_dir' before creating the @@ -866,10 +871,7 @@ def _ensure_directory(path): def _unpack_zipfile(filename, extract_dir): """Unpack zip `filename` to `extract_dir` """ - try: - import zipfile - except ImportError: - raise ReadError('zlib not supported, cannot unpack this archive.') + import zipfile # late import for breaking circular dependency if not zipfile.is_zipfile(filename): raise ReadError("%s is not a zip file" % filename) @@ -903,6 +905,7 @@ def _unpack_zipfile(filename, extract_dir): def _unpack_tarfile(filename, extract_dir): """Unpack tar/tar.gz/tar.bz2/tar.xz `filename` to `extract_dir` """ + import tarfile # late import for breaking circular dependency try: tarobj = tarfile.open(filename) except tarfile.TarError: @@ -914,10 +917,13 @@ def _unpack_tarfile(filename, extract_dir): tarobj.close() _UNPACK_FORMATS = { - 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), - 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") - } + 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file"), +} + +if _ZLIB_SUPPORTED: + _UNPACK_FORMATS['gztar'] = (['.tar.gz', '.tgz'], _unpack_tarfile, [], + "gzip'ed tar-file") if _BZ2_SUPPORTED: _UNPACK_FORMATS['bztar'] = (['.tar.bz2', '.tbz2'], _unpack_tarfile, [], @@ -942,10 +948,10 @@ def unpack_archive(filename, extract_dir=None, format=None): `extract_dir` is the name of the target directory, where the archive is unpacked. If not provided, the current working directory is used. - `format` is the archive format: one of "zip", "tar", or "gztar". Or any - other registered format. If not provided, unpack_archive will use the - filename extension and see if an unpacker was registered for that - extension. + `format` is the archive format: one of "zip", "tar", "gztar", "bztar", + or "xztar". Or any other registered format. If not provided, + unpack_archive will use the filename extension and see if an unpacker + was registered for that extension. In case none is found, a ValueError is raised. """ diff --git a/Lib/site-packages/README b/Lib/site-packages/README deleted file mode 100644 index 273f625..0000000 --- a/Lib/site-packages/README +++ /dev/null @@ -1,2 +0,0 @@ -This directory exists so that 3rd party packages can be installed -here. Read the source for site.py for more details. diff --git a/Lib/sqlite3/test/transactions.py b/Lib/sqlite3/test/transactions.py index 45f1b04..b8a13de 100644 --- a/Lib/sqlite3/test/transactions.py +++ b/Lib/sqlite3/test/transactions.py @@ -179,6 +179,15 @@ class TransactionalDDL(unittest.TestCase): result = self.con.execute("select * from test").fetchall() self.assertEqual(result, []) + def CheckImmediateTransactionalDDL(self): + # You can achieve transactional DDL by issuing a BEGIN + # statement manually. + self.con.execute("begin immediate") + self.con.execute("create table test(i)") + self.con.rollback() + with self.assertRaises(sqlite.OperationalError): + self.con.execute("select * from test") + def CheckTransactionalDDL(self): # You can achieve transactional DDL by issuing a BEGIN # statement manually. diff --git a/Lib/sqlite3/test/types.py b/Lib/sqlite3/test/types.py index 0b5b3e7..6bc8d71 100644 --- a/Lib/sqlite3/test/types.py +++ b/Lib/sqlite3/test/types.py @@ -382,8 +382,7 @@ class DateTimeTests(unittest.TestCase): @unittest.skipIf(sqlite.sqlite_version_info < (3, 1), 'the date functions are available on 3.1 or later') def CheckSqlTimestamp(self): - # SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time. - now = datetime.datetime.now() + now = datetime.datetime.utcnow() self.cur.execute("insert into test(ts) values (current_timestamp)") self.cur.execute("select ts from test") ts = self.cur.fetchone()[0] diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 0b880f6..822ddb4 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -750,15 +750,15 @@ class Popen(object): # Wait for the process to terminate, to avoid zombies. self.wait() - def __del__(self, _maxsize=sys.maxsize): + def __del__(self, _maxsize=sys.maxsize, _warn=warnings.warn): if not self._child_created: # We didn't get to successfully create a child process. return if self.returncode is None: # Not reading subprocess exit status creates a zombi process which # is only destroyed at the parent python process exit - warnings.warn("subprocess %s is still running" % self.pid, - ResourceWarning, source=self) + _warn("subprocess %s is still running" % self.pid, + ResourceWarning, source=self) # In case the child hasn't been waited on, check if it's done. self._internal_poll(_deadstate=_maxsize) if self.returncode is None and _active is not None: @@ -1329,7 +1329,8 @@ class Popen(object): def _handle_exitstatus(self, sts, _WIFSIGNALED=os.WIFSIGNALED, _WTERMSIG=os.WTERMSIG, _WIFEXITED=os.WIFEXITED, - _WEXITSTATUS=os.WEXITSTATUS): + _WEXITSTATUS=os.WEXITSTATUS, _WIFSTOPPED=os.WIFSTOPPED, + _WSTOPSIG=os.WSTOPSIG): """All callers to this function MUST hold self._waitpid_lock.""" # This method is called (indirectly) by __del__, so it cannot # refer to anything outside of its local scope. @@ -1337,6 +1338,8 @@ class Popen(object): self.returncode = -_WTERMSIG(sts) elif _WIFEXITED(sts): self.returncode = _WEXITSTATUS(sts) + elif _WIFSTOPPED(sts): + self.returncode = -_WSTOPSIG(sts) else: # Should never happen raise SubprocessError("Unknown child exit status!") diff --git a/Lib/tarfile.py b/Lib/tarfile.py index b78b1b1..5d4c86c 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -50,9 +50,13 @@ import copy import re try: - import grp, pwd + import pwd except ImportError: - grp = pwd = None + pwd = None +try: + import grp +except ImportError: + grp = None # os.symlink on Windows prior to 6.0 raises NotImplementedError symlink_exception = (AttributeError, NotImplementedError) @@ -2219,22 +2223,25 @@ class TarFile(object): def chown(self, tarinfo, targetpath, numeric_owner): """Set owner of targetpath according to tarinfo. If numeric_owner - is True, use .gid/.uid instead of .gname/.uname. + is True, use .gid/.uid instead of .gname/.uname. If numeric_owner + is False, fall back to .gid/.uid when the search based on name + fails. """ - if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + if hasattr(os, "geteuid") and os.geteuid() == 0: # We have to be root to do so. - if numeric_owner: - g = tarinfo.gid - u = tarinfo.uid - else: + g = tarinfo.gid + u = tarinfo.uid + if not numeric_owner: try: - g = grp.getgrnam(tarinfo.gname)[2] + if grp: + g = grp.getgrnam(tarinfo.gname)[2] except KeyError: - g = tarinfo.gid + pass try: - u = pwd.getpwnam(tarinfo.uname)[2] + if pwd: + u = pwd.getpwnam(tarinfo.uname)[2] except KeyError: - u = tarinfo.uid + pass try: if tarinfo.issym() and hasattr(os, "lchown"): os.lchown(targetpath, u, g) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index c00846c..b5f4782 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3818,6 +3818,19 @@ class TestStartMethod(unittest.TestCase): self.assertTrue(methods == ['fork', 'spawn'] or methods == ['fork', 'spawn', 'forkserver']) + def test_preload_resources(self): + if multiprocessing.get_start_method() != 'forkserver': + self.skipTest("test only relevant for 'forkserver' method") + name = os.path.join(os.path.dirname(__file__), 'mp_preload.py') + rc, out, err = test.support.script_helper.assert_python_ok(name) + out = out.decode() + err = err.decode() + if out.rstrip() != 'ok' or err != '': + print(out) + print(err) + self.fail("failed spawning forkserver or grandchild") + + # # Check that killing process does not leak named semaphores # diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index d65186d..2350125 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1989,6 +1989,47 @@ class TestDateTime(TestDate): self.assertEqual(t.second, 0) self.assertEqual(t.microsecond, 7812) + def test_timestamp_limits(self): + # minimum timestamp + min_dt = self.theclass.min.replace(tzinfo=timezone.utc) + min_ts = min_dt.timestamp() + try: + # date 0001-01-01 00:00:00+00:00: timestamp=-62135596800 + self.assertEqual(self.theclass.fromtimestamp(min_ts, tz=timezone.utc), + min_dt) + except (OverflowError, OSError) as exc: + # the date 0001-01-01 doesn't fit into 32-bit time_t, + # or platform doesn't support such very old date + self.skipTest(str(exc)) + + # maximum timestamp: set seconds to zero to avoid rounding issues + max_dt = self.theclass.max.replace(tzinfo=timezone.utc, + second=0, microsecond=0) + max_ts = max_dt.timestamp() + # date 9999-12-31 23:59:00+00:00: timestamp 253402300740 + self.assertEqual(self.theclass.fromtimestamp(max_ts, tz=timezone.utc), + max_dt) + + # number of seconds greater than 1 year: make sure that the new date + # is not valid in datetime.datetime limits + delta = 3600 * 24 * 400 + + # too small + ts = min_ts - delta + # converting a Python int to C time_t can raise a OverflowError, + # especially on 32-bit platforms. + with self.assertRaises((ValueError, OverflowError)): + self.theclass.fromtimestamp(ts) + with self.assertRaises((ValueError, OverflowError)): + self.theclass.utcfromtimestamp(ts) + + # too big + ts = max_dt.timestamp() + delta + with self.assertRaises((ValueError, OverflowError)): + self.theclass.fromtimestamp(ts) + with self.assertRaises((ValueError, OverflowError)): + self.theclass.utcfromtimestamp(ts) + def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, # and that this test will fail there. This test should diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py index 9fbe04d..c619b3d 100644 --- a/Lib/test/eintrdata/eintr_tester.py +++ b/Lib/test/eintrdata/eintr_tester.py @@ -20,6 +20,7 @@ import time import unittest from test import support +android_not_root = support.android_not_root @contextlib.contextmanager def kill_on_error(proc): @@ -311,6 +312,7 @@ class SocketEINTRTest(EINTRBaseTest): # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203162 @support.requires_freebsd_version(10, 3) @unittest.skipUnless(hasattr(os, 'mkfifo'), 'needs mkfifo()') + @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user") def _test_open(self, do_open_close_reader, do_open_close_writer): filename = support.TESTFN @@ -435,6 +437,8 @@ class SelectEINTRTest(EINTRBaseTest): self.stop_alarm() self.assertGreaterEqual(dt, self.sleep_time) + @unittest.skipIf(sys.platform == "darwin", + "poll may fail on macOS; see issue #28087") @unittest.skipUnless(hasattr(select, 'poll'), 'need select.poll') def test_poll(self): poller = select.poll() diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index 891b00c..d621f5f 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -301,9 +301,9 @@ def _parse_args(args, **kwargs): if ns.single and ns.fromfile: parser.error("-s and -f don't go together!") - if ns.use_mp and ns.trace: + if ns.use_mp is not None and ns.trace: parser.error("-T and -j don't go together!") - if ns.use_mp and ns.findleaks: + if ns.use_mp is not None and ns.findleaks: parser.error("-l and -j don't go together!") if ns.failfast and not (ns.verbose or ns.verbose3): parser.error("-G/--failfast needs either -v or -W") diff --git a/Lib/test/mod_generics_cache.py b/Lib/test/mod_generics_cache.py new file mode 100644 index 0000000..d9a60b4 --- /dev/null +++ b/Lib/test/mod_generics_cache.py @@ -0,0 +1,14 @@ +"""Module for testing the behavior of generics across different modules.""" + +from typing import TypeVar, Generic + +T = TypeVar('T') + + +class A(Generic[T]): + pass + + +class B(Generic[T]): + class A(Generic[T]): + pass diff --git a/Lib/test/mp_preload.py b/Lib/test/mp_preload.py new file mode 100644 index 0000000..5314e8f --- /dev/null +++ b/Lib/test/mp_preload.py @@ -0,0 +1,18 @@ +import multiprocessing + +multiprocessing.Lock() + + +def f(): + print("ok") + + +if __name__ == "__main__": + ctx = multiprocessing.get_context("forkserver") + modname = "test.mp_preload" + # Make sure it's importable + __import__(modname) + ctx.set_forkserver_preload([modname]) + proc = ctx.Process(target=f) + proc.start() + proc.join() diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py old mode 100644 new mode 100755 diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 52c908e..15d8fc8 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -93,8 +93,10 @@ __all__ = [ "check__all__", "requires_android_level", "requires_multiprocessing_queue", # sys "is_jython", "is_android", "check_impl_detail", "unix_shell", + "setswitchinterval", "android_not_root", # network "HOST", "IPV6_ENABLED", "find_unused_port", "bind_port", "open_urlresource", + "bind_unix_socket", # processes 'temp_umask', "reap_children", # logging @@ -360,9 +362,9 @@ if sys.platform.startswith("win"): mode = 0 if stat.S_ISDIR(mode): _waitfor(_rmtree_inner, fullname, waitall=True) - _force_run(path, os.rmdir, fullname) + _force_run(fullname, os.rmdir, fullname) else: - _force_run(path, os.unlink, fullname) + _force_run(fullname, os.unlink, fullname) _waitfor(_rmtree_inner, path, waitall=True) _waitfor(lambda p: _force_run(p, os.rmdir, p), path) else: @@ -707,6 +709,15 @@ def bind_port(sock, host=HOST): port = sock.getsockname()[1] return port +def bind_unix_socket(sock, addr): + """Bind a unix socket, raising SkipTest if PermissionError is raised.""" + assert sock.family == socket.AF_UNIX + try: + sock.bind(addr) + except PermissionError: + sock.close() + raise unittest.SkipTest('cannot bind AF_UNIX sockets') + def _is_ipv6_enabled(): """Check whether IPv6 is enabled on this host.""" if socket.has_ipv6: @@ -768,6 +779,7 @@ is_jython = sys.platform.startswith('java') _ANDROID_API_LEVEL = sysconfig.get_config_var('ANDROID_API_LEVEL') is_android = (_ANDROID_API_LEVEL is not None and _ANDROID_API_LEVEL > 0) +android_not_root = (is_android and os.geteuid() != 0) if sys.platform != 'win32': unix_shell = '/system/bin/sh' if is_android else '/bin/sh' @@ -1054,9 +1066,16 @@ def make_bad_fd(): file.close() unlink(TESTFN) -def check_syntax_error(testcase, statement): - testcase.assertRaises(SyntaxError, compile, statement, - '', 'exec') +def check_syntax_error(testcase, statement, *, lineno=None, offset=None): + with testcase.assertRaises(SyntaxError) as cm: + compile(statement, '', 'exec') + err = cm.exception + testcase.assertIsNotNone(err.lineno) + if lineno is not None: + testcase.assertEqual(err.lineno, lineno) + testcase.assertIsNotNone(err.offset) + if offset is not None: + testcase.assertEqual(err.offset, offset) def open_urlresource(url, *args, **kw): import urllib.request, urllib.parse @@ -2547,3 +2566,18 @@ def missing_compiler_executable(cmd_names=[]): continue if spawn.find_executable(cmd[0]) is None: return cmd[0] + + +_is_android_emulator = None +def setswitchinterval(interval): + # Setting a very low gil interval on the Android emulator causes python + # to hang (issue #26939). + minimum_interval = 1e-5 + if is_android and interval < minimum_interval: + global _is_android_emulator + if _is_android_emulator is None: + _is_android_emulator = (subprocess.check_output( + ['getprop', 'ro.kernel.qemu']).strip() == b'1') + if _is_android_emulator: + interval = minimum_interval + return sys.setswitchinterval(interval) diff --git a/Lib/test/support/script_helper.py b/Lib/test/support/script_helper.py index 80889b1..ca5f9c2 100644 --- a/Lib/test/support/script_helper.py +++ b/Lib/test/support/script_helper.py @@ -70,17 +70,28 @@ def run_python_until_end(*args, **env_vars): elif not env_vars and not env_required: # ignore Python environment variables cmd_line.append('-E') - # Need to preserve the original environment, for in-place testing of - # shared library builds. - env = os.environ.copy() - # set TERM='' unless the TERM environment variable is passed explicitly - # see issues #11390 and #18300 - if 'TERM' not in env_vars: - env['TERM'] = '' + # But a special flag that can be set to override -- in this case, the # caller is responsible to pass the full environment. if env_vars.pop('__cleanenv', None): env = {} + if sys.platform == 'win32': + # Windows requires at least the SYSTEMROOT environment variable to + # start Python. + env['SYSTEMROOT'] = os.environ['SYSTEMROOT'] + + # Other interesting environment variables, not copied currently: + # COMSPEC, HOME, PATH, TEMP, TMPDIR, TMP. + else: + # Need to preserve the original environment, for in-place testing of + # shared library builds. + env = os.environ.copy() + + # set TERM='' unless the TERM environment variable is passed explicitly + # see issues #11390 and #18300 + if 'TERM' not in env_vars: + env['TERM'] = '' + env.update(env_vars) cmd_line.extend(args) proc = subprocess.Popen(cmd_line, stdin=subprocess.PIPE, diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index ae9114e..f6e82eb 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -72,17 +72,6 @@ class AllTest(unittest.TestCase): # than an AttributeError somewhere deep in CGIHTTPServer. import _socket - # rlcompleter needs special consideration; it import readline which - # initializes GNU readline which calls setlocale(LC_CTYPE, "")... :-( - import locale - locale_tuple = locale.getlocale(locale.LC_CTYPE) - try: - import rlcompleter - except ImportError: - pass - finally: - locale.setlocale(locale.LC_CTYPE, locale_tuple) - ignored = [] failed_imports = [] lib_dir = os.path.dirname(os.path.dirname(__file__)) diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index 1bd1f89..a731a51 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -1,5 +1,6 @@ -from test.support import findfile, TESTFN, unlink +from test.support import check_no_resource_warning, findfile, TESTFN, unlink import unittest +from unittest import mock from test import audiotests from audioop import byteswap import io @@ -149,6 +150,21 @@ class AifcMiscTest(audiotests.AudioTests, unittest.TestCase): #This file contains chunk types aifc doesn't recognize. self.f = aifc.open(findfile('Sine-1000Hz-300ms.aif')) + def test_close_opened_files_on_error(self): + non_aifc_file = findfile('pluck-pcm8.wav', subdir='audiodata') + with check_no_resource_warning(self): + with self.assertRaises(aifc.Error): + # Try opening a non-AIFC file, with the expectation that + # `aifc.open` will fail (without raising a ResourceWarning) + self.f = aifc.open(non_aifc_file, 'rb') + + # Aifc_write.initfp() won't raise in normal case. But some errors + # (e.g. MemoryError, KeyboardInterrupt, etc..) can happen. + with mock.patch.object(aifc.Aifc_write, 'initfp', + side_effect=RuntimeError): + with self.assertRaises(RuntimeError): + self.fout = aifc.open(TESTFN, 'wb') + def test_params_added(self): f = self.f = aifc.open(TESTFN, 'wb') f.aiff() diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index bc83161..a5c4a8e 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1943,6 +1943,23 @@ class TestAddSubparsers(TestCase): ++foo foo help ''')) + def test_help_non_breaking_spaces(self): + parser = ErrorRaisingArgumentParser( + prog='PROG', description='main description') + parser.add_argument( + "--non-breaking", action='store_false', + help='help message containing non-breaking spaces shall not ' + 'wrap\N{NO-BREAK SPACE}at non-breaking spaces') + self.assertEqual(parser.format_help(), textwrap.dedent('''\ + usage: PROG [-h] [--non-breaking] + + main description + + optional arguments: + -h, --help show this help message and exit + --non-breaking help message containing non-breaking spaces shall not + wrap\N{NO-BREAK SPACE}at non-breaking spaces + ''')) def test_help_alternate_prefix_chars(self): parser = self._get_parser(prefix_chars='+:/') diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 28d92a9..802763b 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -1,6 +1,7 @@ """Tests for events.py.""" import collections.abc +import concurrent.futures import functools import gc import io @@ -57,6 +58,15 @@ def osx_tiger(): return version < (10, 5) +def _test_get_event_loop_new_process__sub_proc(): + async def doit(): + return 'hello' + + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + return loop.run_until_complete(doit()) + + ONLYCERT = data_file('ssl_cert.pem') ONLYKEY = data_file('ssl_key.pem') SIGNED_CERTFILE = data_file('keycert3.pem') @@ -2181,6 +2191,18 @@ else: asyncio.set_child_watcher(None) super().tearDown() + def test_get_event_loop_new_process(self): + async def main(): + pool = concurrent.futures.ProcessPoolExecutor() + return await self.loop.run_in_executor( + pool, _test_get_event_loop_new_process__sub_proc) + + self.unpatch_get_running_loop() + + self.assertEqual( + self.loop.run_until_complete(main()), + 'hello') + if hasattr(selectors, 'KqueueSelector'): class KqueueEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 89afdca..99336f8 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -569,6 +569,35 @@ class BaseFutureDoneCallbackTests(): self.assertEqual(bag, [2]) self.assertEqual(f.result(), 'foo') + def test_remove_done_callbacks_list_mutation(self): + # see http://bugs.python.org/issue28963 for details + + fut = self._new_future() + fut.add_done_callback(str) + + for _ in range(63): + fut.add_done_callback(id) + + class evil: + def __eq__(self, other): + fut.remove_done_callback(id) + return False + + fut.remove_done_callback(evil()) + + def test_schedule_callbacks_list_mutation(self): + # see http://bugs.python.org/issue28963 for details + + def mut(f): + f.remove_done_callback(str) + + fut = self._new_future() + fut.add_done_callback(mut) + fut.add_done_callback(str) + fut.add_done_callback(str) + fut.set_result(1) + test_utils.run_briefly(self.loop) + @unittest.skipUnless(hasattr(futures, '_CFuture'), 'requires the C _asyncio module') diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index bba688b..2e14a8a 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -459,6 +459,30 @@ class SubprocessMixin: self.loop.run_until_complete(create) self.assertEqual(warns, []) + def test_read_stdout_after_process_exit(self): + @asyncio.coroutine + def execute(): + code = '\n'.join(['import sys', + 'for _ in range(64):', + ' sys.stdout.write("x" * 4096)', + 'sys.stdout.flush()', + 'sys.exit(1)']) + + fut = asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdout=asyncio.subprocess.PIPE, + loop=self.loop) + + process = yield from fut + while True: + data = yield from process.stdout.read(65536) + if data: + yield from asyncio.sleep(0.3, loop=self.loop) + else: + break + + self.loop.run_until_complete(execute()) + if sys.platform != 'win32': # Unix diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index a18d49a..4f05319 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1462,6 +1462,14 @@ class BaseTaskTests: def coro(loop): self.assertTrue(Task.current_task(loop=loop) is task) + # See http://bugs.python.org/issue29271 for details: + asyncio.set_event_loop(loop) + try: + self.assertIs(Task.current_task(None), task) + self.assertIs(Task.current_task(), task) + finally: + asyncio.set_event_loop(None) + task = self.new_task(self.loop, coro(self.loop)) self.loop.run_until_complete(task) self.assertIsNone(Task.current_task(loop=self.loop)) @@ -1806,8 +1814,17 @@ class BaseTaskTests: # schedule the task coro = kill_me(self.loop) task = asyncio.ensure_future(coro, loop=self.loop) + self.assertEqual(Task.all_tasks(loop=self.loop), {task}) + # See http://bugs.python.org/issue29271 for details: + asyncio.set_event_loop(self.loop) + try: + self.assertEqual(Task.all_tasks(), {task}) + self.assertEqual(Task.all_tasks(None), {task}) + finally: + asyncio.set_event_loop(None) + # execute the task so it waits for future self.loop._run_once() self.assertEqual(len(self.loop._ready), 0) diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index dbee593..d05462b 100644 --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -95,7 +95,9 @@ def bind_af_aware(sock, addr): if HAS_UNIX_SOCKETS and sock.family == socket.AF_UNIX: # Make sure the path doesn't exist. support.unlink(addr) - sock.bind(addr) + support.bind_unix_socket(sock, addr) + else: + sock.bind(addr) class HelperFunctionTests(unittest.TestCase): @@ -659,6 +661,9 @@ class BaseTestAPI: if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX: self.skipTest("Not applicable to AF_UNIX sockets.") + if sys.platform == "darwin" and self.use_poll: + self.skipTest("poll may fail on macOS; see issue #28087") + class TestClient(BaseClient): def handle_expt(self): self.socket.recv(1024, socket.MSG_OOB) diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 4f86aaa..4754739 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -18,6 +18,14 @@ class LegacyBase64TestCase(unittest.TestCase): int_data = memoryview(b"1234").cast('I') self.assertRaises(TypeError, f, int_data) + def test_encodestring_warns(self): + with self.assertWarns(DeprecationWarning): + base64.encodestring(b"www.python.org") + + def test_decodestring_warns(self): + with self.assertWarns(DeprecationWarning): + base64.decodestring(b"d3d3LnB5dGhvbi5vcmc=\n") + def test_encodebytes(self): eq = self.assertEqual eq(base64.encodebytes(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n") diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index a792099..416316c 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1627,6 +1627,16 @@ class TestSorted(unittest.TestCase): self.assertEqual(data, sorted(copy, reverse=1)) self.assertNotEqual(data, copy) + def test_bad_arguments(self): + # Issue #29327: The first argument is positional-only. + sorted([]) + with self.assertRaises(TypeError): + sorted(iterable=[]) + # Other arguments are keyword-only + sorted([], key=None) + with self.assertRaises(TypeError): + sorted([], None) + def test_inputtypes(self): s = 'abracadabra' types = [list, tuple, str] diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index b396a76..a103a7d 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -4,6 +4,7 @@ XXX This is a mess. Common tests should be unified with string_tests.py (and the latter should be modernized). """ +import array import os import re import sys @@ -81,6 +82,18 @@ class BaseBytesTest: self.assertRaises(ValueError, self.type2test, [Indexable(-1)]) self.assertRaises(ValueError, self.type2test, [Indexable(256)]) + def test_from_buffer(self): + a = self.type2test(array.array('B', [1, 2, 3])) + self.assertEqual(a, b"\x01\x02\x03") + + # http://bugs.python.org/issue29159 + # Fallback when __index__ raises exception other than OverflowError + class B(bytes): + def __index__(self): + raise TypeError + + self.assertEqual(self.type2test(B(b"foobar")), b"foobar") + def test_from_ssize(self): self.assertEqual(self.type2test(0), b'') self.assertEqual(self.type2test(1), b'\x00') diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index b71bb9f..ae2bcd4 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -8,7 +8,7 @@ import shutil import sys import subprocess import tempfile -from test.support import script_helper +from test.support import script_helper, is_android from test.support.script_helper import (spawn_python, kill_python, assert_python_ok, assert_python_failure) @@ -178,15 +178,16 @@ class CmdLineTest(unittest.TestCase): if not stdout.startswith(pattern): raise AssertionError("%a doesn't start with %a" % (stdout, pattern)) - @unittest.skipUnless(sys.platform == 'darwin', 'test specific to Mac OS X') - def test_osx_utf8(self): + @unittest.skipUnless((sys.platform == 'darwin' or + is_android), 'test specific to Mac OS X and Android') + def test_osx_android_utf8(self): def check_output(text): decoded = text.decode('utf-8', 'surrogateescape') expected = ascii(decoded).encode('ascii') + b'\n' env = os.environ.copy() # C locale gives ASCII locale encoding, but Python uses UTF-8 - # to parse the command line arguments on Mac OS X + # to parse the command line arguments on Mac OS X and Android. env['LC_ALL'] = 'C' p = subprocess.Popen( diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 38cb2e2..1587daf 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -10,6 +10,7 @@ import os import os.path import py_compile import subprocess +import io import textwrap from test import support @@ -539,6 +540,105 @@ class CmdLineTest(unittest.TestCase): text = stderr.decode('ascii') self.assertEqual(text, "some text") + def test_syntaxerror_unindented_caret_position(self): + script = "1 + 1 = 2\n" + with support.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read() + # Confirm that the caret is located under the first 1 character + self.assertIn("\n 1 + 1 = 2\n ^", text) + + def test_syntaxerror_indented_caret_position(self): + script = textwrap.dedent("""\ + if True: + 1 + 1 = 2 + """) + with support.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read() + # Confirm that the caret is located under the first 1 character + self.assertIn("\n 1 + 1 = 2\n ^", text) + + # Try the same with a form feed at the start of the indented line + script = ( + "if True:\n" + "\f 1 + 1 = 2\n" + ) + script_name = _make_test_script(script_dir, "script", script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = io.TextIOWrapper(io.BytesIO(stderr), "ascii").read() + self.assertNotIn("\f", text) + self.assertIn("\n 1 + 1 = 2\n ^", text) + + def test_consistent_sys_path_for_direct_execution(self): + # This test case ensures that the following all give the same + # sys.path configuration: + # + # ./python -s script_dir/__main__.py + # ./python -s script_dir + # ./python -I script_dir + script = textwrap.dedent("""\ + import sys + for entry in sys.path: + print(entry) + """) + # Always show full path diffs on errors + self.maxDiff = None + with support.temp_dir() as work_dir, support.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, '__main__', script) + # Reference output comes from directly executing __main__.py + # We omit PYTHONPATH and user site to align with isolated mode + p = spawn_python("-Es", script_name, cwd=work_dir) + out_by_name = kill_python(p).decode().splitlines() + self.assertEqual(out_by_name[0], script_dir) + self.assertNotIn(work_dir, out_by_name) + # Directory execution should give the same output + p = spawn_python("-Es", script_dir, cwd=work_dir) + out_by_dir = kill_python(p).decode().splitlines() + self.assertEqual(out_by_dir, out_by_name) + # As should directory execution in isolated mode + p = spawn_python("-I", script_dir, cwd=work_dir) + out_by_dir_isolated = kill_python(p).decode().splitlines() + self.assertEqual(out_by_dir_isolated, out_by_dir, out_by_name) + + def test_consistent_sys_path_for_module_execution(self): + # This test case ensures that the following both give the same + # sys.path configuration: + # ./python -sm script_pkg.__main__ + # ./python -sm script_pkg + # + # And that this fails as unable to find the package: + # ./python -Im script_pkg + script = textwrap.dedent("""\ + import sys + for entry in sys.path: + print(entry) + """) + # Always show full path diffs on errors + self.maxDiff = None + with support.temp_dir() as work_dir: + script_dir = os.path.join(work_dir, "script_pkg") + os.mkdir(script_dir) + script_name = _make_test_script(script_dir, '__main__', script) + # Reference output comes from `-m script_pkg.__main__` + # We omit PYTHONPATH and user site to better align with the + # direct execution test cases + p = spawn_python("-sm", "script_pkg.__main__", cwd=work_dir) + out_by_module = kill_python(p).decode().splitlines() + self.assertEqual(out_by_module[0], '') + self.assertNotIn(script_dir, out_by_module) + # Package execution should give the same output + p = spawn_python("-sm", "script_pkg", cwd=work_dir) + out_by_package = kill_python(p).decode().splitlines() + self.assertEqual(out_by_package, out_by_module) + # Isolated mode should fail with an import error + exitcode, stdout, stderr = assert_python_failure( + "-Im", "script_pkg", cwd=work_dir + ) + traceback_lines = stderr.decode().splitlines() + self.assertIn("No module named script_pkg", traceback_lines[-1]) def test_main(): support.run_unittest(CmdLineTest) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 409ec86..da1db15 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -637,6 +637,7 @@ if 1: f1 = ns['f1'] f2 = ns['f2'] self.assertIsNot(f1.__code__, f2.__code__) + self.assertNotEqual(f1.__code__, f2.__code__) self.check_constant(f1, const1) self.check_constant(f2, const2) self.assertEqual(repr(f1()), repr(const1)) @@ -645,6 +646,8 @@ if 1: check_different_constants(0, 0.0) check_different_constants(+0.0, -0.0) check_different_constants((0,), (0.0,)) + check_different_constants('a', b'a') + check_different_constants(('a',), (b'a',)) # check_different_constants() cannot be used because repr(-0j) is # '(-0-0j)', but when '(-0-0j)' is evaluated to 0j: we loose the sign. diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index c249ca7..cee4934 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -387,6 +387,29 @@ class ComplexTest(unittest.TestCase): self.assertAlmostEqual(complex(complex1(1j)), 2j) self.assertRaises(TypeError, complex, complex2(1j)) + @support.requires_IEEE_754 + def test_constructor_special_numbers(self): + class complex2(complex): + pass + for x in 0.0, -0.0, INF, -INF, NAN: + for y in 0.0, -0.0, INF, -INF, NAN: + with self.subTest(x=x, y=y): + z = complex(x, y) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex2(x, y) + self.assertIs(type(z), complex2) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex(complex2(x, y)) + self.assertIs(type(z), complex) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex2(complex(x, y)) + self.assertIs(type(z), complex2) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + def test_underscores(self): # check underscores for lit in VALID_UNDERSCORE_LITERALS: diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 0d06080..72c3f19 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -2,7 +2,7 @@ import collections import configparser import io import os -import sys +import pathlib import textwrap import unittest import warnings @@ -721,6 +721,16 @@ boolean {0[0]} NO parsed_files = cf.read(file1) self.assertEqual(parsed_files, [file1]) self.assertEqual(cf.get("Foo Bar", "foo"), "newbar") + # check when we pass only a Path object: + cf = self.newconfig() + parsed_files = cf.read(pathlib.Path(file1)) + self.assertEqual(parsed_files, [file1]) + self.assertEqual(cf.get("Foo Bar", "foo"), "newbar") + # check when we passed both a filename and a Path object: + cf = self.newconfig() + parsed_files = cf.read([pathlib.Path(file1), file1]) + self.assertEqual(parsed_files, [file1, file1]) + self.assertEqual(cf.get("Foo Bar", "foo"), "newbar") # check when we pass only missing files: cf = self.newconfig() parsed_files = cf.read(["nonexistent-file"]) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 78439a2..b4c7b5b 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1680,6 +1680,44 @@ class CoroutineTest(unittest.TestCase): warnings.simplefilter("error") run_async(foo()) + def test_for_11(self): + class F: + def __aiter__(self): + return self + def __anext__(self): + return self + def __await__(self): + 1 / 0 + + async def main(): + async for _ in F(): + pass + + with self.assertRaisesRegex(TypeError, + 'an invalid object from __anext__') as c: + main().send(None) + + err = c.exception + self.assertIsInstance(err.__cause__, ZeroDivisionError) + + def test_for_12(self): + class F: + def __aiter__(self): + return self + def __await__(self): + 1 / 0 + + async def main(): + async for _ in F(): + pass + + with self.assertRaisesRegex(TypeError, + 'an invalid object from __aiter__') as c: + main().send(None) + + err = c.exception + self.assertIsInstance(err.__cause__, ZeroDivisionError) + def test_for_tuple(self): class Done(Exception): pass diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index d020fd2..3d8c50b 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -27,6 +27,7 @@ requires('curses') curses = import_module('curses') import_module('curses.panel') import_module('curses.ascii') +import_module('curses.textpad') def requires_curses_func(name): return unittest.skipUnless(hasattr(curses, name), @@ -243,7 +244,7 @@ class TestCurses(unittest.TestCase): # Functions only available on a few platforms def test_colors_funcs(self): if not curses.has_colors(): - self.skip('requires colors support') + self.skipTest('requires colors support') curses.start_color() curses.init_pair(2, 1,1) curses.color_content(1) @@ -266,7 +267,7 @@ class TestCurses(unittest.TestCase): def test_getmouse(self): (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED) if availmask == 0: - self.skip('mouse stuff not available') + self.skipTest('mouse stuff not available') curses.mouseinterval(10) # just verify these don't cause errors curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED) @@ -392,6 +393,14 @@ class TestCurses(unittest.TestCase): human_readable_signature = stdscr.addch.__doc__.split("\n")[0] self.assertIn("[y, x,]", human_readable_signature) + def test_issue13051(self): + stdscr = self.stdscr + box = curses.textpad.Textbox(stdscr, insert_mode=True) + lines, cols = stdscr.getmaxyx() + stdscr.resize(lines-2, cols-2) + # this may cause infinite recursion, leading to a RuntimeError + box._insert_printable_char('a') + class MiscTests(unittest.TestCase): @@ -436,6 +445,25 @@ class TestAscii(unittest.TestCase): check(curses.ascii.ispunct, c in string.punctuation) check(curses.ascii.isxdigit, c in string.hexdigits) + for i in (-2, -1, 256, sys.maxunicode, sys.maxunicode+1): + self.assertFalse(curses.ascii.isalnum(i)) + self.assertFalse(curses.ascii.isalpha(i)) + self.assertFalse(curses.ascii.isdigit(i)) + self.assertFalse(curses.ascii.islower(i)) + self.assertFalse(curses.ascii.isspace(i)) + self.assertFalse(curses.ascii.isupper(i)) + + self.assertFalse(curses.ascii.isascii(i)) + self.assertFalse(curses.ascii.isctrl(i)) + self.assertFalse(curses.ascii.iscntrl(i)) + self.assertFalse(curses.ascii.isblank(i)) + self.assertFalse(curses.ascii.isgraph(i)) + self.assertFalse(curses.ascii.isprint(i)) + self.assertFalse(curses.ascii.ispunct(i)) + self.assertFalse(curses.ascii.isxdigit(i)) + + self.assertFalse(curses.ascii.ismeta(-1)) + def test_ascii(self): ascii = curses.ascii.ascii self.assertEqual(ascii('\xc1'), 'A') diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py index 2d77f07..df531d6 100644 --- a/Lib/test/test_dbm_dumb.py +++ b/Lib/test/test_dbm_dumb.py @@ -5,6 +5,7 @@ import io import operator import os +import stat import unittest import warnings import dbm.dumb as dumbdbm @@ -259,6 +260,21 @@ class DumbDBMTestCase(unittest.TestCase): f = dumbdbm.open(_fname, flag) f.close() + @unittest.skipUnless(hasattr(os, 'chmod'), 'test needs os.chmod()') + def test_readonly_files(self): + with support.temp_dir() as dir: + fname = os.path.join(dir, 'db') + with dumbdbm.open(fname, 'n') as f: + self.assertEqual(list(f.keys()), []) + for key in self._dict: + f[key] = self._dict[key] + os.chmod(fname + ".dir", stat.S_IRUSR) + os.chmod(fname + ".dat", stat.S_IRUSR) + os.chmod(dir, stat.S_IRUSR|stat.S_IXUSR) + with dumbdbm.open(fname, 'r') as f: + self.assertEqual(sorted(f.keys()), sorted(self._dict)) + f.close() # don't write + def tearDown(self): _delete_files() diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 1e08ed9..c5bff77 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -7,6 +7,7 @@ import pickle import sys import types import unittest +import warnings import weakref from copy import deepcopy @@ -1661,6 +1662,77 @@ order (MRO) for bases """ self.assertEqual(b.foo, 3) self.assertEqual(b.__class__, D) + @unittest.expectedFailure + def test_bad_new(self): + self.assertRaises(TypeError, object.__new__) + self.assertRaises(TypeError, object.__new__, '') + self.assertRaises(TypeError, list.__new__, object) + self.assertRaises(TypeError, object.__new__, list) + class C(object): + __new__ = list.__new__ + self.assertRaises(TypeError, C) + class C(list): + __new__ = object.__new__ + self.assertRaises(TypeError, C) + + def test_object_new(self): + class A(object): + pass + object.__new__(A) + self.assertRaises(TypeError, object.__new__, A, 5) + object.__init__(A()) + self.assertRaises(TypeError, object.__init__, A(), 5) + + class A(object): + def __init__(self, foo): + self.foo = foo + object.__new__(A) + object.__new__(A, 5) + object.__init__(A(3)) + self.assertRaises(TypeError, object.__init__, A(3), 5) + + class A(object): + def __new__(cls, foo): + return object.__new__(cls) + object.__new__(A) + self.assertRaises(TypeError, object.__new__, A, 5) + object.__init__(A(3)) + object.__init__(A(3), 5) + + class A(object): + def __new__(cls, foo): + return object.__new__(cls) + def __init__(self, foo): + self.foo = foo + object.__new__(A) + self.assertRaises(TypeError, object.__new__, A, 5) + object.__init__(A(3)) + self.assertRaises(TypeError, object.__init__, A(3), 5) + + @unittest.expectedFailure + def test_restored_object_new(self): + class A(object): + def __new__(cls, *args, **kwargs): + raise AssertionError + self.assertRaises(AssertionError, A) + class B(A): + __new__ = object.__new__ + def __init__(self, foo): + self.foo = foo + with warnings.catch_warnings(): + warnings.simplefilter('error', DeprecationWarning) + b = B(3) + self.assertEqual(b.foo, 3) + self.assertEqual(b.__class__, B) + del B.__new__ + self.assertRaises(AssertionError, B) + del A.__new__ + with warnings.catch_warnings(): + warnings.simplefilter('error', DeprecationWarning) + b = B(3) + self.assertEqual(b.foo, 3) + self.assertEqual(b.__class__, B) + def test_altmro(self): # Testing mro() and overriding it... class A(object): @@ -3522,6 +3594,24 @@ order (MRO) for bases """ self.assertIsInstance(d, D) self.assertEqual(d.foo, 1) + class C(object): + @staticmethod + def __new__(*args): + return args + self.assertEqual(C(1, 2), (C, 1, 2)) + class D(C): + pass + self.assertEqual(D(1, 2), (D, 1, 2)) + + class C(object): + @classmethod + def __new__(*args): + return args + self.assertEqual(C(1, 2), (C, C, 1, 2)) + class D(C): + pass + self.assertEqual(D(1, 2), (D, D, 1, 2)) + def test_imul_bug(self): # Testing for __imul__ problems... # SF bug 544647 diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index daa1285..f97ccc6 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -11,6 +11,7 @@ import textwrap from io import StringIO, BytesIO from itertools import chain from random import choice +from socket import getfqdn try: from threading import Thread except ImportError: @@ -3314,6 +3315,17 @@ multipart/report email.utils.make_msgid(domain='testdomain-string')[-19:], '@testdomain-string>') + def test_make_msgid_idstring(self): + self.assertEqual( + email.utils.make_msgid(idstring='test-idstring', + domain='testdomain-string')[-33:], + '.test-idstring@testdomain-string>') + + def test_make_msgid_default_domain(self): + self.assertTrue( + email.utils.make_msgid().endswith( + '@' + getfqdn() + '>')) + def test_Generator_linend(self): # Issue 14645. with openfile('msg_26.txt', newline='\n') as f: diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index e97ef94..13a89fc 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -7,6 +7,11 @@ from enum import Enum, IntEnum, EnumMeta, Flag, IntFlag, unique, auto from io import StringIO from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL from test import support +try: + import threading +except ImportError: + threading = None + # for pickle tests try: @@ -1983,6 +1988,45 @@ class TestFlag(unittest.TestCase): d = 6 self.assertEqual(repr(Bizarre(7)), '') + @unittest.skipUnless(threading, 'Threading required for this test.') + @support.reap_threads + def test_unique_composite(self): + # override __eq__ to be identity only + class TestFlag(Flag): + one = auto() + two = auto() + three = auto() + four = auto() + five = auto() + six = auto() + seven = auto() + eight = auto() + def __eq__(self, other): + return self is other + def __hash__(self): + return hash(self._value_) + # have multiple threads competing to complete the composite members + seen = set() + failed = False + def cycle_enum(): + nonlocal failed + try: + for i in range(256): + seen.add(TestFlag(i)) + except Exception: + failed = True + threads = [ + threading.Thread(target=cycle_enum) + for _ in range(8) + ] + with support.start_threads(threads): + pass + # check that only 248 members were created + self.assertFalse( + failed, + 'at least one thread failed while creating composite members') + self.assertEqual(256, len(seen), 'too many composite members created') + class TestIntFlag(unittest.TestCase): """Tests of the IntFlags.""" @@ -2275,6 +2319,46 @@ class TestIntFlag(unittest.TestCase): for f in Open: self.assertEqual(bool(f.value), bool(f)) + @unittest.skipUnless(threading, 'Threading required for this test.') + @support.reap_threads + def test_unique_composite(self): + # override __eq__ to be identity only + class TestFlag(IntFlag): + one = auto() + two = auto() + three = auto() + four = auto() + five = auto() + six = auto() + seven = auto() + eight = auto() + def __eq__(self, other): + return self is other + def __hash__(self): + return hash(self._value_) + # have multiple threads competing to complete the composite members + seen = set() + failed = False + def cycle_enum(): + nonlocal failed + try: + for i in range(256): + seen.add(TestFlag(i)) + except Exception: + failed = True + threads = [ + threading.Thread(target=cycle_enum) + for _ in range(8) + ] + with support.start_threads(threads): + pass + # check that only 248 members were created + self.assertFalse( + failed, + 'at least one thread failed while creating composite members') + self.assertEqual(256, len(seen), 'too many composite members created') + + class TestUnique(unittest.TestCase): def test_unique_clean(self): @@ -2484,7 +2568,8 @@ CONVERT_TEST_NAME_F = 5 class TestIntEnumConvert(unittest.TestCase): def test_convert_value_lookup_priority(self): test_type = enum.IntEnum._convert( - 'UnittestConvert', 'test.test_enum', + 'UnittestConvert', + ('test.test_enum', '__main__')[__name__=='__main__'], filter=lambda x: x.startswith('CONVERT_TEST_')) # We don't want the reverse lookup value to vary when there are # multiple possible names for a given value. It should always @@ -2493,7 +2578,8 @@ class TestIntEnumConvert(unittest.TestCase): def test_convert(self): test_type = enum.IntEnum._convert( - 'UnittestConvert', 'test.test_enum', + 'UnittestConvert', + ('test.test_enum', '__main__')[__name__=='__main__'], filter=lambda x: x.startswith('CONVERT_TEST_')) # Ensure that test_type has all of the desired names and values. self.assertEqual(test_type.CONVERT_TEST_NAME_F, diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index 12f2f11..3da210a 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -9,7 +9,8 @@ from array import array from weakref import proxy from functools import wraps -from test.support import TESTFN, check_warnings, run_unittest, make_bad_fd, cpython_only +from test.support import (TESTFN, TESTFN_UNICODE, check_warnings, run_unittest, + make_bad_fd, cpython_only) from collections import UserList import _io # C implementation of io @@ -432,6 +433,23 @@ class OtherFileTests: finally: os.unlink(TESTFN) + @unittest.skipIf(sys.getfilesystemencoding() != 'utf-8', + "test only works for utf-8 filesystems") + def testUtf8BytesOpen(self): + # Opening a UTF-8 bytes filename + try: + fn = TESTFN_UNICODE.encode("utf-8") + except UnicodeEncodeError: + self.skipTest('could not encode %r to utf-8' % TESTFN_UNICODE) + f = self.FileIO(fn, "w") + try: + f.write(b"abc") + f.close() + with open(TESTFN_UNICODE, "rb") as f: + self.assertEqual(f.read(), b"abc") + finally: + os.unlink(TESTFN_UNICODE) + def testConstructorHandlesNULChars(self): fn_with_NUL = 'foo\0bar' self.assertRaises(ValueError, self.FileIO, fn_with_NUL, 'w') diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index 8afd5b8..83eb29f 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -114,6 +114,7 @@ class FormatTest(unittest.TestCase): testcommon("%o", 100000000000, "1351035564000") testcommon("%d", 10, "10") testcommon("%d", 100000000000, "100000000000") + big = 123456789012345678901234567890 testcommon("%d", big, "123456789012345678901234567890") testcommon("%d", -big, "-123456789012345678901234567890") @@ -133,6 +134,7 @@ class FormatTest(unittest.TestCase): testcommon("%.31d", big, "0123456789012345678901234567890") testcommon("%32.31d", big, " 0123456789012345678901234567890") testcommon("%d", float(big), "123456________________________", 6) + big = 0x1234567890abcdef12345 # 21 hex digits testcommon("%x", big, "1234567890abcdef12345") testcommon("%x", -big, "-1234567890abcdef12345") @@ -156,19 +158,26 @@ class FormatTest(unittest.TestCase): testcommon("%#X", big, "0X1234567890ABCDEF12345") testcommon("%#x", big, "0x1234567890abcdef12345") testcommon("%#x", -big, "-0x1234567890abcdef12345") + testcommon("%#27x", big, " 0x1234567890abcdef12345") + testcommon("%#-27x", big, "0x1234567890abcdef12345 ") + testcommon("%#027x", big, "0x00001234567890abcdef12345") + testcommon("%#.23x", big, "0x001234567890abcdef12345") testcommon("%#.23x", -big, "-0x001234567890abcdef12345") + testcommon("%#27.23x", big, " 0x001234567890abcdef12345") + testcommon("%#-27.23x", big, "0x001234567890abcdef12345 ") + testcommon("%#027.23x", big, "0x00001234567890abcdef12345") testcommon("%#+.23x", big, "+0x001234567890abcdef12345") testcommon("%# .23x", big, " 0x001234567890abcdef12345") testcommon("%#+.23X", big, "+0X001234567890ABCDEF12345") - testcommon("%#-+.23X", big, "+0X001234567890ABCDEF12345") - testcommon("%#-+26.23X", big, "+0X001234567890ABCDEF12345") - testcommon("%#-+27.23X", big, "+0X001234567890ABCDEF12345 ") - testcommon("%#+27.23X", big, " +0X001234567890ABCDEF12345") # next one gets two leading zeroes from precision, and another from the # 0 flag and the width testcommon("%#+027.23X", big, "+0X0001234567890ABCDEF12345") + testcommon("%# 027.23X", big, " 0X0001234567890ABCDEF12345") # same, except no 0 flag testcommon("%#+27.23X", big, " +0X001234567890ABCDEF12345") + testcommon("%#-+27.23x", big, "+0x001234567890abcdef12345 ") + testcommon("%#- 27.23x", big, " 0x001234567890abcdef12345 ") + big = 0o12345670123456701234567012345670 # 32 octal digits testcommon("%o", big, "12345670123456701234567012345670") testcommon("%o", -big, "-12345670123456701234567012345670") @@ -191,51 +200,46 @@ class FormatTest(unittest.TestCase): testcommon("%o", big, "12345670123456701234567012345670") testcommon("%#o", big, "0o12345670123456701234567012345670") testcommon("%#o", -big, "-0o12345670123456701234567012345670") + testcommon("%#38o", big, " 0o12345670123456701234567012345670") + testcommon("%#-38o", big, "0o12345670123456701234567012345670 ") + testcommon("%#038o", big, "0o000012345670123456701234567012345670") + testcommon("%#.34o", big, "0o0012345670123456701234567012345670") testcommon("%#.34o", -big, "-0o0012345670123456701234567012345670") + testcommon("%#38.34o", big, " 0o0012345670123456701234567012345670") + testcommon("%#-38.34o", big, "0o0012345670123456701234567012345670 ") + testcommon("%#038.34o", big, "0o000012345670123456701234567012345670") testcommon("%#+.34o", big, "+0o0012345670123456701234567012345670") testcommon("%# .34o", big, " 0o0012345670123456701234567012345670") - testcommon("%#+.34o", big, "+0o0012345670123456701234567012345670") - testcommon("%#-+.34o", big, "+0o0012345670123456701234567012345670") - testcommon("%#-+37.34o", big, "+0o0012345670123456701234567012345670") - testcommon("%#+37.34o", big, "+0o0012345670123456701234567012345670") + testcommon("%#+38.34o", big, " +0o0012345670123456701234567012345670") + testcommon("%#-+38.34o", big, "+0o0012345670123456701234567012345670 ") + testcommon("%#- 38.34o", big, " 0o0012345670123456701234567012345670 ") + testcommon("%#+038.34o", big, "+0o00012345670123456701234567012345670") + testcommon("%# 038.34o", big, " 0o00012345670123456701234567012345670") # next one gets one leading zero from precision testcommon("%.33o", big, "012345670123456701234567012345670") - # base marker shouldn't change that, since "0" is redundant + # base marker added in spite of leading zero (different to Python 2) testcommon("%#.33o", big, "0o012345670123456701234567012345670") - # but reduce precision, and base marker should add a zero + # reduce precision, and base marker is always added testcommon("%#.32o", big, "0o12345670123456701234567012345670") - # one leading zero from precision, and another from "0" flag & width - testcommon("%034.33o", big, "0012345670123456701234567012345670") - # base marker shouldn't change that - testcommon("%0#34.33o", big, "0o012345670123456701234567012345670") + # one leading zero from precision, plus two from "0" flag & width + testcommon("%035.33o", big, "00012345670123456701234567012345670") + # base marker shouldn't change the size + testcommon("%0#35.33o", big, "0o012345670123456701234567012345670") + # Some small ints, in both Python int and flavors). testcommon("%d", 42, "42") testcommon("%d", -42, "-42") - testcommon("%d", 42, "42") - testcommon("%d", -42, "-42") testcommon("%d", 42.0, "42") testcommon("%#x", 1, "0x1") - testcommon("%#x", 1, "0x1") testcommon("%#X", 1, "0X1") - testcommon("%#X", 1, "0X1") - testcommon("%#o", 1, "0o1") testcommon("%#o", 1, "0o1") testcommon("%#o", 0, "0o0") - testcommon("%#o", 0, "0o0") - testcommon("%o", 0, "0") testcommon("%o", 0, "0") testcommon("%d", 0, "0") - testcommon("%d", 0, "0") testcommon("%#x", 0, "0x0") - testcommon("%#x", 0, "0x0") - testcommon("%#X", 0, "0X0") testcommon("%#X", 0, "0X0") testcommon("%x", 0x42, "42") testcommon("%x", -0x42, "-42") - testcommon("%x", 0x42, "42") - testcommon("%x", -0x42, "-42") - testcommon("%o", 0o42, "42") - testcommon("%o", -0o42, "-42") testcommon("%o", 0o42, "42") testcommon("%o", -0o42, "-42") # alternate float formatting @@ -386,6 +390,13 @@ class FormatTest(unittest.TestCase): else: raise TestFailed('"%*d"%(maxsize, -127) should fail') + def test_nul(self): + # test the null character + testcommon("a\0b", (), 'a\0b') + testcommon("a%cb", (0,), 'a\0b') + testformat("a%sb", ('c\0d',), 'ac\0db') + testcommon(b"a%sb", (b'c\0d',), b'ac\0db') + def test_non_ascii(self): testformat("\u20ac=%f", (1.0,), "\u20ac=1.000000") diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 8205083..708ed25 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -70,18 +70,18 @@ f'{a * x()}'""" # Make sure x was called. self.assertTrue(x.called) - def test_literal_eval(self): - # With no expressions, an f-string is okay. - self.assertEqual(ast.literal_eval("f'x'"), 'x') - self.assertEqual(ast.literal_eval("f'x' 'y'"), 'xy') - - # But this should raise an error. - with self.assertRaisesRegex(ValueError, 'malformed node or string'): - ast.literal_eval("f'x{3}'") + def test_docstring(self): + def f(): + f'''Not a docstring''' + self.assertIsNone(f.__doc__) + def g(): + '''Not a docstring''' \ + f'' + self.assertIsNone(g.__doc__) - # As should this, which uses a different ast node + def test_literal_eval(self): with self.assertRaisesRegex(ValueError, 'malformed node or string'): - ast.literal_eval("f'{3}'") + ast.literal_eval("f'x'") def test_ast_compile_time_concat(self): x = [''] diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 75427df..b7d648d 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -1,4 +1,5 @@ import abc +import builtins import collections import copy from itertools import permutations @@ -6,6 +7,7 @@ import pickle from random import choice import sys from test import support +import time import unittest from weakref import proxy import contextlib @@ -87,6 +89,15 @@ class TestPartial: p(b=7) self.assertEqual(d, {'a':3}) + def test_kwargs_copy(self): + # Issue #29532: Altering a kwarg dictionary passed to a constructor + # should not affect a partial object after creation + d = {'a': 3} + p = self.partial(capture, **d) + self.assertEqual(p(), ((), {'a': 3})) + d['a'] = 5 + self.assertEqual(p(), ((), {'a': 3})) + def test_arg_combinations(self): # exercise special code paths for zero args in either partial # object or the caller @@ -1189,6 +1200,18 @@ class TestLRU: self.assertEqual(misses, 4) self.assertEqual(currsize, 2) + def test_lru_reentrancy_with_len(self): + # Test to make sure the LRU cache code isn't thrown-off by + # caching the built-in len() function. Since len() can be + # cached, we shouldn't use it inside the lru code itself. + old_len = builtins.len + try: + builtins.len = self.module.lru_cache(4)(len) + for i in [0, 0, 1, 2, 3, 3, 4, 5, 6, 1, 7, 2, 1]: + self.assertEqual(len('abcdefghijklmn'[:i]), i) + finally: + builtins.len = old_len + def test_lru_type_error(self): # Regression test for issue #28653. # lru_cache was leaking when one of the arguments @@ -1293,6 +1316,16 @@ class TestLRU: self.assertEqual(fib.cache_info(), self.module._CacheInfo(hits=0, misses=0, maxsize=None, currsize=0)) + def test_kwargs_order(self): + # PEP 468: Preserving Keyword Argument Order + @self.module.lru_cache(maxsize=10) + def f(**kwargs): + return list(kwargs.items()) + self.assertEqual(f(a=1, b=2), [('a', 1), ('b', 2)]) + self.assertEqual(f(b=2, a=1), [('b', 2), ('a', 1)]) + self.assertEqual(f.cache_info(), + self.module._CacheInfo(hits=0, misses=2, maxsize=10, currsize=2)) + def test_lru_cache_decoration(self): def f(zomg: 'zomg_annotation'): """f doc string""" @@ -1322,7 +1355,7 @@ class TestLRU: f.cache_clear() orig_si = sys.getswitchinterval() - sys.setswitchinterval(1e-6) + support.setswitchinterval(1e-6) try: # create n threads in order to fill cache threads = [threading.Thread(target=full, args=[k]) @@ -1378,6 +1411,20 @@ class TestLRU: pause.reset() self.assertEqual(f.cache_info(), (0, (i+1)*n, m*n, i+1)) + @unittest.skipUnless(threading, 'This test requires threading.') + def test_lru_cache_threaded3(self): + @self.module.lru_cache(maxsize=2) + def f(x): + time.sleep(.01) + return 3 * x + def test(i, x): + with self.subTest(thread=i): + self.assertEqual(f(x), 3 * x, i) + threads = [threading.Thread(target=test, args=(i, v)) + for i, v in enumerate([1, 2, 2, 3, 2])] + with support.start_threads(threads): + pass + def test_need_for_rlock(self): # This will deadlock on an LRU cache that uses a regular lock diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index 213b2ba..2f1c410 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -2,6 +2,7 @@ import unittest from test import support +import os import re rx = re.compile(r'\((\S+).py, line (\d+)') @@ -12,6 +13,12 @@ def get_error_location(msg): class FutureTest(unittest.TestCase): + def check_syntax_error(self, err, basename, lineno, offset=0): + self.assertIn('%s.py, line %d' % (basename, lineno), str(err)) + self.assertEqual(os.path.basename(err.filename), basename + '.py') + self.assertEqual(err.lineno, lineno) + self.assertEqual(err.offset, offset) + def test_future1(self): with support.CleanImport('future_test1'): from test import future_test1 @@ -27,68 +34,44 @@ class FutureTest(unittest.TestCase): from test import test_future3 def test_badfuture3(self): - try: + with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future3 - except SyntaxError as msg: - self.assertEqual(get_error_location(msg), ("badsyntax_future3", '3')) - else: - self.fail("expected exception didn't occur") + self.check_syntax_error(cm.exception, "badsyntax_future3", 3) def test_badfuture4(self): - try: + with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future4 - except SyntaxError as msg: - self.assertEqual(get_error_location(msg), ("badsyntax_future4", '3')) - else: - self.fail("expected exception didn't occur") + self.check_syntax_error(cm.exception, "badsyntax_future4", 3) def test_badfuture5(self): - try: + with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future5 - except SyntaxError as msg: - self.assertEqual(get_error_location(msg), ("badsyntax_future5", '4')) - else: - self.fail("expected exception didn't occur") + self.check_syntax_error(cm.exception, "badsyntax_future5", 4) def test_badfuture6(self): - try: + with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future6 - except SyntaxError as msg: - self.assertEqual(get_error_location(msg), ("badsyntax_future6", '3')) - else: - self.fail("expected exception didn't occur") + self.check_syntax_error(cm.exception, "badsyntax_future6", 3) def test_badfuture7(self): - try: + with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future7 - except SyntaxError as msg: - self.assertEqual(get_error_location(msg), ("badsyntax_future7", '3')) - else: - self.fail("expected exception didn't occur") + self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53) def test_badfuture8(self): - try: + with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future8 - except SyntaxError as msg: - self.assertEqual(get_error_location(msg), ("badsyntax_future8", '3')) - else: - self.fail("expected exception didn't occur") + self.check_syntax_error(cm.exception, "badsyntax_future8", 3) def test_badfuture9(self): - try: + with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future9 - except SyntaxError as msg: - self.assertEqual(get_error_location(msg), ("badsyntax_future9", '3')) - else: - self.fail("expected exception didn't occur") + self.check_syntax_error(cm.exception, "badsyntax_future9", 3, 0) def test_badfuture10(self): - try: + with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future10 - except SyntaxError as msg: - self.assertEqual(get_error_location(msg), ("badsyntax_future10", '3')) - else: - self.fail("expected exception didn't occur") + self.check_syntax_error(cm.exception, "badsyntax_future10", 3, 0) def test_parserhack(self): # test that the parser.c::future_hack function works as expected diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index ae5dd6a..f698e13 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -8,6 +8,7 @@ import sys import unittest import warnings from test import support +android_not_root = support.android_not_root def create_file(filename, data=b'foo'): @@ -212,6 +213,7 @@ class GenericTest: def test_samefile_on_symlink(self): self._test_samefile_on_link_func(os.symlink) + @unittest.skipIf(android_not_root, "hard links not allowed, non root user") def test_samefile_on_link(self): self._test_samefile_on_link_func(os.link) @@ -251,6 +253,7 @@ class GenericTest: def test_samestat_on_symlink(self): self._test_samestat_on_link_func(os.symlink) + @unittest.skipIf(android_not_root, "hard links not allowed, non root user") def test_samestat_on_link(self): self._test_samestat_on_link_func(os.link) diff --git a/Lib/test/test_global.py b/Lib/test/test_global.py index 37ec672..9eeccf1 100644 --- a/Lib/test/test_global.py +++ b/Lib/test/test_global.py @@ -24,7 +24,7 @@ def wrong1(): global a global b """ - check_syntax_error(self, prog_text_1) + check_syntax_error(self, prog_text_1, lineno=4, offset=4) def test2(self): prog_text_2 = """\ @@ -32,7 +32,7 @@ def wrong2(): print(x) global x """ - check_syntax_error(self, prog_text_2) + check_syntax_error(self, prog_text_2, lineno=3, offset=4) def test3(self): prog_text_3 = """\ @@ -41,7 +41,7 @@ def wrong3(): x = 2 global x """ - check_syntax_error(self, prog_text_3) + check_syntax_error(self, prog_text_3, lineno=4, offset=4) def test4(self): prog_text_4 = """\ diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 63ac810..fac6b57 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -10,10 +10,12 @@ import os.path import socketserver import time import calendar +import inspect from test.support import (reap_threads, verbose, transient_internet, run_with_tz, run_with_locale) import unittest +from unittest import mock from datetime import datetime, timezone, timedelta try: import ssl @@ -174,6 +176,334 @@ class SimpleIMAPHandler(socketserver.StreamRequestHandler): self._send_tagged(tag, 'OK', 'LOGIN completed') +class NewIMAPTestsMixin(): + client = None + + def _setup(self, imap_handler, connect=True): + """ + Sets up imap_handler for tests. imap_handler should inherit from either: + - SimpleIMAPHandler - for testing IMAP commands, + - socketserver.StreamRequestHandler - if raw access to stream is needed. + Returns (client, server). + """ + class TestTCPServer(self.server_class): + def handle_error(self, request, client_address): + """ + End request and raise the error if one occurs. + """ + self.close_request(request) + self.server_close() + raise + + self.addCleanup(self._cleanup) + self.server = self.server_class((support.HOST, 0), imap_handler) + self.thread = threading.Thread( + name=self._testMethodName+'-server', + target=self.server.serve_forever, + # Short poll interval to make the test finish quickly. + # Time between requests is short enough that we won't wake + # up spuriously too many times. + kwargs={'poll_interval': 0.01}) + self.thread.daemon = True # In case this function raises. + self.thread.start() + + if connect: + self.client = self.imap_class(*self.server.server_address) + + return self.client, self.server + + def _cleanup(self): + """ + Cleans up the test server. This method should not be called manually, + it is added to the cleanup queue in the _setup method already. + """ + # if logout was called already we'd raise an exception trying to + # shutdown the client once again + if self.client is not None and self.client.state != 'LOGOUT': + self.client.shutdown() + # cleanup the server + self.server.shutdown() + self.server.server_close() + self.thread.join(3.0) + + def test_EOF_without_complete_welcome_message(self): + # http://bugs.python.org/issue5949 + class EOFHandler(socketserver.StreamRequestHandler): + def handle(self): + self.wfile.write(b'* OK') + _, server = self._setup(EOFHandler, connect=False) + self.assertRaises(imaplib.IMAP4.abort, self.imap_class, + *server.server_address) + + def test_line_termination(self): + class BadNewlineHandler(SimpleIMAPHandler): + def cmd_CAPABILITY(self, tag, args): + self._send(b'* CAPABILITY IMAP4rev1 AUTH\n') + self._send_tagged(tag, 'OK', 'CAPABILITY completed') + _, server = self._setup(BadNewlineHandler, connect=False) + self.assertRaises(imaplib.IMAP4.abort, self.imap_class, + *server.server_address) + + def test_enable_raises_error_if_not_AUTH(self): + class EnableHandler(SimpleIMAPHandler): + capabilities = 'AUTH ENABLE UTF8=ACCEPT' + client, _ = self._setup(EnableHandler) + self.assertFalse(client.utf8_enabled) + with self.assertRaisesRegex(imaplib.IMAP4.error, 'ENABLE.*NONAUTH'): + client.enable('foo') + self.assertFalse(client.utf8_enabled) + + def test_enable_raises_error_if_no_capability(self): + client, _ = self._setup(SimpleIMAPHandler) + with self.assertRaisesRegex(imaplib.IMAP4.error, + 'does not support ENABLE'): + client.enable('foo') + + def test_enable_UTF8_raises_error_if_not_supported(self): + client, _ = self._setup(SimpleIMAPHandler) + typ, data = client.login('user', 'pass') + self.assertEqual(typ, 'OK') + with self.assertRaisesRegex(imaplib.IMAP4.error, + 'does not support ENABLE'): + client.enable('UTF8=ACCEPT') + + def test_enable_UTF8_True_append(self): + class UTF8AppendServer(SimpleIMAPHandler): + capabilities = 'ENABLE UTF8=ACCEPT' + def cmd_ENABLE(self, tag, args): + self._send_tagged(tag, 'OK', 'ENABLE successful') + def cmd_AUTHENTICATE(self, tag, args): + self._send_textline('+') + self.server.response = yield + self._send_tagged(tag, 'OK', 'FAKEAUTH successful') + def cmd_APPEND(self, tag, args): + self._send_textline('+') + self.server.response = yield + self._send_tagged(tag, 'OK', 'okay') + client, server = self._setup(UTF8AppendServer) + self.assertEqual(client._encoding, 'ascii') + code, _ = client.authenticate('MYAUTH', lambda x: b'fake') + self.assertEqual(code, 'OK') + self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake' + code, _ = client.enable('UTF8=ACCEPT') + self.assertEqual(code, 'OK') + self.assertEqual(client._encoding, 'utf-8') + msg_string = 'Subject: üñí©öðé' + typ, data = client.append(None, None, None, msg_string.encode('utf-8')) + self.assertEqual(typ, 'OK') + self.assertEqual(server.response, + ('UTF8 (%s)\r\n' % msg_string).encode('utf-8')) + + def test_search_disallows_charset_in_utf8_mode(self): + class UTF8Server(SimpleIMAPHandler): + capabilities = 'AUTH ENABLE UTF8=ACCEPT' + def cmd_ENABLE(self, tag, args): + self._send_tagged(tag, 'OK', 'ENABLE successful') + def cmd_AUTHENTICATE(self, tag, args): + self._send_textline('+') + self.server.response = yield + self._send_tagged(tag, 'OK', 'FAKEAUTH successful') + client, _ = self._setup(UTF8Server) + typ, _ = client.authenticate('MYAUTH', lambda x: b'fake') + self.assertEqual(typ, 'OK') + typ, _ = client.enable('UTF8=ACCEPT') + self.assertEqual(typ, 'OK') + self.assertTrue(client.utf8_enabled) + with self.assertRaisesRegex(imaplib.IMAP4.error, 'charset.*UTF8'): + client.search('foo', 'bar') + + def test_bad_auth_name(self): + class MyServer(SimpleIMAPHandler): + def cmd_AUTHENTICATE(self, tag, args): + self._send_tagged(tag, 'NO', + 'unrecognized authentication type {}'.format(args[0])) + client, _ = self._setup(MyServer) + with self.assertRaisesRegex(imaplib.IMAP4.error, + 'unrecognized authentication type METHOD'): + client.authenticate('METHOD', lambda: 1) + + def test_invalid_authentication(self): + class MyServer(SimpleIMAPHandler): + def cmd_AUTHENTICATE(self, tag, args): + self._send_textline('+') + self.response = yield + self._send_tagged(tag, 'NO', '[AUTHENTICATIONFAILED] invalid') + client, _ = self._setup(MyServer) + with self.assertRaisesRegex(imaplib.IMAP4.error, + r'\[AUTHENTICATIONFAILED\] invalid'): + client.authenticate('MYAUTH', lambda x: b'fake') + + def test_valid_authentication_bytes(self): + class MyServer(SimpleIMAPHandler): + def cmd_AUTHENTICATE(self, tag, args): + self._send_textline('+') + self.server.response = yield + self._send_tagged(tag, 'OK', 'FAKEAUTH successful') + client, server = self._setup(MyServer) + code, _ = client.authenticate('MYAUTH', lambda x: b'fake') + self.assertEqual(code, 'OK') + self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake' + + def test_valid_authentication_plain_text(self): + class MyServer(SimpleIMAPHandler): + def cmd_AUTHENTICATE(self, tag, args): + self._send_textline('+') + self.server.response = yield + self._send_tagged(tag, 'OK', 'FAKEAUTH successful') + client, server = self._setup(MyServer) + code, _ = client.authenticate('MYAUTH', lambda x: 'fake') + self.assertEqual(code, 'OK') + self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake' + + def test_login_cram_md5_bytes(self): + class AuthHandler(SimpleIMAPHandler): + capabilities = 'LOGINDISABLED AUTH=CRAM-MD5' + def cmd_AUTHENTICATE(self, tag, args): + self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm' + 'VzdG9uLm1jaS5uZXQ=') + r = yield + if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT' + b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'): + self._send_tagged(tag, 'OK', 'CRAM-MD5 successful') + else: + self._send_tagged(tag, 'NO', 'No access') + client, _ = self._setup(AuthHandler) + self.assertTrue('AUTH=CRAM-MD5' in client.capabilities) + ret, _ = client.login_cram_md5("tim", b"tanstaaftanstaaf") + self.assertEqual(ret, "OK") + + def test_login_cram_md5_plain_text(self): + class AuthHandler(SimpleIMAPHandler): + capabilities = 'LOGINDISABLED AUTH=CRAM-MD5' + def cmd_AUTHENTICATE(self, tag, args): + self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm' + 'VzdG9uLm1jaS5uZXQ=') + r = yield + if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT' + b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'): + self._send_tagged(tag, 'OK', 'CRAM-MD5 successful') + else: + self._send_tagged(tag, 'NO', 'No access') + client, _ = self._setup(AuthHandler) + self.assertTrue('AUTH=CRAM-MD5' in client.capabilities) + ret, _ = client.login_cram_md5("tim", "tanstaaftanstaaf") + self.assertEqual(ret, "OK") + + def test_aborted_authentication(self): + class MyServer(SimpleIMAPHandler): + def cmd_AUTHENTICATE(self, tag, args): + self._send_textline('+') + self.response = yield + if self.response == b'*\r\n': + self._send_tagged( + tag, + 'NO', + '[AUTHENTICATIONFAILED] aborted') + else: + self._send_tagged(tag, 'OK', 'MYAUTH successful') + client, _ = self._setup(MyServer) + with self.assertRaisesRegex(imaplib.IMAP4.error, + r'\[AUTHENTICATIONFAILED\] aborted'): + client.authenticate('MYAUTH', lambda x: None) + + @mock.patch('imaplib._MAXLINE', 10) + def test_linetoolong(self): + class TooLongHandler(SimpleIMAPHandler): + def handle(self): + # send response line longer than the limit set in the next line + self.wfile.write(b'* OK ' + 11 * b'x' + b'\r\n') + _, server = self._setup(TooLongHandler, connect=False) + with self.assertRaisesRegex(imaplib.IMAP4.error, + 'got more than 10 bytes'): + self.imap_class(*server.server_address) + + def test_simple_with_statement(self): + _, server = self._setup(SimpleIMAPHandler, connect=False) + with self.imap_class(*server.server_address): + pass + + def test_with_statement(self): + _, server = self._setup(SimpleIMAPHandler, connect=False) + with self.imap_class(*server.server_address) as imap: + imap.login('user', 'pass') + self.assertEqual(server.logged, 'user') + self.assertIsNone(server.logged) + + def test_with_statement_logout(self): + # It is legal to log out explicitly inside the with block + _, server = self._setup(SimpleIMAPHandler, connect=False) + with self.imap_class(*server.server_address) as imap: + imap.login('user', 'pass') + self.assertEqual(server.logged, 'user') + imap.logout() + self.assertIsNone(server.logged) + self.assertIsNone(server.logged) + + # command tests + + def test_login(self): + client, _ = self._setup(SimpleIMAPHandler) + typ, data = client.login('user', 'pass') + self.assertEqual(typ, 'OK') + self.assertEqual(data[0], b'LOGIN completed') + self.assertEqual(client.state, 'AUTH') + + def test_logout(self): + client, _ = self._setup(SimpleIMAPHandler) + typ, data = client.login('user', 'pass') + self.assertEqual(typ, 'OK') + self.assertEqual(data[0], b'LOGIN completed') + typ, data = client.logout() + self.assertEqual(typ, 'BYE') + self.assertEqual(data[0], b'IMAP4ref1 Server logging out') + self.assertEqual(client.state, 'LOGOUT') + + def test_lsub(self): + class LsubCmd(SimpleIMAPHandler): + def cmd_LSUB(self, tag, args): + self._send_textline('* LSUB () "." directoryA') + return self._send_tagged(tag, 'OK', 'LSUB completed') + client, _ = self._setup(LsubCmd) + client.login('user', 'pass') + typ, data = client.lsub() + self.assertEqual(typ, 'OK') + self.assertEqual(data[0], b'() "." directoryA') + + +class NewIMAPTests(NewIMAPTestsMixin, unittest.TestCase): + imap_class = imaplib.IMAP4 + server_class = socketserver.TCPServer + + +@unittest.skipUnless(ssl, "SSL not available") +class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): + imap_class = IMAP4_SSL + server_class = SecureTCPServer + + def test_ssl_raises(self): + ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + ssl_context.verify_mode = ssl.CERT_REQUIRED + ssl_context.check_hostname = True + ssl_context.load_verify_locations(CAFILE) + + with self.assertRaisesRegex(ssl.CertificateError, + "hostname '127.0.0.1' doesn't match 'localhost'"): + _, server = self._setup(SimpleIMAPHandler) + client = self.imap_class(*server.server_address, + ssl_context=ssl_context) + client.shutdown() + + def test_ssl_verified(self): + ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + ssl_context.verify_mode = ssl.CERT_REQUIRED + ssl_context.check_hostname = True + ssl_context.load_verify_locations(CAFILE) + + _, server = self._setup(SimpleIMAPHandler) + client = self.imap_class("localhost", server.server_address[1], + ssl_context=ssl_context) + client.shutdown() + class ThreadedNetworkedTests(unittest.TestCase): server_class = socketserver.TCPServer imap_class = imaplib.IMAP4 diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py index b2aadff..dbce9c2 100644 --- a/Lib/test/test_importlib/test_locks.py +++ b/Lib/test/test_importlib/test_locks.py @@ -57,7 +57,7 @@ if threading is not None: def setUp(self): try: self.old_switchinterval = sys.getswitchinterval() - sys.setswitchinterval(0.000001) + support.setswitchinterval(0.000001) except AttributeError: self.old_switchinterval = None diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 97634e5..88eaabe 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -402,6 +402,11 @@ class TestRetrievingSourceCode(GetSourceBase): # Check filename override self.assertEqual(inspect.getmodule(None, modfile), mod) + def test_getframeinfo_get_first_line(self): + frame_info = inspect.getframeinfo(self.fodderModule.fr, 50) + self.assertEqual(frame_info.code_context[0], "# line 1\n") + self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n") + def test_getsource(self): self.assertSourceEqual(git.abuse, 29, 39) self.assertSourceEqual(mod.StupidGit, 21, 51) diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index fae2c3d..99fab58 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -1,4 +1,4 @@ -from test.support import verbose +from test.support import verbose, is_android import unittest import locale import sys @@ -353,7 +353,7 @@ class TestEnUSCollation(BaseLocalizedTest, TestCollation): enc = codecs.lookup(locale.getpreferredencoding(False) or 'ascii').name if enc not in ('utf-8', 'iso8859-1', 'cp1252'): raise unittest.SkipTest('encoding not suitable') - if enc != 'iso8859-1' and (sys.platform == 'darwin' or + if enc != 'iso8859-1' and (sys.platform == 'darwin' or is_android or sys.platform.startswith('freebsd')): raise unittest.SkipTest('wcscoll/wcsxfrm have known bugs') BaseLocalizedTest.setUp(self) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 08cdd7f..9dedc09 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1,4 +1,4 @@ -# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2017 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -16,7 +16,7 @@ """Test harness for the logging module. Run all tests. -Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2017 Vinay Sajip. All Rights Reserved. """ import logging @@ -313,6 +313,14 @@ class BuiltinLevelsTest(BaseTest): fatal = logging.getLevelName('FATAL') self.assertEqual(fatal, logging.FATAL) + def test_regression_29220(self): + """See issue #29220 for more information.""" + logging.addLevelName(logging.INFO, '') + self.addCleanup(logging.addLevelName, logging.INFO, 'INFO') + self.assertEqual(logging.getLevelName(logging.INFO), '') + self.assertEqual(logging.getLevelName(logging.NOTSET), 'NOTSET') + self.assertEqual(logging.getLevelName('NOTSET'), logging.NOTSET) + class BasicFilterTest(BaseTest): """Test the bundled Filter class.""" @@ -1440,9 +1448,17 @@ class SocketHandlerTest(BaseTest): """Set up a TCP server to receive log messages, and a SocketHandler pointing to that server's address and port.""" BaseTest.setUp(self) - self.server = server = self.server_class(self.address, - self.handle_socket, 0.01) - server.start() + # Issue #29177: deal with errors that happen during setup + self.server = self.sock_hdlr = self.server_exception = None + try: + self.server = server = self.server_class(self.address, + self.handle_socket, 0.01) + server.start() + # Uncomment next line to test error recovery in setUp() + # raise OSError('dummy error raised') + except OSError as e: + self.server_exception = e + return server.ready.wait() hcls = logging.handlers.SocketHandler if isinstance(server.server_address, tuple): @@ -1457,9 +1473,11 @@ class SocketHandlerTest(BaseTest): def tearDown(self): """Shutdown the TCP server.""" try: - self.server.stop(2.0) - self.root_logger.removeHandler(self.sock_hdlr) - self.sock_hdlr.close() + if self.server: + self.server.stop(2.0) + if self.sock_hdlr: + self.root_logger.removeHandler(self.sock_hdlr) + self.sock_hdlr.close() finally: BaseTest.tearDown(self) @@ -1480,6 +1498,8 @@ class SocketHandlerTest(BaseTest): def test_output(self): # The log message sent to the SocketHandler is properly received. + if self.server_exception: + self.skipTest(self.server_exception) logger = logging.getLogger("tcp") logger.error("spam") self.handled.acquire() @@ -1488,6 +1508,8 @@ class SocketHandlerTest(BaseTest): self.assertEqual(self.log_output, "spam\neggs\n") def test_noserver(self): + if self.server_exception: + self.skipTest(self.server_exception) # Avoid timing-related failures due to SocketHandler's own hard-wired # one-second timeout on socket.create_connection() (issue #16264). self.sock_hdlr.retryStart = 2.5 @@ -1528,7 +1550,7 @@ class UnixSocketHandlerTest(SocketHandlerTest): def tearDown(self): SocketHandlerTest.tearDown(self) - os.remove(self.address) + support.unlink(self.address) @unittest.skipUnless(threading, 'Threading required for this test.') class DatagramHandlerTest(BaseTest): @@ -1543,9 +1565,17 @@ class DatagramHandlerTest(BaseTest): """Set up a UDP server to receive log messages, and a DatagramHandler pointing to that server's address and port.""" BaseTest.setUp(self) - self.server = server = self.server_class(self.address, - self.handle_datagram, 0.01) - server.start() + # Issue #29177: deal with errors that happen during setup + self.server = self.sock_hdlr = self.server_exception = None + try: + self.server = server = self.server_class(self.address, + self.handle_datagram, 0.01) + server.start() + # Uncomment next line to test error recovery in setUp() + # raise OSError('dummy error raised') + except OSError as e: + self.server_exception = e + return server.ready.wait() hcls = logging.handlers.DatagramHandler if isinstance(server.server_address, tuple): @@ -1560,9 +1590,11 @@ class DatagramHandlerTest(BaseTest): def tearDown(self): """Shutdown the UDP server.""" try: - self.server.stop(2.0) - self.root_logger.removeHandler(self.sock_hdlr) - self.sock_hdlr.close() + if self.server: + self.server.stop(2.0) + if self.sock_hdlr: + self.root_logger.removeHandler(self.sock_hdlr) + self.sock_hdlr.close() finally: BaseTest.tearDown(self) @@ -1576,6 +1608,8 @@ class DatagramHandlerTest(BaseTest): def test_output(self): # The log message sent to the DatagramHandler is properly received. + if self.server_exception: + self.skipTest(self.server_exception) logger = logging.getLogger("udp") logger.error("spam") self.handled.wait() @@ -1600,7 +1634,7 @@ class UnixDatagramHandlerTest(DatagramHandlerTest): def tearDown(self): DatagramHandlerTest.tearDown(self) - os.remove(self.address) + support.unlink(self.address) @unittest.skipUnless(threading, 'Threading required for this test.') class SysLogHandlerTest(BaseTest): @@ -1615,9 +1649,17 @@ class SysLogHandlerTest(BaseTest): """Set up a UDP server to receive log messages, and a SysLogHandler pointing to that server's address and port.""" BaseTest.setUp(self) - self.server = server = self.server_class(self.address, - self.handle_datagram, 0.01) - server.start() + # Issue #29177: deal with errors that happen during setup + self.server = self.sl_hdlr = self.server_exception = None + try: + self.server = server = self.server_class(self.address, + self.handle_datagram, 0.01) + server.start() + # Uncomment next line to test error recovery in setUp() + # raise OSError('dummy error raised') + except OSError as e: + self.server_exception = e + return server.ready.wait() hcls = logging.handlers.SysLogHandler if isinstance(server.server_address, tuple): @@ -1630,11 +1672,13 @@ class SysLogHandlerTest(BaseTest): self.handled = threading.Event() def tearDown(self): - """Shutdown the UDP server.""" + """Shutdown the server.""" try: - self.server.stop(2.0) - self.root_logger.removeHandler(self.sl_hdlr) - self.sl_hdlr.close() + if self.server: + self.server.stop(2.0) + if self.sl_hdlr: + self.root_logger.removeHandler(self.sl_hdlr) + self.sl_hdlr.close() finally: BaseTest.tearDown(self) @@ -1643,6 +1687,8 @@ class SysLogHandlerTest(BaseTest): self.handled.set() def test_output(self): + if self.server_exception: + self.skipTest(self.server_exception) # The log message sent to the SysLogHandler is properly received. logger = logging.getLogger("slh") logger.error("sp\xe4m") @@ -1675,7 +1721,7 @@ class UnixSysLogHandlerTest(SysLogHandlerTest): def tearDown(self): SysLogHandlerTest.tearDown(self) - os.remove(self.address) + support.unlink(self.address) @unittest.skipUnless(threading, 'Threading required for this test.') class HTTPHandlerTest(BaseTest): diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index aeabdbb..2ba9443 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -2137,9 +2137,9 @@ class MaildirTestCase(unittest.TestCase): if mbox: fp.write(FROM_) fp.write(DUMMY_MESSAGE) - if hasattr(os, "link"): + try: os.link(tmpname, newname) - else: + except (AttributeError, PermissionError): with open(newname, "w") as fp: fp.write(DUMMY_MESSAGE) self._msgfiles.append(newname) diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index feaba3c..c46ded1 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -132,6 +132,8 @@ class NetworkedNNTPTestsMixin: self.assertLessEqual(art_num, last) self._check_art_dict(art_dict) + @unittest.skipIf(True, 'temporarily skipped until a permanent solution' + ' is found for issue #28971') def test_over(self): resp, count, first, last, name = self.server.group(self.GROUP_NAME) start = last - 10 diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py index a35ed12..93f812a 100644 --- a/Lib/test/test_ordered_dict.py +++ b/Lib/test/test_ordered_dict.py @@ -52,6 +52,14 @@ class OrderedDictTests: self.assertEqual(list(d.items()), [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) + def test_468(self): + OrderedDict = self.OrderedDict + items = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)] + shuffle(items) + argdict = OrderedDict(items) + d = OrderedDict(**argdict) + self.assertEqual(list(d.items()), items) + def test_update(self): OrderedDict = self.OrderedDict with self.assertRaises(TypeError): diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index f98c1fe..88a93e5 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -10,6 +10,7 @@ import tempfile import unittest from test import support +android_not_root = support.android_not_root TESTFN = support.TESTFN try: @@ -1775,6 +1776,17 @@ class _BasePathTest(object): self.assertTrue(p.exists()) self.assertEqual(p.stat().st_ctime, st_ctime_first) + @only_nt # XXX: not sure how to test this on POSIX + def test_mkdir_with_unknown_drive(self): + for d in 'ZYXWVUTSRQPONMLKJIHGFEDCBA': + p = self.cls(d + ':\\') + if not p.is_dir(): + break + else: + self.skipTest("cannot find a drive that doesn't exist") + with self.assertRaises(OSError): + (p / 'child' / 'path').mkdir(parents=True) + def test_mkdir_with_child_file(self): p = self.cls(BASE, 'dirB', 'fileB') self.assertTrue(p.exists()) @@ -1864,6 +1876,7 @@ class _BasePathTest(object): self.assertFalse((P / 'fileA' / 'bah').is_fifo()) @unittest.skipUnless(hasattr(os, "mkfifo"), "os.mkfifo() required") + @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user") def test_is_fifo_true(self): P = self.cls(BASE, 'myfifo') os.mkfifo(str(P)) @@ -1886,7 +1899,8 @@ class _BasePathTest(object): try: sock.bind(str(P)) except OSError as e: - if "AF_UNIX path too long" in str(e): + if (isinstance(e, PermissionError) or + "AF_UNIX path too long" in str(e)): self.skipTest("cannot bind Unix socket: " + str(e)) self.assertTrue(P.is_socket()) self.assertFalse(P.is_fifo()) @@ -2080,6 +2094,8 @@ class PosixPathTest(_BasePathTest, unittest.TestCase): self.assertEqual(given, expect) self.assertEqual(set(p.rglob("FILEd*")), set()) + @unittest.skipUnless(hasattr(pwd, 'getpwall'), + 'pwd module does not expose getpwall()') def test_expanduser(self): P = self.cls support.import_module('pwd') diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 5f875ef..ea6752b 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -67,12 +67,12 @@ class PlatformTest(unittest.TestCase): def setUp(self): self.save_version = sys.version - self.save_mercurial = sys._mercurial + self.save_git = sys._git self.save_platform = sys.platform def tearDown(self): sys.version = self.save_version - sys._mercurial = self.save_mercurial + sys._git = self.save_git sys.platform = self.save_platform def test_sys_version(self): @@ -102,7 +102,7 @@ class PlatformTest(unittest.TestCase): ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')), ): # branch and revision are not "parsed", but fetched - # from sys._mercurial. Ignore them + # from sys._git. Ignore them (name, version, branch, revision, buildno, builddate, compiler) \ = platform._sys_version(input) self.assertEqual( @@ -149,10 +149,10 @@ class PlatformTest(unittest.TestCase): sys_versions.items(): sys.version = version_tag if subversion is None: - if hasattr(sys, "_mercurial"): - del sys._mercurial + if hasattr(sys, "_git"): + del sys._git else: - sys._mercurial = subversion + sys._git = subversion if sys_platform is not None: sys.platform = sys_platform self.assertEqual(platform.python_implementation(), info[0]) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 63c74cd..029d081 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1,6 +1,7 @@ "Test posix functions" from test import support +android_not_root = support.android_not_root # Skip these tests if there is no posix module. posix = support.import_module('posix') @@ -422,6 +423,7 @@ class PosixTester(unittest.TestCase): posix.stat, list(os.fsencode(support.TESTFN))) @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()") + @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user") def test_mkfifo(self): support.unlink(support.TESTFN) posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR) @@ -429,6 +431,7 @@ class PosixTester(unittest.TestCase): @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'), "don't have mknod()/S_IFIFO") + @unittest.skipIf(android_not_root, "mknod not allowed, non root user") def test_mknod(self): # Test using mknod() to create a FIFO (the only use specified # by POSIX). @@ -907,6 +910,7 @@ class PosixTester(unittest.TestCase): posix.close(f) @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()") + @unittest.skipIf(android_not_root, "hard link not allowed, non root user") def test_link_dir_fd(self): f = posix.open(posix.getcwd(), posix.O_RDONLY) try: @@ -930,6 +934,7 @@ class PosixTester(unittest.TestCase): @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'), "test requires both stat.S_IFIFO and dir_fd support for os.mknod()") + @unittest.skipIf(android_not_root, "mknod not allowed, non root user") def test_mknod_dir_fd(self): # Test using mknodat() to create a FIFO (the only use specified # by POSIX). @@ -1013,6 +1018,7 @@ class PosixTester(unittest.TestCase): posix.close(f) @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()") + @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user") def test_mkfifo_dir_fd(self): support.unlink(support.TESTFN) f = posix.open(posix.getcwd(), posix.O_RDONLY) diff --git a/Lib/test/test_pow.py b/Lib/test/test_pow.py index ce99fe6..cac1ae5 100644 --- a/Lib/test/test_pow.py +++ b/Lib/test/test_pow.py @@ -59,9 +59,6 @@ class PowTest(unittest.TestCase): def test_powint(self): self.powtest(int) - def test_powlong(self): - self.powtest(int) - def test_powfloat(self): self.powtest(float) diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index b7b1a4a..ac9cff7 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -4,10 +4,19 @@ from test import support pwd = support.import_module('pwd') +def _getpwall(): + # Android does not have getpwall. + if hasattr(pwd, 'getpwall'): + return pwd.getpwall() + elif hasattr(pwd, 'getpwuid'): + return [pwd.getpwuid(0)] + else: + return [] + class PwdTest(unittest.TestCase): def test_values(self): - entries = pwd.getpwall() + entries = _getpwall() for e in entries: self.assertEqual(len(e), 7) @@ -33,7 +42,7 @@ class PwdTest(unittest.TestCase): # and check afterwards (done in test_values_extended) def test_values_extended(self): - entries = pwd.getpwall() + entries = _getpwall() entriesbyname = {} entriesbyuid = {} @@ -57,12 +66,13 @@ class PwdTest(unittest.TestCase): self.assertRaises(TypeError, pwd.getpwuid, 3.14) self.assertRaises(TypeError, pwd.getpwnam) self.assertRaises(TypeError, pwd.getpwnam, 42) - self.assertRaises(TypeError, pwd.getpwall, 42) + if hasattr(pwd, 'getpwall'): + self.assertRaises(TypeError, pwd.getpwall, 42) # try to get some errors bynames = {} byuids = {} - for (n, p, u, g, gecos, d, s) in pwd.getpwall(): + for (n, p, u, g, gecos, d, s) in _getpwall(): bynames[n] = u byuids[u] = n @@ -96,13 +106,17 @@ class PwdTest(unittest.TestCase): # loop, say), pwd.getpwuid() might still be able to find data for that # uid. Using sys.maxint may provoke the same problems, but hopefully # it will be a more repeatable failure. + # Android accepts a very large span of uids including sys.maxsize and + # -1; it raises KeyError with 1 or 2 for example. fakeuid = sys.maxsize self.assertNotIn(fakeuid, byuids) - self.assertRaises(KeyError, pwd.getpwuid, fakeuid) + if not support.is_android: + self.assertRaises(KeyError, pwd.getpwuid, fakeuid) # -1 shouldn't be a valid uid because it has a special meaning in many # uid-related functions - self.assertRaises(KeyError, pwd.getpwuid, -1) + if not support.is_android: + self.assertRaises(KeyError, pwd.getpwuid, -1) # should be out of uid_t range self.assertRaises(KeyError, pwd.getpwuid, 2**128) self.assertRaises(KeyError, pwd.getpwuid, -2**128) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 4bdaa4b..a506b98 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1402,7 +1402,7 @@ class ReTests(unittest.TestCase): def test_locale_flag(self): import locale - _, enc = locale.getlocale(locale.LC_CTYPE) + enc = locale.getpreferredencoding(False) # Search non-ASCII letter for i in range(128, 256): try: @@ -1824,6 +1824,16 @@ SUBPATTERN None 0 0 warnings.simplefilter('error', BytesWarning) self.assertNotEqual(pattern3, pattern1) + def test_bug_29444(self): + s = bytearray(b'abcdefgh') + m = re.search(b'[a-h]+', s) + m2 = re.search(b'[e-h]+', s) + self.assertEqual(m.group(), b'abcdefgh') + self.assertEqual(m2.group(), b'efgh') + s[:] = b'xyz' + self.assertEqual(m.group(), b'xyz') + self.assertEqual(m2.group(), b'') + class PatternReprTests(unittest.TestCase): def check(self, pattern, expected): diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 52909d8..751df15 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -226,6 +226,8 @@ class ParseArgsTestCase(unittest.TestCase): self.checkError([opt, 'foo'], 'invalid int value') self.checkError([opt, '2', '-T'], "don't go together") self.checkError([opt, '2', '-l'], "don't go together") + self.checkError([opt, '0', '-T'], "don't go together") + self.checkError([opt, '0', '-l'], "don't go together") def test_coverage(self): for opt in '-T', '--coverage': diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py index 2ecae0f..cc9c570 100644 --- a/Lib/test/test_resource.py +++ b/Lib/test/test_resource.py @@ -158,6 +158,20 @@ class ResourceTest(unittest.TestCase): self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, limit), limit) + # Issue 20191: Reference counting bug + @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit') + @support.requires_linux_version(2, 6, 36) + def test_prlimit_refcount(self): + class BadSeq: + def __len__(self): + return 2 + def __getitem__(self, key): + return limits[key] - 1 # new reference + + limits = resource.getrlimit(resource.RLIMIT_AS) + self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, BadSeq()), + limits) + def test_main(verbose=None): support.run_unittest(ResourceTest) diff --git a/Lib/test/test_secrets.py b/Lib/test/test_secrets.py index 4c65cf0..d31d07e 100644 --- a/Lib/test/test_secrets.py +++ b/Lib/test/test_secrets.py @@ -70,6 +70,7 @@ class Random_Tests(unittest.TestCase): for i in range(2, 10): self.assertIn(secrets.randbelow(i), range(i)) self.assertRaises(ValueError, secrets.randbelow, 0) + self.assertRaises(ValueError, secrets.randbelow, -1) class Token_Tests(unittest.TestCase): diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index 3936c97..fd35788 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -273,6 +273,14 @@ class ShlexTest(unittest.TestCase): # white space self.assertEqual(list(s), ['a', '&&', 'b', '||', 'c']) + def testPunctuationWithPosix(self): + """Test that punctuation_chars and posix behave correctly together.""" + # see Issue #29132 + s = shlex.shlex('f >"abc"', posix=True, punctuation_chars=True) + self.assertEqual(list(s), ['f', '>', 'abc']) + s = shlex.shlex('f >\\"abc\\"', posix=True, punctuation_chars=True) + self.assertEqual(list(s), ['f', '>', '"abc"']) + def testEmptyStringHandling(self): """Test that parsing of empty strings is correctly handled.""" # see Issue #21999 diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index af5f00f..2ad3a21 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -19,22 +19,12 @@ from shutil import (make_archive, unregister_unpack_format, get_unpack_formats, SameFileError) import tarfile +import zipfile import warnings from test import support -from test.support import TESTFN, check_warnings, captured_stdout, requires_zlib - -try: - import bz2 - BZ2_SUPPORTED = True -except ImportError: - BZ2_SUPPORTED = False - -try: - import lzma - LZMA_SUPPORTED = True -except ImportError: - LZMA_SUPPORTED = False +from test.support import (TESTFN, check_warnings, captured_stdout, + android_not_root) TESTFN2 = TESTFN + "2" @@ -45,12 +35,6 @@ try: except ImportError: UID_GID_SUPPORT = False -try: - import zipfile - ZIP_SUPPORT = True -except ImportError: - ZIP_SUPPORT = shutil.which('zip') - def _fake_rename(*args, **kwargs): # Pretend the destination path is on a different filesystem. raise OSError(getattr(errno, 'EXDEV', 18), "Invalid cross-device link") @@ -787,6 +771,7 @@ class TestShutil(unittest.TestCase): @unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows') @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') + @unittest.skipIf(android_not_root, "hard links not allowed, non root user") def test_dont_copy_file_onto_link_to_itself(self): # bug 851123. os.mkdir(TESTFN) @@ -839,6 +824,7 @@ class TestShutil(unittest.TestCase): # Issue #3002: copyfile and copytree block indefinitely on named pipes @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()') + @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user") def test_copyfile_named_pipe(self): os.mkfifo(TESTFN) try: @@ -849,6 +835,7 @@ class TestShutil(unittest.TestCase): finally: os.remove(TESTFN) + @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user") @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()') @support.skip_unless_symlink def test_copytree_named_pipe(self): @@ -962,7 +949,7 @@ class TestShutil(unittest.TestCase): self.assertEqual(getattr(file1_stat, 'st_flags'), getattr(file2_stat, 'st_flags')) - @requires_zlib + @support.requires_zlib def test_make_tarball(self): # creating something to tar root_dir, base_dir = self._create_files('') @@ -1018,7 +1005,7 @@ class TestShutil(unittest.TestCase): write_file((root_dir, 'outer'), 'xxx') return root_dir, base_dir - @requires_zlib + @support.requires_zlib @unittest.skipUnless(shutil.which('tar'), 'Need the tar command to run') def test_tarfile_vs_tar(self): @@ -1051,8 +1038,7 @@ class TestShutil(unittest.TestCase): self.assertEqual(tarball, base_name + '.tar') self.assertTrue(os.path.isfile(tarball)) - @requires_zlib - @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @support.requires_zlib def test_make_zipfile(self): # creating something to zip root_dir, base_dir = self._create_files() @@ -1089,8 +1075,7 @@ class TestShutil(unittest.TestCase): ['dist/', 'dist/sub/', 'dist/sub2/', 'dist/file1', 'dist/file2', 'dist/sub/file3']) - @requires_zlib - @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @support.requires_zlib @unittest.skipUnless(shutil.which('zip'), 'Need the zip command to run') def test_zipfile_vs_zip(self): @@ -1116,8 +1101,7 @@ class TestShutil(unittest.TestCase): names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2)) - @requires_zlib - @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @support.requires_zlib @unittest.skipUnless(shutil.which('unzip'), 'Need the unzip command to run') def test_unzip_zipfile(self): @@ -1144,7 +1128,7 @@ class TestShutil(unittest.TestCase): base_name = os.path.join(tmpdir, 'archive') self.assertRaises(ValueError, make_archive, base_name, 'xxx') - @requires_zlib + @support.requires_zlib def test_make_archive_owner_group(self): # testing make_archive with owner and group, with various combinations # this works even if there's not gid/uid support @@ -1172,7 +1156,7 @@ class TestShutil(unittest.TestCase): self.assertTrue(os.path.isfile(res)) - @requires_zlib + @support.requires_zlib @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") def test_tarfile_root_owner(self): root_dir, base_dir = self._create_files() @@ -1217,7 +1201,7 @@ class TestShutil(unittest.TestCase): self.assertEqual(make_archive('test', 'tar'), 'test.tar') self.assertTrue(os.path.isfile('test.tar')) - @requires_zlib + @support.requires_zlib def test_make_zipfile_in_curdir(self): # Issue #21280 root_dir = self.mkdtemp() @@ -1241,33 +1225,46 @@ class TestShutil(unittest.TestCase): formats = [name for name, params in get_archive_formats()] self.assertNotIn('xxx', formats) - @requires_zlib - def test_unpack_archive(self): - formats = ['tar', 'gztar', 'zip'] - if BZ2_SUPPORTED: - formats.append('bztar') - if LZMA_SUPPORTED: - formats.append('xztar') - + def check_unpack_archive(self, format): root_dir, base_dir = self._create_files() expected = rlistdir(root_dir) expected.remove('outer') - for format in formats: - base_name = os.path.join(self.mkdtemp(), 'archive') - filename = make_archive(base_name, format, root_dir, base_dir) - - # let's try to unpack it now - tmpdir2 = self.mkdtemp() - unpack_archive(filename, tmpdir2) - self.assertEqual(rlistdir(tmpdir2), expected) - - # and again, this time with the format specified - tmpdir3 = self.mkdtemp() - unpack_archive(filename, tmpdir3, format=format) - self.assertEqual(rlistdir(tmpdir3), expected) + + base_name = os.path.join(self.mkdtemp(), 'archive') + filename = make_archive(base_name, format, root_dir, base_dir) + + # let's try to unpack it now + tmpdir2 = self.mkdtemp() + unpack_archive(filename, tmpdir2) + self.assertEqual(rlistdir(tmpdir2), expected) + + # and again, this time with the format specified + tmpdir3 = self.mkdtemp() + unpack_archive(filename, tmpdir3, format=format) + self.assertEqual(rlistdir(tmpdir3), expected) + self.assertRaises(shutil.ReadError, unpack_archive, TESTFN) self.assertRaises(ValueError, unpack_archive, TESTFN, format='xxx') + def test_unpack_archive_tar(self): + self.check_unpack_archive('tar') + + @support.requires_zlib + def test_unpack_archive_gztar(self): + self.check_unpack_archive('gztar') + + @support.requires_bz2 + def test_unpack_archive_bztar(self): + self.check_unpack_archive('bztar') + + @support.requires_lzma + def test_unpack_archive_xztar(self): + self.check_unpack_archive('xztar') + + @support.requires_zlib + def test_unpack_archive_zip(self): + self.check_unpack_archive('zip') + def test_unpack_registry(self): formats = get_unpack_formats() diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index d245fd5..0620b24 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -511,16 +511,30 @@ class StartupImportTests(unittest.TestCase): os.unlink(_pth_file) os.unlink(exe_file) + @classmethod + def _calc_sys_path_for_underpth_nosite(self, sys_prefix, lines): + sys_path = [] + for line in lines: + if not line or line[0] == '#': + continue + abs_path = os.path.abspath(os.path.join(sys_prefix, line)) + sys_path.append(abs_path) + return sys_path + @unittest.skipUnless(sys.platform == 'win32', "only supported on Windows") def test_underpth_nosite_file(self): libpath = os.path.dirname(os.path.dirname(encodings.__file__)) exe_prefix = os.path.dirname(sys.executable) - exe_file = self._create_underpth_exe([ + pth_lines = [ 'fake-path-name', *[libpath for _ in range(200)], + '', '# comment', - 'import site' - ]) + ] + exe_file = self._create_underpth_exe(pth_lines) + sys_path = self._calc_sys_path_for_underpth_nosite( + os.path.dirname(exe_file), + pth_lines) try: env = os.environ.copy() @@ -529,14 +543,11 @@ class StartupImportTests(unittest.TestCase): rc = subprocess.call([exe_file, '-c', 'import sys; sys.exit(sys.flags.no_site and ' 'len(sys.path) > 200 and ' - '%r in sys.path and %r in sys.path and %r not in sys.path)' % ( - os.path.join(sys.prefix, 'fake-path-name'), - libpath, - os.path.join(sys.prefix, 'from-env'), - )], env=env) + 'sys.path == %r)' % sys_path, + ], env=env) finally: self._cleanup_underpth_exe(exe_file) - self.assertEqual(rc, 0) + self.assertTrue(rc, "sys.path is incorrect") @unittest.skipUnless(sys.platform == 'win32', "only supported on Windows") def test_underpth_file(self): @@ -545,23 +556,26 @@ class StartupImportTests(unittest.TestCase): exe_file = self._create_underpth_exe([ 'fake-path-name', *[libpath for _ in range(200)], + '', '# comment', 'import site' ]) + sys_prefix = os.path.dirname(exe_file) try: env = os.environ.copy() env['PYTHONPATH'] = 'from-env' env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH')) rc = subprocess.call([exe_file, '-c', 'import sys; sys.exit(not sys.flags.no_site and ' - '%r in sys.path and %r in sys.path and %r not in sys.path)' % ( - os.path.join(sys.prefix, 'fake-path-name'), + '%r in sys.path and %r in sys.path and %r not in sys.path and ' + 'all("\\r" not in p and "\\n" not in p for p in sys.path))' % ( + os.path.join(sys_prefix, 'fake-path-name'), libpath, - os.path.join(sys.prefix, 'from-env'), + os.path.join(sys_prefix, 'from-env'), )], env=env) finally: self._cleanup_underpth_exe(exe_file) - self.assertEqual(rc, 0) + self.assertTrue(rc, "sys.path is incorrect") if __name__ == "__main__": diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 59564c9..97dc3cd 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -278,8 +278,14 @@ class ThreadableTest: def clientRun(self, test_func): self.server_ready.wait() - self.clientSetUp() - self.client_ready.set() + try: + self.clientSetUp() + except BaseException as e: + self.queue.put(e) + self.clientTearDown() + return + finally: + self.client_ready.set() if self.server_crashed: self.clientTearDown() return @@ -520,8 +526,11 @@ class ConnectedStreamTestMixin(SocketListeningTestMixin, self.serv_conn = self.cli def clientTearDown(self): - self.serv_conn.close() - self.serv_conn = None + try: + self.serv_conn.close() + self.serv_conn = None + except AttributeError: + pass super().clientTearDown() @@ -540,7 +549,7 @@ class UnixSocketTestBase(SocketTestBase): def bindSock(self, sock): path = tempfile.mktemp(dir=self.dir_path) - sock.bind(path) + support.bind_unix_socket(sock, path) self.addCleanup(support.unlink, path) class UnixStreamBase(UnixSocketTestBase): @@ -4631,7 +4640,7 @@ class TestUnixDomain(unittest.TestCase): def bind(self, sock, path): # Bind the socket try: - sock.bind(path) + support.bind_unix_socket(sock, path) except OSError as e: if str(e) == "AF_UNIX path too long": self.skipTest( @@ -4769,9 +4778,13 @@ def isTipcAvailable(): """ if not hasattr(socket, "AF_TIPC"): return False - if not os.path.isfile("/proc/modules"): + try: + f = open("/proc/modules") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # It's ok if the file does not exist, is a directory or if we + # have not the permission to read it. return False - with open("/proc/modules") as f: + with f: for line in f: if line.startswith("tipc "): return True diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index f1a5938..cd02a6e 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -1,7 +1,7 @@ import unittest import os import sys -from test.support import TESTFN, import_fresh_module +from test.support import TESTFN, import_fresh_module, android_not_root c_stat = import_fresh_module('stat', fresh=['_stat']) py_stat = import_fresh_module('stat', blocked=['_stat']) @@ -168,6 +168,7 @@ class TestFilemode: self.assertS_IS("LNK", st_mode) @unittest.skipUnless(hasattr(os, 'mkfifo'), 'os.mkfifo not available') + @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user") def test_fifo(self): os.mkfifo(TESTFN, 0o700) st_mode, modestr = self.get_mode() diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 4d9d601..be00475 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -412,6 +412,10 @@ class StructTest(unittest.TestCase): for i in range(6, len(test_string) + 1): self.assertRaises(struct.error, struct.unpack_from, fmt, data, i) + # keyword arguments + self.assertEqual(s.unpack_from(buffer=test_string, offset=2), + (b'cd01',)) + def test_pack_into(self): test_string = b'Reykjavik rocks, eow!' writable_buf = array.array('b', b' '*100) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 89de6d1..3c871dd 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -3,6 +3,7 @@ from unittest import mock from test import support import subprocess import sys +import platform import signal import io import os @@ -17,6 +18,11 @@ import gc import textwrap try: + import ctypes +except ImportError: + ctypes = None + +try: import threading except ImportError: threading = None @@ -341,6 +347,16 @@ class ProcessTestCase(BaseTestCase): temp_dir = self._normalize_cwd(temp_dir) self._assert_cwd(temp_dir, sys.executable, cwd=temp_dir) + def test_cwd_with_pathlike(self): + temp_dir = tempfile.gettempdir() + temp_dir = self._normalize_cwd(temp_dir) + + class _PathLikeObj: + def __fspath__(self): + return temp_dir + + self._assert_cwd(temp_dir, sys.executable, cwd=_PathLikeObj()) + @unittest.skipIf(mswindows, "pending resolution of issue #15533") def test_cwd_with_relative_arg(self): # Check that Popen looks for args[0] relative to cwd if args[0] @@ -2498,6 +2514,46 @@ class POSIXProcessTestCase(BaseTestCase): proc.communicate(timeout=999) mock_proc_stdin.close.assert_called_once_with() + _libc_file_extensions = { + 'Linux': 'so.6', + 'Darwin': 'dylib', + } + @unittest.skipIf(not ctypes, 'ctypes module required.') + @unittest.skipIf(platform.uname()[0] not in _libc_file_extensions, + 'Test requires a libc this code can load with ctypes.') + @unittest.skipIf(not sys.executable, 'Test requires sys.executable.') + def test_child_terminated_in_stopped_state(self): + """Test wait() behavior when waitpid returns WIFSTOPPED; issue29335.""" + PTRACE_TRACEME = 0 # From glibc and MacOS (PT_TRACE_ME). + libc_name = 'libc.' + self._libc_file_extensions[platform.uname()[0]] + libc = ctypes.CDLL(libc_name) + if not hasattr(libc, 'ptrace'): + raise unittest.SkipTest('ptrace() required.') + test_ptrace = subprocess.Popen( + [sys.executable, '-c', """if True: + import ctypes + libc = ctypes.CDLL({libc_name!r}) + libc.ptrace({PTRACE_TRACEME}, 0, 0) + """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME) + ]) + if test_ptrace.wait() != 0: + raise unittest.SkipTest('ptrace() failed - unable to test.') + child = subprocess.Popen( + [sys.executable, '-c', """if True: + import ctypes + libc = ctypes.CDLL({libc_name!r}) + libc.ptrace({PTRACE_TRACEME}, 0, 0) + libc.printf(ctypes.c_char_p(0xdeadbeef)) # Crash the process. + """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME) + ]) + try: + returncode = child.wait() + except Exception as e: + child.kill() # Clean up the hung stopped process. + raise e + self.assertNotEqual(0, returncode) + self.assertLess(returncode, 0) # signal death, likely SIGSEGV. + @unittest.skipUnless(mswindows, "Windows specific tests") class Win32ProcessTestCase(BaseTestCase): diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 553822b..e83a4d6 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -240,7 +240,7 @@ class TestSupport(unittest.TestCase): self.assertEqual(cm.exception.errno, errno.EBADF) def test_check_syntax_error(self): - support.check_syntax_error(self, "def class") + support.check_syntax_error(self, "def class", lineno=1, offset=9) with self.assertRaises(AssertionError): support.check_syntax_error(self, "x=1") diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 3047165..dfaee17 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -159,15 +159,17 @@ class SymtableTest(unittest.TestCase): def test_filename_correct(self): ### Bug tickler: SyntaxError file name correct whether error raised ### while parsing or building symbol table. - def checkfilename(brokencode): + def checkfilename(brokencode, offset): try: symtable.symtable(brokencode, "spam", "exec") except SyntaxError as e: self.assertEqual(e.filename, "spam") + self.assertEqual(e.lineno, 1) + self.assertEqual(e.offset, offset) else: self.fail("no SyntaxError for %r" % (brokencode,)) - checkfilename("def f(x): foo)(") # parse-time - checkfilename("def f(x): global x") # symtable-build-time + checkfilename("def f(x): foo)(", 14) # parse-time + checkfilename("def f(x): global x", 10) # symtable-build-time symtable.symtable("pass", b"spam", "exec") with self.assertWarns(DeprecationWarning), \ self.assertRaises(TypeError): diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 80e36fd..7f7e6da 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -544,7 +544,7 @@ from test import support class SyntaxTestCase(unittest.TestCase): def _check_error(self, code, errtext, - filename="", mode="exec", subclass=None): + filename="", mode="exec", subclass=None, lineno=None, offset=None): """Check that compiling code raises SyntaxError with errtext. errtest is a regular expression that must be present in the @@ -559,6 +559,11 @@ class SyntaxTestCase(unittest.TestCase): mo = re.search(errtext, str(err)) if mo is None: self.fail("SyntaxError did not contain '%r'" % (errtext,)) + self.assertEqual(err.filename, filename) + if lineno is not None: + self.assertEqual(err.lineno, lineno) + if offset is not None: + self.assertEqual(err.offset, offset) else: self.fail("compile() did not raise SyntaxError") @@ -569,7 +574,7 @@ class SyntaxTestCase(unittest.TestCase): self._check_error("del f()", "delete") def test_global_err_then_warn(self): - # Bug tickler: The SyntaxError raised for one global statement + # Bug #763201: The SyntaxError raised for one global statement # shouldn't be clobbered by a SyntaxWarning issued for a later one. source = """if 1: def error(a): diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 091e905..a29ca96 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -5,7 +5,8 @@ import subprocess import shutil from copy import copy -from test.support import (run_unittest, TESTFN, unlink, check_warnings, +from test.support import (run_unittest, + import_module, TESTFN, unlink, check_warnings, captured_stdout, skip_unless_symlink, change_cwd) import sysconfig @@ -385,9 +386,12 @@ class TestSysConfig(unittest.TestCase): self.assertIsNotNone(vars['SO']) self.assertEqual(vars['SO'], vars['EXT_SUFFIX']) - @unittest.skipUnless(sys.platform == 'linux', 'Linux-specific test') + @unittest.skipUnless(sys.platform == 'linux' and + hasattr(sys.implementation, '_multiarch'), + 'multiarch-specific test') def test_triplet_in_ext_suffix(self): - import ctypes, platform, re + ctypes = import_module('ctypes') + import platform, re machine = platform.machine() suffix = sysconfig.get_config_var('EXT_SUFFIX') if re.match('(aarch64|arm|mips|ppc|powerpc|s390|sparc)', machine): @@ -395,7 +399,6 @@ class TestSysConfig(unittest.TestCase): if re.match('(i[3-6]86|x86_64)$', machine): if ctypes.sizeof(ctypes.c_char_p()) == 4: self.assertTrue(suffix.endswith('i386-linux-gnu.so') or - suffix.endswith('i686-linux-android.so') or suffix.endswith('x86_64-linux-gnux32.so'), suffix) else: # 8 byte pointer size diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 845e7d4..6b6c4d2 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -170,6 +170,9 @@ class ThreadTests(BaseTestCase): mutex.acquire() self.assertIn(tid, threading._active) self.assertIsInstance(threading._active[tid], threading._DummyThread) + #Issue 29376 + self.assertTrue(threading._active[tid].is_alive()) + self.assertRegex(repr(threading._active[tid]), '_DummyThread') del threading._active[tid] # PyThreadState_SetAsyncExc() is a CPython-only gimmick, not (currently) @@ -462,7 +465,7 @@ class ThreadTests(BaseTestCase): self.addCleanup(sys.setswitchinterval, old_interval) # Make the bug more likely to manifest. - sys.setswitchinterval(1e-6) + test.support.setswitchinterval(1e-6) for i in range(20): t = threading.Thread(target=lambda: None) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index d203ce3..f0070ec 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -12,7 +12,7 @@ from typing import T, KT, VT # Not in __all__. from typing import Union, Optional from typing import Tuple, List, MutableMapping from typing import Callable -from typing import Generic, ClassVar +from typing import Generic, ClassVar, GenericMeta from typing import cast from typing import get_type_hints from typing import no_type_check, no_type_check_decorator @@ -23,6 +23,7 @@ from typing import IO, TextIO, BinaryIO from typing import Pattern, Match import abc import typing +import weakref try: import collections.abc as collections_abc except ImportError: @@ -189,6 +190,10 @@ class TypeVarTests(BaseTestCase): with self.assertRaises(TypeError): TypeVar('X', str, float, bound=Employee) + def test_no_bivariant(self): + with self.assertRaises(ValueError): + TypeVar('T', covariant=True, contravariant=True) + class UnionTests(BaseTestCase): @@ -253,6 +258,11 @@ class UnionTests(BaseTestCase): self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__) u = Union[int, Employee] self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__) + T = TypeVar('T') + u = Union[T, int][int] + self.assertEqual(repr(u), repr(int)) + u = Union[List[int], int] + self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]') def test_cannot_subclass(self): with self.assertRaises(TypeError): @@ -281,6 +291,15 @@ class UnionTests(BaseTestCase): self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int]) self.assertTrue(Union[str, typing.Iterable] == typing.Iterable) + def test_union_compare_other(self): + self.assertNotEqual(Union, object) + self.assertNotEqual(Union, Any) + self.assertNotEqual(ClassVar, Union) + self.assertNotEqual(Optional, Union) + self.assertNotEqual([None], Optional) + self.assertNotEqual(Optional, typing.Mapping) + self.assertNotEqual(Optional[typing.MutableMapping], Union) + def test_optional(self): o = Optional[int] u = Union[int, None] @@ -294,6 +313,15 @@ class UnionTests(BaseTestCase): with self.assertRaises(TypeError): isinstance(42, Union[int, str]) + def test_no_eval_union(self): + u = Union[int, str] + def f(x: u): ... + self.assertIs(get_type_hints(f)['x'], u) + + def test_function_repr_union(self): + def fun() -> int: ... + self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]') + def test_union_str_pattern(self): # Shouldn't crash; see http://bugs.python.org/issue25390 A = Union[str, Pattern] @@ -391,6 +419,8 @@ class CallableTests(BaseTestCase): Callable[[()], int] with self.assertRaises(TypeError): Callable[[int, 1], 2] + with self.assertRaises(TypeError): + Callable[int] def test_callable_instance_works(self): def f(): @@ -536,15 +566,27 @@ class GenericTests(BaseTestCase): Y[str] with self.assertRaises(TypeError): Y[str, str] + self.assertIsSubclass(SimpleMapping[str, int], SimpleMapping) def test_generic_errors(self): T = TypeVar('T') + S = TypeVar('S') with self.assertRaises(TypeError): Generic[T]() with self.assertRaises(TypeError): + Generic[T][T] + with self.assertRaises(TypeError): + Generic[T][S] + with self.assertRaises(TypeError): isinstance([], List[int]) with self.assertRaises(TypeError): issubclass(list, List[int]) + with self.assertRaises(TypeError): + class NewGeneric(Generic): ... + with self.assertRaises(TypeError): + class MyGeneric(Generic[T], Generic[S]): ... + with self.assertRaises(TypeError): + class MyGeneric(List[T], Generic[S]): ... def test_init(self): T = TypeVar('T') @@ -602,8 +644,10 @@ class GenericTests(BaseTestCase): self.assertEqual(repr(typing.Mapping[T, TS][TS, T]), 'typing.Mapping[~TS, ~T]') self.assertEqual(repr(List[Tuple[T, TS]][int, T]), 'typing.List[typing.Tuple[int, ~T]]') - self.assertEqual(repr(List[Tuple[T, T]][List[int]]), - 'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]') + self.assertEqual( + repr(List[Tuple[T, T]][List[int]]), + 'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]' + ) def test_new_repr_bare(self): T = TypeVar('T') @@ -630,6 +674,41 @@ class GenericTests(BaseTestCase): c.bar = 'abc' self.assertEqual(c.__dict__, {'bar': 'abc'}) + def test_subscripted_generics_as_proxies(self): + T = TypeVar('T') + class C(Generic[T]): + x = 'def' + self.assertEqual(C[int].x, 'def') + self.assertEqual(C[C[int]].x, 'def') + C[C[int]].x = 'changed' + self.assertEqual(C.x, 'changed') + self.assertEqual(C[str].x, 'changed') + C[List[str]].z = 'new' + self.assertEqual(C.z, 'new') + self.assertEqual(C[Tuple[int]].z, 'new') + + self.assertEqual(C().x, 'changed') + self.assertEqual(C[Tuple[str]]().z, 'new') + + class D(C[T]): + pass + self.assertEqual(D[int].x, 'changed') + self.assertEqual(D.z, 'new') + D.z = 'from derived z' + D[int].x = 'from derived x' + self.assertEqual(C.x, 'changed') + self.assertEqual(C[int].z, 'new') + self.assertEqual(D.x, 'from derived x') + self.assertEqual(D[str].z, 'from derived z') + + def test_abc_registry_kept(self): + T = TypeVar('T') + class C(Generic[T]): ... + C.register(int) + self.assertIsInstance(1, C) + C[int] + self.assertIsInstance(1, C) + def test_false_subclasses(self): class MyMapping(MutableMapping[str, str]): pass self.assertNotIsInstance({}, MyMapping) @@ -674,8 +753,10 @@ class GenericTests(BaseTestCase): raise NotImplementedError if tp.__args__: KT, VT = tp.__args__ - return all(isinstance(k, KT) and isinstance(v, VT) - for k, v in obj.items()) + return all( + isinstance(k, KT) and isinstance(v, VT) + for k, v in obj.items() + ) self.assertTrue(naive_dict_check({'x': 1}, typing.Dict[str, int])) self.assertFalse(naive_dict_check({1: 'x'}, typing.Dict[str, int])) with self.assertRaises(NotImplementedError): @@ -691,7 +772,7 @@ class GenericTests(BaseTestCase): self.assertFalse(naive_generic_check(Node[str](), Node[int])) self.assertFalse(naive_generic_check(Node[str](), List)) with self.assertRaises(NotImplementedError): - naive_generic_check([1,2,3], Node[int]) + naive_generic_check([1, 2, 3], Node[int]) def naive_list_base_check(obj, tp): # Check if list conforms to a List subclass @@ -718,6 +799,59 @@ class GenericTests(BaseTestCase): self.assertEqual(C.__orig_bases__, (List[T][U][V],)) self.assertEqual(D.__orig_bases__, (C, List[T][U][V])) + def test_subscript_meta(self): + T = TypeVar('T') + self.assertEqual(Type[GenericMeta], Type[GenericMeta]) + self.assertEqual(Union[T, int][GenericMeta], Union[GenericMeta, int]) + self.assertEqual(Callable[..., GenericMeta].__args__, (Ellipsis, GenericMeta)) + + def test_generic_hashes(self): + try: + from test import mod_generics_cache + except ImportError: # for Python 3.4 and previous versions + import mod_generics_cache + class A(Generic[T]): + ... + + class B(Generic[T]): + class A(Generic[T]): + ... + + self.assertEqual(A, A) + self.assertEqual(mod_generics_cache.A[str], mod_generics_cache.A[str]) + self.assertEqual(B.A, B.A) + self.assertEqual(mod_generics_cache.B.A[B.A[str]], + mod_generics_cache.B.A[B.A[str]]) + + self.assertNotEqual(A, B.A) + self.assertNotEqual(A, mod_generics_cache.A) + self.assertNotEqual(A, mod_generics_cache.B.A) + self.assertNotEqual(B.A, mod_generics_cache.A) + self.assertNotEqual(B.A, mod_generics_cache.B.A) + + self.assertNotEqual(A[str], B.A[str]) + self.assertNotEqual(A[List[Any]], B.A[List[Any]]) + self.assertNotEqual(A[str], mod_generics_cache.A[str]) + self.assertNotEqual(A[str], mod_generics_cache.B.A[str]) + self.assertNotEqual(B.A[int], mod_generics_cache.A[int]) + self.assertNotEqual(B.A[List[Any]], mod_generics_cache.B.A[List[Any]]) + + self.assertNotEqual(Tuple[A[str]], Tuple[B.A[str]]) + self.assertNotEqual(Tuple[A[List[Any]]], Tuple[B.A[List[Any]]]) + self.assertNotEqual(Union[str, A[str]], Union[str, mod_generics_cache.A[str]]) + self.assertNotEqual(Union[A[str], A[str]], + Union[A[str], mod_generics_cache.A[str]]) + self.assertNotEqual(typing.FrozenSet[A[str]], + typing.FrozenSet[mod_generics_cache.B.A[str]]) + + if sys.version_info[:2] > (3, 2): + self.assertTrue(repr(Tuple[A[str]]).endswith('.A[str]]')) + self.assertTrue(repr(Tuple[B.A[str]]).endswith('.B.A[str]]')) + self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) + .endswith('mod_generics_cache.A[str]]')) + self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) + .endswith('mod_generics_cache.B.A[str]]')) + def test_extended_generic_rules_eq(self): T = TypeVar('T') U = TypeVar('U') @@ -757,7 +891,10 @@ class GenericTests(BaseTestCase): def test_generic_forward_ref(self): def foobar(x: List[List['CC']]): ... class CC: ... - self.assertEqual(get_type_hints(foobar, globals(), locals()), {'x': List[List[CC]]}) + self.assertEqual( + get_type_hints(foobar, globals(), locals()), + {'x': List[List[CC]]} + ) T = TypeVar('T') AT = Tuple[T, ...] def barfoo(x: AT): ... @@ -812,6 +949,8 @@ class GenericTests(BaseTestCase): Tuple[Generic[T]] with self.assertRaises(TypeError): List[typing._Protocol] + with self.assertRaises(TypeError): + isinstance(1, Generic) def test_type_erasure_special(self): T = TypeVar('T') @@ -830,6 +969,11 @@ class GenericTests(BaseTestCase): class MyDef(typing.DefaultDict[str, T]): ... self.assertIs(MyDef[int]().__class__, MyDef) self.assertIs(MyDef[int]().__orig_class__, MyDef[int]) + # ChainMap was added in 3.3 + if sys.version_info >= (3, 3): + class MyChain(typing.ChainMap[str, T]): ... + self.assertIs(MyChain[int]().__class__, MyChain) + self.assertIs(MyChain[int]().__orig_class__, MyChain[int]) def test_all_repr_eq_any(self): objs = (getattr(typing, el) for el in typing.__all__) @@ -896,6 +1040,14 @@ class GenericTests(BaseTestCase): self.assertEqual(t, copy(t)) self.assertEqual(t, deepcopy(t)) + def test_weakref_all(self): + T = TypeVar('T') + things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any], + Optional[List[int]], typing.Mapping[int, str], + typing.re.Match[bytes], typing.Iterable['whatever']] + for t in things: + self.assertEqual(weakref.ref(t)(), t) + def test_parameterized_slots(self): T = TypeVar('T') class C(Generic[T]): @@ -1070,6 +1222,7 @@ class GenericTests(BaseTestCase): with self.assertRaises(Exception): D[T] + class ClassVarTests(BaseTestCase): def test_basics(self): @@ -1171,6 +1324,19 @@ class ForwardRefTests(BaseTestCase): with self.assertRaises(TypeError): isinstance(42, fr) + def test_forwardref_subclass_type_error(self): + fr = typing._ForwardRef('int') + with self.assertRaises(TypeError): + issubclass(int, fr) + + def test_forward_equality(self): + fr = typing._ForwardRef('int') + self.assertEqual(fr, typing._ForwardRef('int')) + self.assertNotEqual(List['int'], List[int]) + + def test_forward_repr(self): + self.assertEqual(repr(List['int']), "typing.List[_ForwardRef('int')]") + def test_union_forward(self): def foo(a: Union['T']): @@ -1253,6 +1419,15 @@ class ForwardRefTests(BaseTestCase): ith = get_type_hints(C().foo) self.assertEqual(ith, {}) + def test_no_type_check_no_bases(self): + class C: + def meth(self, x: int): ... + @no_type_check + class D(C): + c = C + # verify that @no_type_check never affects bases + self.assertEqual(get_type_hints(C.meth), {'x': int}) + def test_meta_no_type_check(self): @no_type_check_decorator @@ -1292,9 +1467,6 @@ class ForwardRefTests(BaseTestCase): class OverloadTests(BaseTestCase): - def test_overload_exists(self): - from typing import overload - def test_overload_fails(self): from typing import overload @@ -1357,6 +1529,10 @@ if ASYNCIO: exec(ASYNCIO_TESTS) except ImportError: ASYNCIO = False +else: + # fake names for the sake of static analysis + asyncio = None + AwaitableWrapper = AsyncIteratorWrapper = object PY36 = sys.version_info[:2] >= (3, 6) @@ -1368,21 +1544,49 @@ class A: class B(A): x: ClassVar[Optional['B']] = None y: int + b: int class CSub(B): z: ClassVar['CSub'] = B() class G(Generic[T]): lst: ClassVar[List[T]] = [] +class NoneAndForward: + parent: 'NoneAndForward' + meaning: None + class CoolEmployee(NamedTuple): name: str cool: int + +class CoolEmployeeWithDefault(NamedTuple): + name: str + cool: int = 0 + +class XMeth(NamedTuple): + x: int + def double(self): + return 2 * self.x + +class XRepr(NamedTuple): + x: int + y: int = 1 + def __str__(self): + return f'{self.x} -> {self.y}' + def __add__(self, other): + return 0 """ if PY36: exec(PY36_TESTS) +else: + # fake names for the sake of static analysis + ann_module = ann_module2 = ann_module3 = None + A = B = CSub = G = CoolEmployee = CoolEmployeeWithDefault = object + XMeth = XRepr = NoneAndForward = object gth = get_type_hints + class GetTypeHintTests(BaseTestCase): def test_get_type_hints_from_various_objects(self): # For invalid objects should fail with TypeError (not AttributeError etc). @@ -1395,7 +1599,8 @@ class GetTypeHintTests(BaseTestCase): @skipUnless(PY36, 'Python 3.6 required') def test_get_type_hints_modules(self): - self.assertEqual(gth(ann_module), {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str}) + ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str} + self.assertEqual(gth(ann_module), ann_module_type_hints) self.assertEqual(gth(ann_module2), {}) self.assertEqual(gth(ann_module3), {}) @@ -1412,6 +1617,8 @@ class GetTypeHintTests(BaseTestCase): {'y': Optional[ann_module.C]}) self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) self.assertEqual(gth(ann_module.foo), {'x': int}) + self.assertEqual(gth(NoneAndForward, globals()), + {'parent': NoneAndForward, 'meaning': type(None)}) @skipUnless(PY36, 'Python 3.6 required') def test_respect_no_type_check(self): @@ -1428,17 +1635,22 @@ class GetTypeHintTests(BaseTestCase): class Der(ABase): ... self.assertEqual(gth(ABase.meth), {'x': int}) - def test_get_type_hints_for_builins(self): + def test_get_type_hints_for_builtins(self): # Should not fail for built-in classes and functions. self.assertEqual(gth(int), {}) self.assertEqual(gth(type), {}) self.assertEqual(gth(dir), {}) self.assertEqual(gth(len), {}) + self.assertEqual(gth(object.__str__), {}) + self.assertEqual(gth(object().__str__), {}) + self.assertEqual(gth(str.join), {}) def test_previous_behavior(self): def testf(x, y): ... testf.__annotations__['x'] = 'int' self.assertEqual(gth(testf), {'x': int}) + def testg(x: None): ... + self.assertEqual(gth(testg), {'x': type(None)}) def test_get_type_hints_for_object_with_annotations(self): class A: ... @@ -1452,9 +1664,10 @@ class GetTypeHintTests(BaseTestCase): self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__), {'var': typing.ClassVar[ann_module2.CV]}) self.assertEqual(gth(B, globals()), - {'y': int, 'x': ClassVar[Optional[B]]}) + {'y': int, 'x': ClassVar[Optional[B]], 'b': int}) self.assertEqual(gth(CSub, globals()), - {'z': ClassVar[CSub], 'y': int, 'x': ClassVar[Optional[B]]}) + {'z': ClassVar[CSub], 'y': int, 'b': int, + 'x': ClassVar[Optional[B]]}) self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) @@ -1572,6 +1785,14 @@ class CollectionsAbcTests(BaseTestCase): def test_list(self): self.assertIsSubclass(list, typing.List) + def test_deque(self): + self.assertIsSubclass(collections.deque, typing.Deque) + class MyDeque(typing.Deque[int]): ... + self.assertIsInstance(MyDeque(), collections.deque) + + def test_counter(self): + self.assertIsSubclass(collections.Counter, typing.Counter) + def test_set(self): self.assertIsSubclass(set, typing.Set) self.assertNotIsSubclass(frozenset, typing.Set) @@ -1623,13 +1844,10 @@ class CollectionsAbcTests(BaseTestCase): 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_instantiation(self): + self.assertIs(type(typing.DefaultDict()), collections.defaultdict) + self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) + self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) def test_defaultdict_subclass(self): @@ -1642,6 +1860,50 @@ class CollectionsAbcTests(BaseTestCase): self.assertIsSubclass(MyDefDict, collections.defaultdict) self.assertNotIsSubclass(collections.defaultdict, MyDefDict) + @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') + def test_chainmap_instantiation(self): + self.assertIs(type(typing.ChainMap()), collections.ChainMap) + self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) + self.assertIs(type(typing.ChainMap[str, int]()), collections.ChainMap) + class CM(typing.ChainMap[KT, VT]): ... + self.assertIs(type(CM[int, str]()), CM) + + @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') + def test_chainmap_subclass(self): + + class MyChainMap(typing.ChainMap[str, int]): + pass + + cm = MyChainMap() + self.assertIsInstance(cm, MyChainMap) + + self.assertIsSubclass(MyChainMap, collections.ChainMap) + self.assertNotIsSubclass(collections.ChainMap, MyChainMap) + + def test_deque_instantiation(self): + self.assertIs(type(typing.Deque()), collections.deque) + self.assertIs(type(typing.Deque[T]()), collections.deque) + self.assertIs(type(typing.Deque[int]()), collections.deque) + class D(typing.Deque[T]): ... + self.assertIs(type(D[int]()), D) + + def test_counter_instantiation(self): + self.assertIs(type(typing.Counter()), collections.Counter) + self.assertIs(type(typing.Counter[T]()), collections.Counter) + self.assertIs(type(typing.Counter[int]()), collections.Counter) + class C(typing.Counter[T]): ... + self.assertIs(type(C[int]()), C) + + def test_counter_subclass_instantiation(self): + + class MyCounter(typing.Counter[int]): + pass + + d = MyCounter() + self.assertIsInstance(d, MyCounter) + self.assertIsInstance(d, typing.Counter) + self.assertIsInstance(d, collections.Counter) + def test_no_set_instantiation(self): with self.assertRaises(TypeError): typing.Set() @@ -1696,6 +1958,23 @@ class CollectionsAbcTests(BaseTestCase): with self.assertRaises(TypeError): typing.Generator[int, int, int]() + @skipUnless(PY36, 'Python 3.6 required') + def test_async_generator(self): + ns = {} + exec("async def f():\n" + " yield 42\n", globals(), ns) + g = ns['f']() + self.assertIsSubclass(type(g), typing.AsyncGenerator) + + @skipUnless(PY36, 'Python 3.6 required') + def test_no_async_generator_instantiation(self): + with self.assertRaises(TypeError): + typing.AsyncGenerator() + with self.assertRaises(TypeError): + typing.AsyncGenerator[T, T]() + with self.assertRaises(TypeError): + typing.AsyncGenerator[int, int]() + def test_subclassing(self): class MMA(typing.MutableMapping): @@ -1765,6 +2044,31 @@ class CollectionsAbcTests(BaseTestCase): self.assertIsSubclass(G, collections.Iterable) self.assertNotIsSubclass(type(g), G) + @skipUnless(PY36, 'Python 3.6 required') + def test_subclassing_async_generator(self): + class G(typing.AsyncGenerator[int, int]): + def asend(self, value): + pass + def athrow(self, typ, val=None, tb=None): + pass + + ns = {} + exec('async def g(): yield 0', globals(), ns) + g = ns['g'] + self.assertIsSubclass(G, typing.AsyncGenerator) + self.assertIsSubclass(G, typing.AsyncIterable) + self.assertIsSubclass(G, collections.AsyncGenerator) + self.assertIsSubclass(G, collections.AsyncIterable) + self.assertNotIsSubclass(type(g), G) + + instance = G() + self.assertIsInstance(instance, typing.AsyncGenerator) + self.assertIsInstance(instance, typing.AsyncIterable) + self.assertIsInstance(instance, collections.AsyncGenerator) + self.assertIsInstance(instance, collections.AsyncIterable) + self.assertNotIsInstance(type(g), G) + self.assertNotIsInstance(g, G) + def test_subclassing_subclasshook(self): class Base(typing.Iterable): @@ -1845,7 +2149,7 @@ class TypeTests(BaseTestCase): def new_user(user_class: Type[User]) -> User: return user_class() - joe = new_user(BasicUser) + new_user(BasicUser) def test_type_typevar(self): @@ -1858,7 +2162,7 @@ class TypeTests(BaseTestCase): def new_user(user_class: Type[U]) -> U: return user_class() - joe = new_user(BasicUser) + new_user(BasicUser) def test_type_optional(self): A = Optional[Type[BaseException]] @@ -1907,7 +2211,17 @@ class NamedTupleTests(BaseTestCase): 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)) + self.assertEqual(Emp.__annotations__, + collections.OrderedDict([('name', str), ('id', int)])) + self.assertIs(Emp._field_types, Emp.__annotations__) + + def test_namedtuple_pyversion(self): + if sys.version_info[:2] < (3, 6): + with self.assertRaises(TypeError): + NamedTuple('Name', one=int, other=str) + with self.assertRaises(TypeError): + class NotYet(NamedTuple): + whatever = 0 @skipUnless(PY36, 'Python 3.6 required') def test_annotation_usage(self): @@ -1918,7 +2232,46 @@ class NamedTupleTests(BaseTestCase): self.assertEqual(tim.cool, 9000) self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') self.assertEqual(CoolEmployee._fields, ('name', 'cool')) - self.assertEqual(CoolEmployee._field_types, dict(name=str, cool=int)) + self.assertEqual(CoolEmployee.__annotations__, + collections.OrderedDict(name=str, cool=int)) + self.assertIs(CoolEmployee._field_types, CoolEmployee.__annotations__) + + @skipUnless(PY36, 'Python 3.6 required') + def test_annotation_usage_with_default(self): + jelle = CoolEmployeeWithDefault('Jelle') + self.assertIsInstance(jelle, CoolEmployeeWithDefault) + self.assertIsInstance(jelle, tuple) + self.assertEqual(jelle.name, 'Jelle') + self.assertEqual(jelle.cool, 0) + cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1) + self.assertEqual(cooler_employee.cool, 1) + + self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') + self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) + self.assertEqual(CoolEmployeeWithDefault._field_types, dict(name=str, cool=int)) + self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) + + with self.assertRaises(TypeError): + exec(""" +class NonDefaultAfterDefault(NamedTuple): + x: int = 3 + y: int +""") + + @skipUnless(PY36, 'Python 3.6 required') + def test_annotation_usage_with_methods(self): + self.assertEqual(XMeth(1).double(), 2) + self.assertEqual(XMeth(42).x, XMeth(42)[0]) + self.assertEqual(str(XRepr(42)), '42 -> 1') + self.assertEqual(XRepr(1, 2) + XRepr(3), 0) + + with self.assertRaises(AttributeError): + exec(""" +class XMethBad(NamedTuple): + x: int + def _fields(self): + return 'no chance for this' +""") @skipUnless(PY36, 'Python 3.6 required') def test_namedtuple_keyword_usage(self): @@ -1928,7 +2281,8 @@ class NamedTupleTests(BaseTestCase): self.assertEqual(nick.name, 'Nick') self.assertEqual(LocalEmployee.__name__, 'LocalEmployee') self.assertEqual(LocalEmployee._fields, ('name', 'age')) - self.assertEqual(LocalEmployee._field_types, dict(name=str, age=int)) + self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) + self.assertIs(LocalEmployee._field_types, LocalEmployee.__annotations__) with self.assertRaises(TypeError): NamedTuple('Name', [('x', int)], y=str) with self.assertRaises(TypeError): @@ -1994,8 +2348,14 @@ class RETests(BaseTestCase): self.assertIsInstance(mat, Match) # these should just work - p = Pattern[Union[str, bytes]] - m = Match[Union[bytes, str]] + Pattern[Union[str, bytes]] + Match[Union[bytes, str]] + + def test_alias_equality(self): + self.assertEqual(Pattern[str], Pattern[str]) + self.assertNotEqual(Pattern[str], Pattern[bytes]) + self.assertNotEqual(Pattern[str], Match[str]) + self.assertNotEqual(Pattern[str], str) def test_errors(self): with self.assertRaises(TypeError): @@ -2011,6 +2371,9 @@ class RETests(BaseTestCase): with self.assertRaises(TypeError): # We don't support isinstance(). isinstance(42, Pattern[str]) + with self.assertRaises(TypeError): + # We don't support issubclass(). + issubclass(Pattern[bytes], Pattern[str]) def test_repr(self): self.assertEqual(repr(Pattern), 'Pattern[~AnyStr]') diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 0737140..2844bc5 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -465,6 +465,13 @@ class UnicodeTest(string_tests.CommonTest, self.checkraises(TypeError, ' ', 'join', [1, 2, 3]) self.checkraises(TypeError, ' ', 'join', ['1', '2', 3]) + @unittest.skipIf(sys.maxsize > 2**32, + 'needs too much memory on a 64-bit platform') + def test_join_overflow(self): + size = int(sys.maxsize**0.5) + 1 + seq = ('A' * size,) * size + self.assertRaises(OverflowError, ''.join, seq) + def test_replace(self): string_tests.CommonTest.test_replace(self) @@ -1441,6 +1448,15 @@ class UnicodeTest(string_tests.CommonTest, with self.assertRaises(ValueError): result = format_string % 2.34 + def test_issue28598_strsubclass_rhs(self): + # A subclass of str with an __rmod__ method should be able to hook + # into the % operator + class SubclassedStr(str): + def __rmod__(self, other): + return 'Success, self.__rmod__({!r}) was called'.format(other) + self.assertEqual('lhs %% %r' % SubclassedStr('rhs'), + "Success, self.__rmod__('lhs %% %r') was called") + @support.cpython_only def test_formatting_huge_precision_c_limits(self): from _testcapi import INT_MAX @@ -2639,7 +2655,7 @@ class CAPITest(unittest.TestCase): b'repr=%V', None, b'abc\xff') # not supported: copy the raw format string. these tests are just here - # to check for crashs and should not be considered as specifications + # to check for crashes and should not be considered as specifications check_format('%s', b'%1%s', b'abc') check_format('%1abc', diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 43ea6b8..5084486 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -247,11 +247,12 @@ class ProxyTests(unittest.TestCase): 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') + 'localhost, anotherdomain.com, newdomain.com:1234, .d.o.t') self.assertTrue(bypass('localhost')) self.assertTrue(bypass('LocalHost')) # MixedCase self.assertTrue(bypass('LOCALHOST')) # UPPERCASE self.assertTrue(bypass('newdomain.com:1234')) + self.assertTrue(bypass('foo.d.o.t')) # issue 29142 self.assertTrue(bypass('anotherdomain.com:8888')) self.assertTrue(bypass('www.newdomain.com:1234')) self.assertFalse(bypass('prelocalhost')) diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index e34d8e6..47248f9 100644 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -292,6 +292,10 @@ class TestUUID(unittest.TestCase): badtype(lambda: setattr(u, 'clock_seq_low', 0)) badtype(lambda: setattr(u, 'node', 0)) + # Comparison with a non-UUID object + badtype(lambda: u < object()) + badtype(lambda: u > object()) + def test_getnode(self): node1 = uuid.getnode() self.assertTrue(0 < node1 < (1 << 48), '%012x' % node1) diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 0ff978f..2691632 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -330,12 +330,7 @@ class EnsurePipTest(BaseTest): else: self.assertTrue(os.path.exists(os.devnull)) - - @unittest.skipUnless(threading, 'some dependencies of pip import threading' - ' module unconditionally') - # Issue #26610: pip/pep425tags.py requires ctypes - @unittest.skipUnless(ctypes, 'pip requires ctypes') - def test_with_pip(self): + def do_test_with_pip(self, system_site_packages): rmtree(self.env_dir) with EnvironmentVarGuard() as envvars: # pip's cross-version compatibility may trigger deprecation @@ -369,6 +364,7 @@ class EnsurePipTest(BaseTest): # config in place to ensure we ignore it try: self.run_with_capture(venv.create, self.env_dir, + system_site_packages=system_site_packages, with_pip=True) except subprocess.CalledProcessError as exc: # The output this produces can be a little hard to read, @@ -418,9 +414,19 @@ class EnsurePipTest(BaseTest): out = out.decode("latin-1") # Force to text, prevent decoding errors self.assertIn("Successfully uninstalled pip", out) self.assertIn("Successfully uninstalled setuptools", out) - # Check pip is now gone from the virtual environment - self.assert_pip_not_installed() + # Check pip is now gone from the virtual environment. This only + # applies in the system_site_packages=False case, because in the + # other case, pip may still be available in the system site-packages + if not system_site_packages: + self.assert_pip_not_installed() + @unittest.skipUnless(threading, 'some dependencies of pip import threading' + ' module unconditionally') + # Issue #26610: pip/pep425tags.py requires ctypes + @unittest.skipUnless(ctypes, 'pip requires ctypes') + def test_with_pip(self): + self.do_test_with_pip(False) + self.do_test_with_pip(True) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index a474a07..43cf2c0 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -6,6 +6,7 @@ import weakref import operator import contextlib import copy +import time from test import support from test.support import script_helper @@ -72,6 +73,29 @@ class TestBase(unittest.TestCase): self.cbcalled += 1 +@contextlib.contextmanager +def collect_in_thread(period=0.0001): + """ + Ensure GC collections happen in a different thread, at a high frequency. + """ + threading = support.import_module('threading') + please_stop = False + + def collect(): + while not please_stop: + time.sleep(period) + gc.collect() + + with support.disable_gc(): + t = threading.Thread(target=collect) + t.start() + try: + yield + finally: + please_stop = True + t.join() + + class ReferencesTestCase(TestBase): def test_basic_ref(self): @@ -1636,6 +1660,35 @@ class MappingTestCase(TestBase): dict = weakref.WeakKeyDictionary() self.assertRegex(repr(dict), '') + def test_threaded_weak_valued_setdefault(self): + d = weakref.WeakValueDictionary() + with collect_in_thread(): + for i in range(100000): + x = d.setdefault(10, RefCycle()) + self.assertIsNot(x, None) # we never put None in there! + del x + + def test_threaded_weak_valued_pop(self): + d = weakref.WeakValueDictionary() + with collect_in_thread(): + for i in range(100000): + d[10] = RefCycle() + x = d.pop(10, 10) + self.assertIsNot(x, None) # we never put None in there! + + def test_threaded_weak_valued_consistency(self): + # Issue #28427: old keys should not remove new values from + # WeakValueDictionary when collecting from another thread. + d = weakref.WeakValueDictionary() + with collect_in_thread(): + for i in range(200000): + o = RefCycle() + d[10] = o + # o is still alive, so the dict can't be empty + self.assertEqual(len(d), 1) + o = None # lose ref + + from test import mapping_tests class WeakValueDictionaryTestCase(mapping_tests.BasicTestMappingProtocol): diff --git a/Lib/test/test_winconsoleio.py b/Lib/test/test_winconsoleio.py index b1a2f7a..656483c 100644 --- a/Lib/test/test_winconsoleio.py +++ b/Lib/test/test_winconsoleio.py @@ -2,8 +2,11 @@ ''' import io -import unittest +import os import sys +import tempfile +import unittest +from test import support if sys.platform != 'win32': raise unittest.SkipTest("test only relevant on win32") @@ -19,6 +22,18 @@ class WindowsConsoleIOTests(unittest.TestCase): self.assertFalse(issubclass(ConIO, io.TextIOBase)) def test_open_fd(self): + self.assertRaisesRegex(ValueError, + "negative file descriptor", ConIO, -1) + + fd, _ = tempfile.mkstemp() + try: + # Windows 10: "Cannot open non-console file" + # Earlier: "Cannot open console output buffer for reading" + self.assertRaisesRegex(ValueError, + "Cannot open (console|non-console file)", ConIO, fd) + finally: + os.close(fd) + try: f = ConIO(0) except ValueError: @@ -56,6 +71,8 @@ class WindowsConsoleIOTests(unittest.TestCase): f.close() def test_open_name(self): + self.assertRaises(ValueError, ConIO, sys.executable) + f = ConIO("CON") self.assertTrue(f.readable()) self.assertFalse(f.writable()) @@ -77,6 +94,33 @@ class WindowsConsoleIOTests(unittest.TestCase): f.close() f.close() + f = open('C:/con', 'rb', buffering=0) + self.assertIsInstance(f, ConIO) + f.close() + + @unittest.skipIf(sys.getwindowsversion()[:2] <= (6, 1), + "test does not work on Windows 7 and earlier") + def test_conin_conout_names(self): + f = open(r'\\.\conin$', 'rb', buffering=0) + self.assertIsInstance(f, ConIO) + f.close() + + f = open('//?/conout$', 'wb', buffering=0) + self.assertIsInstance(f, ConIO) + f.close() + + def test_conout_path(self): + temp_path = tempfile.mkdtemp() + self.addCleanup(support.rmtree, temp_path) + + conout_path = os.path.join(temp_path, 'CONOUT$') + + with open(conout_path, 'wb', buffering=0) as f: + if sys.getwindowsversion()[:2] > (6, 1): + self.assertIsInstance(f, ConIO) + else: + self.assertNotIsInstance(f, ConIO) + def assertStdinRoundTrip(self, text): stdin = open('CONIN$', 'r') old_stdin = sys.stdin diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index d642b13..2be61ae 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -57,7 +57,7 @@ class BaseWinregTests(unittest.TestCase): def delete_tree(self, root, subkey): try: - hkey = OpenKey(root, subkey, KEY_ALL_ACCESS) + hkey = OpenKey(root, subkey, 0, KEY_ALL_ACCESS) except OSError: # subkey does not exist return @@ -368,6 +368,18 @@ class LocalWinregTests(BaseWinregTests): finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) + def test_read_string_containing_null(self): + # Test for issue 25778: REG_SZ should not contain null characters + try: + with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: + self.assertNotEqual(ck.handle, 0) + test_val = "A string\x00 with a null" + SetValueEx(ck, "test_name", 0, REG_SZ, test_val) + ret_val, ret_type = QueryValueEx(ck, "test_name") + self.assertEqual(ret_type, REG_SZ) + self.assertEqual(ret_val, "A string") + finally: + DeleteKey(HKEY_CURRENT_USER, test_key_name) @unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests") diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index 87f3f27..7c60699 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -11,6 +11,7 @@ cET_alias = import_fresh_module('xml.etree.cElementTree', fresh=['_elementtree', 'xml.etree']) +@unittest.skipUnless(cET, 'requires _elementtree') class MiscTests(unittest.TestCase): # Issue #8651. @support.bigmemtest(size=support._2G + 100, memuse=1, dry_run=False) @@ -54,6 +55,15 @@ class MiscTests(unittest.TestCase): del element.attrib self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + def test_trashcan(self): + # If this test fails, it will most likely die via segfault. + e = root = cET.Element('root') + for i in range(200000): + e = cET.SubElement(e, 'x') + del e + del root + support.gc_collect() + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): diff --git a/Lib/threading.py b/Lib/threading.py index 4829ff4..95978d3 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -1217,6 +1217,10 @@ class _DummyThread(Thread): def _stop(self): pass + def is_alive(self): + assert not self._is_stopped and self._started.is_set() + return True + def join(self, timeout=None): assert False, "cannot join a dummy thread" diff --git a/Lib/timeit.py b/Lib/timeit.py old mode 100644 new mode 100755 index 2770efa..8eea766 --- a/Lib/timeit.py +++ b/Lib/timeit.py @@ -208,7 +208,7 @@ class Timer: return r def autorange(self, callback=None): - """Return the number of loops so that total time >= 0.2. + """Return the number of loops and time taken so that total time >= 0.2. Calls the timeit method with *number* set to successive powers of ten (10, 100, 1000, ...) up to a maximum of one billion, until diff --git a/Lib/tkinter/tix.py b/Lib/tkinter/tix.py index e7cb10a..d9c097a 100644 --- a/Lib/tkinter/tix.py +++ b/Lib/tkinter/tix.py @@ -1,7 +1,3 @@ -# -*-mode: python; fill-column: 75; tab-width: 8 -*- -# -# $Id$ -# # Tix.py -- Tix widget wrappers. # # For Tix, see http://tix.sourceforge.net diff --git a/Lib/typing.py b/Lib/typing.py index 34845b7..9a0f490 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -10,6 +10,12 @@ try: import collections.abc as collections_abc except ImportError: import collections as collections_abc # Fallback for PY3.2. +try: + from types import SlotWrapperType, MethodWrapperType, MethodDescriptorType +except ImportError: + SlotWrapperType = type(object.__init__) + MethodWrapperType = type(object().__str__) + MethodDescriptorType = type(str.join) # Please keep __all__ alphabetized within each category. @@ -27,6 +33,8 @@ __all__ = [ # ABCs (from collections.abc). 'AbstractSet', # collections.abc.Set. + 'GenericMeta', # subclass of abc.ABCMeta and a metaclass + # for 'Generic' and ABCs below. 'ByteString', 'Container', 'Hashable', @@ -49,7 +57,8 @@ __all__ = [ # AsyncIterable, # Coroutine, # Collection, - # ContextManager + # ContextManager, + # AsyncGenerator, # Structural checks, a.k.a. protocols. 'Reversible', @@ -59,6 +68,8 @@ __all__ = [ 'SupportsRound', # Concrete collection types. + 'Counter', + 'Deque', 'Dict', 'DefaultDict', 'List', @@ -93,8 +104,8 @@ def _qualname(x): def _trim_name(nm): - if nm.startswith('_') and nm not in ('_TypeAlias', - '_ForwardRef', '_TypingBase', '_FinalTypingBase'): + whitelist = ('_TypeAlias', '_ForwardRef', '_TypingBase', '_FinalTypingBase') + if nm.startswith('_') and nm not in whitelist: nm = nm[1:] return nm @@ -144,7 +155,7 @@ class TypingMeta(type): class _TypingBase(metaclass=TypingMeta, _root=True): """Internal indicator of special typing constructs.""" - __slots__ = () + __slots__ = ('__weakref__',) def __init__(self, *args, **kwds): pass @@ -351,13 +362,17 @@ def _type_check(arg, msg): return type(None) if isinstance(arg, str): arg = _ForwardRef(arg) - if (isinstance(arg, _TypingBase) and type(arg).__name__ == '_ClassVar' or - not isinstance(arg, (type, _TypingBase)) and not callable(arg)): + if ( + isinstance(arg, _TypingBase) and type(arg).__name__ == '_ClassVar' or + not isinstance(arg, (type, _TypingBase)) and not callable(arg) + ): raise TypeError(msg + " Got %.100r." % (arg,)) # Bare Union etc. are not valid as type arguments - if (type(arg).__name__ in ('_Union', '_Optional') - and not getattr(arg, '__origin__', None) - or isinstance(arg, TypingMeta) and _gorg(arg) in (Generic, _Protocol)): + if ( + type(arg).__name__ in ('_Union', '_Optional') and + not getattr(arg, '__origin__', None) or + isinstance(arg, TypingMeta) and _gorg(arg) in (Generic, _Protocol) + ): raise TypeError("Plain %s is not valid as type argument" % arg) return arg @@ -451,7 +466,7 @@ class TypeVar(_TypingBase, _root=True): '__covariant__', '__contravariant__') def __init__(self, name, *constraints, bound=None, - covariant=False, contravariant=False): + covariant=False, contravariant=False): super().__init__(name, *constraints, bound=bound, covariant=covariant, contravariant=contravariant) self.__name__ = name @@ -513,7 +528,7 @@ def _replace_arg(arg, tvars, args): if tvars is None: tvars = [] - if hasattr(arg, '_subs_tree'): + if hasattr(arg, '_subs_tree') and isinstance(arg, (GenericMeta, _TypingBase)): return arg._subs_tree(tvars, args) if isinstance(arg, TypeVar): for i, tvar in enumerate(tvars): @@ -522,6 +537,16 @@ def _replace_arg(arg, tvars, args): return arg +# Special typing constructs Union, Optional, Generic, Callable and Tuple +# use three special attributes for internal bookkeeping of generic types: +# * __parameters__ is a tuple of unique free type parameters of a generic +# type, for example, Dict[T, T].__parameters__ == (T,); +# * __origin__ keeps a reference to a type that was subscripted, +# e.g., Union[T, int].__origin__ == Union; +# * __args__ is a tuple of all arguments used in subscripting, +# e.g., Dict[T, int].__args__ == (T, int). + + def _subs_tree(cls, tvars=None, args=None): """An internal helper function: calculate substitution tree for generic cls after replacing its type parameters with @@ -549,7 +574,7 @@ def _subs_tree(cls, tvars=None, args=None): # ... then continue replacing down the origin chain. for ocls in orig_chain: new_tree_args = [] - for i, arg in enumerate(ocls.__args__): + for arg in ocls.__args__: new_tree_args.append(_replace_arg(arg, ocls.__parameters__, tree_args)) tree_args = new_tree_args return tree_args @@ -617,6 +642,7 @@ def _tp_cache(func): cached = functools.lru_cache()(func) _cleanups.append(cached.cache_clear) + @functools.wraps(func) def inner(*args, **kwds): try: @@ -756,9 +782,12 @@ class _Union(_FinalTypingBase, _root=True): return (Union,) + tree_args def __eq__(self, other): - if not isinstance(other, _Union): + if isinstance(other, _Union): + return self.__tree_hash__ == other.__tree_hash__ + elif self is not Union: return self._subs_tree() == other - return self.__tree_hash__ == other.__tree_hash__ + else: + return self is other def __hash__(self): return self.__tree_hash__ @@ -823,21 +852,10 @@ def _next_in_mro(cls): # 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] + next_in_mro = cls.__mro__[i + 1] return next_in_mro -def _valid_for_check(cls): - """An internal helper to prohibit isinstance([1], List[str]) etc.""" - if cls is Generic: - raise TypeError("Class %r cannot be used with class " - "or instance checks" % cls) - if (cls.__origin__ is not None and - sys._getframe(3).f_globals['__name__'] not in ['abc', 'functools']): - raise TypeError("Parameterized generics cannot be used with class " - "or instance checks") - - def _make_subclasshook(cls): """Construct a __subclasshook__ callable that incorporates the associated __extra__ class in subclass checks performed @@ -848,7 +866,6 @@ def _make_subclasshook(cls): # Registered classes need not be checked here because # cls and its extra share the same _abc_registry. def __extrahook__(subclass): - _valid_for_check(cls) res = cls.__extra__.__subclasshook__(subclass) if res is not NotImplemented: return res @@ -863,7 +880,6 @@ def _make_subclasshook(cls): else: # For non-ABC extras we'll just call issubclass(). def __extrahook__(subclass): - _valid_for_check(cls) if cls.__extra__ and issubclass(subclass, cls.__extra__): return True return NotImplemented @@ -882,10 +898,26 @@ def _no_slots_copy(dct): class GenericMeta(TypingMeta, abc.ABCMeta): - """Metaclass for generic types.""" + """Metaclass for generic types. + + This is a metaclass for typing.Generic and generic ABCs defined in + typing module. User defined subclasses of GenericMeta can override + __new__ and invoke super().__new__. Note that GenericMeta.__new__ + has strict rules on what is allowed in its bases argument: + * plain Generic is disallowed in bases; + * Generic[...] should appear in bases at most once; + * if Generic[...] is present, then it should list all type variables + that appear in other bases. + In addition, type of all generic bases is erased, e.g., C[int] is + stripped to plain C. + """ def __new__(cls, name, bases, namespace, tvars=None, args=None, origin=None, extra=None, orig_bases=None): + """Create a new generic class. GenericMeta.__new__ accepts + keyword arguments that are used for internal bookkeeping, therefore + an override should pass unused keyword arguments to super(). + """ if tvars is not None: # Called from __getitem__() below. assert origin is not None @@ -934,6 +966,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta): # remove bare Generic from bases if there are other generic bases if any(isinstance(b, GenericMeta) and b is not Generic for b in bases): bases = tuple(b for b in bases if b is not Generic) + namespace.update({'__origin__': origin, '__extra__': extra}) self = super().__new__(cls, name, bases, namespace, _root=True) self.__parameters__ = tvars @@ -942,8 +975,6 @@ class GenericMeta(TypingMeta, abc.ABCMeta): self.__args__ = tuple(... if a is _TypingEllipsis else () if a is _TypingEmpty else a for a in args) if args else None - self.__origin__ = origin - self.__extra__ = extra # Speed hack (https://github.com/python/typing/issues/196). self.__next_in_mro__ = _next_in_mro(self) # Preserve base classes on subclassing (__bases__ are type erased now). @@ -953,18 +984,57 @@ class GenericMeta(TypingMeta, abc.ABCMeta): # This allows unparameterized generic collections to be used # with issubclass() and isinstance() in the same way as their # collections.abc counterparts (e.g., isinstance([], Iterable)). - if ('__subclasshook__' not in namespace and extra # allow overriding - or hasattr(self.__subclasshook__, '__name__') and - self.__subclasshook__.__name__ == '__extrahook__'): + if ( + '__subclasshook__' not in namespace and extra or + # allow overriding + getattr(self.__subclasshook__, '__name__', '') == '__extrahook__' + ): self.__subclasshook__ = _make_subclasshook(self) if isinstance(extra, abc.ABCMeta): self._abc_registry = extra._abc_registry + self._abc_cache = extra._abc_cache + elif origin is not None: + self._abc_registry = origin._abc_registry + self._abc_cache = origin._abc_cache if origin and hasattr(origin, '__qualname__'): # Fix for Python 3.2. self.__qualname__ = origin.__qualname__ - self.__tree_hash__ = hash(self._subs_tree()) if origin else hash((self.__name__,)) + self.__tree_hash__ = (hash(self._subs_tree()) if origin else + super(GenericMeta, self).__hash__()) return self + # _abc_negative_cache and _abc_negative_cache_version + # realised as descriptors, since GenClass[t1, t2, ...] always + # share subclass info with GenClass. + # This is an important memory optimization. + @property + def _abc_negative_cache(self): + if isinstance(self.__extra__, abc.ABCMeta): + return self.__extra__._abc_negative_cache + return _gorg(self)._abc_generic_negative_cache + + @_abc_negative_cache.setter + def _abc_negative_cache(self, value): + if self.__origin__ is None: + if isinstance(self.__extra__, abc.ABCMeta): + self.__extra__._abc_negative_cache = value + else: + self._abc_generic_negative_cache = value + + @property + def _abc_negative_cache_version(self): + if isinstance(self.__extra__, abc.ABCMeta): + return self.__extra__._abc_negative_cache_version + return _gorg(self)._abc_generic_negative_cache_version + + @_abc_negative_cache_version.setter + def _abc_negative_cache_version(self, value): + if self.__origin__ is None: + if isinstance(self.__extra__, abc.ABCMeta): + self.__extra__._abc_negative_cache_version = value + else: + self._abc_generic_negative_cache_version = value + def _get_type_vars(self, tvars): if self.__origin__ and self.__parameters__: _get_type_vars(self.__parameters__, tvars) @@ -1052,8 +1122,10 @@ class GenericMeta(TypingMeta, abc.ABCMeta): _check_generic(self, params) tvars = _type_vars(params) args = params + + prepend = (self,) if self.__origin__ is None else () return self.__class__(self.__name__, - self.__bases__, + prepend + self.__bases__, _no_slots_copy(self.__dict__), tvars=tvars, args=args, @@ -1061,6 +1133,17 @@ class GenericMeta(TypingMeta, abc.ABCMeta): extra=self.__extra__, orig_bases=self.__orig_bases__) + def __subclasscheck__(self, cls): + if self.__origin__ is not None: + if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools']: + raise TypeError("Parameterized generics cannot be used with class " + "or instance checks") + return False + if self is Generic: + raise TypeError("Class %r cannot be used with class " + "or instance checks" % self) + return super().__subclasscheck__(cls) + def __instancecheck__(self, instance): # Since we extend ABC.__subclasscheck__ and # ABC.__instancecheck__ inlines the cache checking done by the @@ -1075,6 +1158,16 @@ class GenericMeta(TypingMeta, abc.ABCMeta): self.__parameters__, self.__args__, self.__origin__, self.__extra__, self.__orig_bases__) + def __setattr__(self, attr, value): + # We consider all the subscripted genrics as proxies for original class + if ( + attr.startswith('__') and attr.endswith('__') or + attr.startswith('_abc_') + ): + super(GenericMeta, self).__setattr__(attr, value) + else: + super(GenericMeta, _gorg(self)).__setattr__(attr, value) + # Prevent checks for Generic to crash when defining Generic. Generic = None @@ -1159,13 +1252,13 @@ class TupleMeta(GenericMeta): return super().__getitem__(parameters) def __instancecheck__(self, obj): - if self.__args__ == None: + if self.__args__ is None: return isinstance(obj, tuple) raise TypeError("Parameterized Tuple cannot be used " "with isinstance().") def __subclasscheck__(self, cls): - if self.__args__ == None: + if self.__args__ is None: return issubclass(cls, tuple) raise TypeError("Parameterized Tuple cannot be used " "with issubclass().") @@ -1219,7 +1312,7 @@ class CallableMeta(GenericMeta): with hashable arguments to improve speed. """ - if self.__origin__ is not None or not _geqv(self, Callable): + if self.__origin__ is not None or not _geqv(self, Callable): return super().__getitem__(parameters) if not isinstance(parameters, tuple) or len(parameters) != 2: raise TypeError("Callable must be used as " @@ -1247,7 +1340,7 @@ class CallableMeta(GenericMeta): return super().__getitem__(parameters) -class Callable(extra=collections_abc.Callable, metaclass = CallableMeta): +class Callable(extra=collections_abc.Callable, metaclass=CallableMeta): """Callable type; Callable[[int], str] is a function of (int) -> str. The subscription syntax must always be used with exactly two @@ -1355,6 +1448,11 @@ def _get_defaults(func): return res +_allowed_types = (types.FunctionType, types.BuiltinFunctionType, + types.MethodType, types.ModuleType, + SlotWrapperType, MethodWrapperType, MethodDescriptorType) + + def get_type_hints(obj, globalns=None, localns=None): """Return type hints for an object. @@ -1409,10 +1507,7 @@ def get_type_hints(obj, globalns=None, localns=None): hints = getattr(obj, '__annotations__', None) if hints is None: # Return empty annotations for something that _could_ have them. - if (isinstance(obj, types.FunctionType) or - isinstance(obj, types.BuiltinFunctionType) or - isinstance(obj, types.MethodType) or - isinstance(obj, types.ModuleType)): + if isinstance(obj, _allowed_types): return {} else: raise TypeError('{!r} is not a module, class, method, ' @@ -1452,7 +1547,7 @@ def no_type_check(arg): no_type_check(obj) try: arg.__no_type_check__ = True - except TypeError: # built-in classes + except TypeError: # built-in classes pass return arg @@ -1738,14 +1833,15 @@ else: class MutableMapping(Mapping[KT, VT], extra=collections_abc.MutableMapping): __slots__ = () + if hasattr(collections_abc, 'Reversible'): if hasattr(collections_abc, 'Collection'): class Sequence(Reversible[T_co], Collection[T_co], - extra=collections_abc.Sequence): + extra=collections_abc.Sequence): __slots__ = () else: class Sequence(Sized, Reversible[T_co], Container[T_co], - extra=collections_abc.Sequence): + extra=collections_abc.Sequence): __slots__ = () else: class Sequence(Sized, Iterable[T_co], Container[T_co], @@ -1772,6 +1868,16 @@ class List(list, MutableSequence[T], extra=list): return _generic_new(list, cls, *args, **kwds) +class Deque(collections.deque, MutableSequence[T], extra=collections.deque): + + __slots__ = () + + def __new__(cls, *args, **kwds): + if _geqv(cls, Deque): + return collections.deque(*args, **kwds) + return _generic_new(collections.deque, cls, *args, **kwds) + + class Set(set, MutableSet[T], extra=set): __slots__ = () @@ -1829,6 +1935,7 @@ class Dict(dict, MutableMapping[KT, VT], extra=dict): "use dict() instead") return _generic_new(dict, cls, *args, **kwds) + class DefaultDict(collections.defaultdict, MutableMapping[KT, VT], extra=collections.defaultdict): @@ -1836,10 +1943,35 @@ class DefaultDict(collections.defaultdict, MutableMapping[KT, VT], def __new__(cls, *args, **kwds): if _geqv(cls, DefaultDict): - raise TypeError("Type DefaultDict cannot be instantiated; " - "use collections.defaultdict() instead") + return collections.defaultdict(*args, **kwds) return _generic_new(collections.defaultdict, cls, *args, **kwds) + +class Counter(collections.Counter, Dict[T, int], extra=collections.Counter): + + __slots__ = () + + def __new__(cls, *args, **kwds): + if _geqv(cls, Counter): + return collections.Counter(*args, **kwds) + return _generic_new(collections.Counter, cls, *args, **kwds) + + +if hasattr(collections, 'ChainMap'): + # ChainMap only exists in 3.3+ + __all__.append('ChainMap') + + class ChainMap(collections.ChainMap, MutableMapping[KT, VT], + extra=collections.ChainMap): + + __slots__ = () + + def __new__(cls, *args, **kwds): + if _geqv(cls, ChainMap): + return collections.ChainMap(*args, **kwds) + return _generic_new(collections.ChainMap, cls, *args, **kwds) + + # Determine what base class to use for Generator. if hasattr(collections_abc, 'Generator'): # Sufficiently recent versions of 3.5 have a Generator ABC. @@ -1860,6 +1992,14 @@ class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co], return _generic_new(_G_base, cls, *args, **kwds) +if hasattr(collections_abc, 'AsyncGenerator'): + class AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra], + extra=collections_abc.AsyncGenerator): + __slots__ = () + + __all__.append('AsyncGenerator') + + # Internal type variable used for Type[]. CT_co = TypeVar('CT_co', covariant=True, bound=type) @@ -1896,7 +2036,9 @@ def _make_nmtuple(name, types): msg = "NamedTuple('Name', [(f0, t0), (f1, t1), ...]); each t must be a type" types = [(n, _type_check(t, msg)) for n, t in types] nm_tpl = collections.namedtuple(name, [n for n, t in types]) - nm_tpl._field_types = dict(types) + # Prior to PEP 526, only _field_types attribute was assigned. + # Now, both __annotations__ and _field_types are used to maintain compatibility. + nm_tpl.__annotations__ = nm_tpl._field_types = collections.OrderedDict(types) try: nm_tpl.__module__ = sys._getframe(2).f_globals.get('__name__', '__main__') except (AttributeError, ValueError): @@ -1906,6 +2048,13 @@ def _make_nmtuple(name, types): _PY36 = sys.version_info[:2] >= (3, 6) +# attributes prohibited to set in NamedTuple class syntax +_prohibited = ('__new__', '__init__', '__slots__', '__getnewargs__', + '_fields', '_field_defaults', '_field_types', + '_make', '_replace', '_asdict') + +_special = ('__module__', '__name__', '__qualname__', '__annotations__') + class NamedTupleMeta(type): @@ -1916,7 +2065,29 @@ class NamedTupleMeta(type): raise TypeError("Class syntax for NamedTuple is only supported" " in Python 3.6+") types = ns.get('__annotations__', {}) - return _make_nmtuple(typename, types.items()) + nm_tpl = _make_nmtuple(typename, types.items()) + defaults = [] + defaults_dict = {} + for field_name in types: + if field_name in ns: + default_value = ns[field_name] + defaults.append(default_value) + defaults_dict[field_name] = default_value + elif defaults: + raise TypeError("Non-default namedtuple field {field_name} cannot " + "follow default field(s) {default_names}" + .format(field_name=field_name, + default_names=', '.join(defaults_dict.keys()))) + nm_tpl.__new__.__defaults__ = tuple(defaults) + nm_tpl._field_defaults = defaults_dict + # update from user namespace without overriding special namedtuple attributes + for key in ns: + if key in _prohibited: + raise AttributeError("Cannot overwrite NamedTuple attribute " + key) + elif key not in _special and key not in nm_tpl._fields: + setattr(nm_tpl, key, ns[key]) + return nm_tpl + class NamedTuple(metaclass=NamedTupleMeta): """Typed version of namedtuple. @@ -1931,8 +2102,10 @@ class NamedTuple(metaclass=NamedTupleMeta): Employee = collections.namedtuple('Employee', ['name', 'id']) - The resulting class has one extra attribute: _field_types, - giving a dict mapping field names to types. (The field names + The resulting class has extra __annotations__ and _field_types + attributes, giving an ordered dict mapping field names to types. + __annotations__ should be preferred, while _field_types + is kept to maintain pre PEP 526 compatibility. (The field names are in the _fields attribute, which is part of the namedtuple API.) Alternative equivalent keyword syntax is also accepted:: @@ -2139,6 +2312,7 @@ class io: TextIO = TextIO BinaryIO = BinaryIO + io.__name__ = __name__ + '.io' sys.modules[io.__name__] = io @@ -2156,5 +2330,6 @@ class re: Pattern = Pattern Match = Match + re.__name__ = __name__ + '.re' sys.modules[re.__name__] = re diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index eb447d7..e860deb 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -81,7 +81,7 @@ class TestLoader(object): self._loading_packages = set() def loadTestsFromTestCase(self, testCaseClass): - """Return a suite of all tests cases contained in testCaseClass""" + """Return a suite of all test cases contained in testCaseClass""" if issubclass(testCaseClass, suite.TestSuite): raise TypeError("Test cases should not be derived from " "TestSuite. Maybe you meant to derive from " @@ -95,7 +95,7 @@ class TestLoader(object): # XXX After Python 3.5, remove backward compatibility hacks for # use_load_tests deprecation via *args and **kws. See issue 16662. def loadTestsFromModule(self, module, *args, pattern=None, **kws): - """Return a suite of all tests cases contained in the given module""" + """Return a suite of all test cases contained in the given module""" # This method used to take an undocumented and unofficial # use_load_tests argument. For backward compatibility, we still # accept the argument (which can also be the first position) but we @@ -135,7 +135,7 @@ class TestLoader(object): return tests def loadTestsFromName(self, name, module=None): - """Return a suite of all tests cases given a string specifier. + """Return a suite of all test cases given a string specifier. The name may resolve either to a module, a test case class, a test method within a test case class, or a callable object which @@ -213,7 +213,7 @@ class TestLoader(object): raise TypeError("don't know how to make test from: %s" % obj) def loadTestsFromNames(self, names, module=None): - """Return a suite of all tests cases found using the given sequence + """Return a suite of all test cases found using the given sequence of string specifiers. See 'loadTestsFromName()'. """ suites = [self.loadTestsFromName(name, module) for name in names] diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index f134919..5f97728 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -815,8 +815,8 @@ class NonCallableMock(Base): def assert_called_once_with(_mock_self, *args, **kwargs): - """assert that the mock was called exactly once and with the specified - arguments.""" + """assert that the mock was called exactly once and that that call was + with the specified arguments.""" self = _mock_self if not self.call_count == 1: msg = ("Expected '%s' to be called once. Called %s times." % @@ -1769,14 +1769,18 @@ def _get_eq(self): ret_val = self.__eq__._mock_return_value if ret_val is not DEFAULT: return ret_val - return self is other + if self is other: + return True + return NotImplemented return __eq__ def _get_ne(self): def __ne__(other): if self.__ne__._mock_return_value is not DEFAULT: return DEFAULT - return self is not other + if self is other: + return False + return NotImplemented return __ne__ def _get_iter(self): @@ -1961,9 +1965,8 @@ class _Call(tuple): If the _Call has no name then it will match any name. """ - def __new__(cls, value=(), name=None, parent=None, two=False, + def __new__(cls, value=(), name='', parent=None, two=False, from_kall=True): - name = '' args = () kwargs = {} _len = len(value) diff --git a/Lib/unittest/test/test_loader.py b/Lib/unittest/test/test_loader.py index b2f9c88..1131a75 100644 --- a/Lib/unittest/test/test_loader.py +++ b/Lib/unittest/test/test_loader.py @@ -35,7 +35,7 @@ class Test_TestLoader(unittest.TestCase): ### Tests for TestLoader.loadTestsFromTestCase ################################################################ - # "Return a suite of all tests cases contained in the TestCase-derived + # "Return a suite of all test cases contained in the TestCase-derived # class testCaseClass" def test_loadTestsFromTestCase(self): class Foo(unittest.TestCase): @@ -48,7 +48,7 @@ class Test_TestLoader(unittest.TestCase): loader = unittest.TestLoader() self.assertEqual(loader.loadTestsFromTestCase(Foo), tests) - # "Return a suite of all tests cases contained in the TestCase-derived + # "Return a suite of all test cases contained in the TestCase-derived # class testCaseClass" # # Make sure it does the right thing even if no tests were found @@ -61,7 +61,7 @@ class Test_TestLoader(unittest.TestCase): loader = unittest.TestLoader() self.assertEqual(loader.loadTestsFromTestCase(Foo), empty_suite) - # "Return a suite of all tests cases contained in the TestCase-derived + # "Return a suite of all test cases contained in the TestCase-derived # class testCaseClass" # # What happens if loadTestsFromTestCase() is given an object @@ -82,7 +82,7 @@ class Test_TestLoader(unittest.TestCase): else: self.fail('Should raise TypeError') - # "Return a suite of all tests cases contained in the TestCase-derived + # "Return a suite of all test cases contained in the TestCase-derived # class testCaseClass" # # Make sure loadTestsFromTestCase() picks up the default test method diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 3477634..d2202a7 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -306,6 +306,11 @@ class CallTest(unittest.TestCase): other_args = _Call(((1, 2), {'a': 3})) self.assertEqual(args, other_args) + def test_call_with_name(self): + self.assertEqual(_Call((), 'foo')[0], 'foo') + self.assertEqual(_Call((('bar', 'barz'),),)[0], '') + self.assertEqual(_Call((('bar', 'barz'), {'hello': 'world'}),)[0], '') + class SpecSignatureTest(unittest.TestCase): diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index b07a7cc..b64c866 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -306,13 +306,24 @@ class MockTest(unittest.TestCase): 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 + mm = mock.MagicMock() + self.assertTrue(mm == mm) + self.assertFalse(mm != mm) + self.assertFalse(mm == mock.MagicMock()) + self.assertTrue(mm != mock.MagicMock()) + self.assertTrue(mm == mock.ANY) + self.assertFalse(mm != mock.ANY) + self.assertTrue(mock.ANY == mm) + self.assertFalse(mock.ANY != mm) + + call1 = mock.call(mock.MagicMock()) + call2 = mock.call(mock.ANY) self.assertTrue(call1 == call2) self.assertFalse(call1 != call2) + self.assertTrue(call2 == call1) + self.assertFalse(call2 != call1) def test_assert_called_with(self): diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 5f15b74..b6690c3 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -2514,6 +2514,7 @@ def proxy_bypass_environment(host, proxies=None): no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')] for name in no_proxy_list: if name: + name = name.lstrip('.') # ignore leading dots name = re.escape(name) pattern = r'(.+\.)?%s$' % name if (re.match(pattern, hostonly, re.I) diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 0a094e3..716129d 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -57,6 +57,10 @@ class EnvBuilder: """ env_dir = os.path.abspath(env_dir) context = self.ensure_directories(env_dir) + # See issue 24875. We need system_site_packages to be False + # until after pip is installed. + true_system_site_packages = self.system_site_packages + self.system_site_packages = False self.create_configuration(context) self.setup_python(context) if self.with_pip: @@ -64,6 +68,11 @@ class EnvBuilder: if not self.upgrade: self.setup_scripts(context) self.post_setup(context) + if true_system_site_packages: + # We had set it to False before, now + # restore it and rewrite the configuration + self.system_site_packages = True + self.create_configuration(context) def clear_directory(self, path): for fn in os.listdir(path): @@ -311,19 +320,17 @@ class EnvBuilder: dstfile = os.path.join(dstdir, f) with open(srcfile, 'rb') as f: data = f.read() - if srcfile.endswith('.exe'): - mode = 'wb' - else: - mode = 'w' + if not srcfile.endswith('.exe'): try: data = data.decode('utf-8') data = self.replace_variables(data, context) - except UnicodeDecodeError as e: + data = data.encode('utf-8') + except UnicodeError as e: data = None logger.warning('unable to copy script %r, ' 'may be binary: %s', srcfile, e) if data is not None: - with open(dstfile, mode) as f: + with open(dstfile, 'wb') as f: f.write(data) shutil.copymode(srcfile, dstfile) diff --git a/Lib/venv/scripts/posix/activate b/Lib/venv/scripts/common/activate similarity index 100% rename from Lib/venv/scripts/posix/activate rename to Lib/venv/scripts/common/activate diff --git a/Lib/venv/scripts/nt/Activate.ps1 b/Lib/venv/scripts/nt/Activate.ps1 index b15decb..85646c8 100644 --- a/Lib/venv/scripts/nt/Activate.ps1 +++ b/Lib/venv/scripts/nt/Activate.ps1 @@ -26,16 +26,18 @@ function global:deactivate ([switch]$NonDestructive) { } deactivate -nondestructive - + $env:VIRTUAL_ENV="__VENV_DIR__" -# Set the prompt to include the env name -# Make sure _OLD_VIRTUAL_PROMPT is global -function global:_OLD_VIRTUAL_PROMPT {""} -copy-item function:prompt function:_OLD_VIRTUAL_PROMPT -function global:prompt { - Write-Host -NoNewline -ForegroundColor Green '__VENV_PROMPT__' - _OLD_VIRTUAL_PROMPT +if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) { + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT {""} + copy-item function:prompt function:_OLD_VIRTUAL_PROMPT + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green '__VENV_PROMPT__' + _OLD_VIRTUAL_PROMPT + } } # Clear PYTHONHOME diff --git a/Lib/weakref.py b/Lib/weakref.py index 2968fb9..787e33a 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -16,7 +16,8 @@ from _weakref import ( proxy, CallableProxyType, ProxyType, - ReferenceType) + ReferenceType, + _remove_dead_weakref) from _weakrefset import WeakSet, _IterationGuard @@ -105,13 +106,15 @@ class WeakValueDictionary(collections.MutableMapping): self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) - def remove(wr, selfref=ref(self)): + def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref): self = selfref() if self is not None: if self._iterating: self._pending_removals.append(wr.key) else: - del self.data[wr.key] + # Atomic removal is necessary since this function + # can be called asynchronously by the GC + _atomic_removal(d, wr.key) self._remove = remove # A list of keys to be removed self._pending_removals = [] @@ -125,9 +128,12 @@ class WeakValueDictionary(collections.MutableMapping): # We shouldn't encounter any KeyError, because this method should # always be called *before* mutating the dict. while l: - del d[l.pop()] + key = l.pop() + _remove_dead_weakref(d, key) def __getitem__(self, key): + if self._pending_removals: + self._commit_removals() o = self.data[key]() if o is None: raise KeyError(key) @@ -140,9 +146,13 @@ class WeakValueDictionary(collections.MutableMapping): del self.data[key] def __len__(self): - return len(self.data) - len(self._pending_removals) + if self._pending_removals: + self._commit_removals() + return len(self.data) def __contains__(self, key): + if self._pending_removals: + self._commit_removals() try: o = self.data[key]() except KeyError: @@ -158,6 +168,8 @@ class WeakValueDictionary(collections.MutableMapping): self.data[key] = KeyedRef(value, self._remove, key) def copy(self): + if self._pending_removals: + self._commit_removals() new = WeakValueDictionary() for key, wr in self.data.items(): o = wr() @@ -169,6 +181,8 @@ class WeakValueDictionary(collections.MutableMapping): def __deepcopy__(self, memo): from copy import deepcopy + if self._pending_removals: + self._commit_removals() new = self.__class__() for key, wr in self.data.items(): o = wr() @@ -177,6 +191,8 @@ class WeakValueDictionary(collections.MutableMapping): return new def get(self, key, default=None): + if self._pending_removals: + self._commit_removals() try: wr = self.data[key] except KeyError: @@ -190,6 +206,8 @@ class WeakValueDictionary(collections.MutableMapping): return o def items(self): + if self._pending_removals: + self._commit_removals() with _IterationGuard(self): for k, wr in self.data.items(): v = wr() @@ -197,6 +215,8 @@ class WeakValueDictionary(collections.MutableMapping): yield k, v def keys(self): + if self._pending_removals: + self._commit_removals() with _IterationGuard(self): for k, wr in self.data.items(): if wr() is not None: @@ -214,10 +234,14 @@ class WeakValueDictionary(collections.MutableMapping): keep the values around longer than needed. """ + if self._pending_removals: + self._commit_removals() with _IterationGuard(self): yield from self.data.values() def values(self): + if self._pending_removals: + self._commit_removals() with _IterationGuard(self): for wr in self.data.values(): obj = wr() @@ -239,24 +263,27 @@ class WeakValueDictionary(collections.MutableMapping): try: o = self.data.pop(key)() except KeyError: + o = None + if o is None: if args: return args[0] - raise - if o is None: - raise KeyError(key) + else: + raise KeyError(key) else: return o def setdefault(self, key, default=None): try: - wr = self.data[key] + o = self.data[key]() except KeyError: + o = None + if o is None: if self._pending_removals: self._commit_removals() self.data[key] = KeyedRef(default, self._remove, key) return default else: - return wr() + return o def update(*args, **kwargs): if not args: @@ -287,6 +314,8 @@ class WeakValueDictionary(collections.MutableMapping): keep the values around longer than needed. """ + if self._pending_removals: + self._commit_removals() return list(self.data.values()) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index e2ae042..7f2b43c 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1102,11 +1102,12 @@ class ZipFile: # set the modified flag so central directory gets written # even if no files are added to the archive self._didModify = True + self._start_disk = 0 try: - self.start_dir = self._start_disk = self.fp.tell() + self.start_dir = self.fp.tell() except (AttributeError, OSError): self.fp = _Tellable(self.fp) - self.start_dir = self._start_disk = 0 + self.start_dir = 0 self._seekable = False else: # Some file-like objects can provide tell() but not seek() diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 8dfd092..f59ae34 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -13,7 +13,7 @@ sphinx-build and the current versions of Sphinx now require at least Python 2.6. In addition to what is supplied with OS X 10.5+ and Xcode 3+, the script -requires an installed version of hg and a third-party version of +requires an installed version of git and a third-party version of Tcl/Tk 8.4 (for OS X 10.4 and 10.5 deployment targets) or Tcl/TK 8.5 (for 10.6 or later) installed in /Library/Frameworks. When installed, the Python built by this script will attempt to dynamically link first to @@ -23,7 +23,7 @@ installing the most recent ActiveTcl 8.4 or 8.5 version. 32-bit-only installer builds are still possible on OS X 10.4 with Xcode 2.5 and the installation of additional components, such as a newer Python -(2.5 is needed for Python parser updates), hg, and for the documentation +(2.5 is needed for Python parser updates), git, and for the documentation build either svn (pre-3.4.1) or sphinx-build (3.4.1 and later). Usage: see USAGE variable in the script. @@ -213,9 +213,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.0.2j", - url="https://www.openssl.org/source/openssl-1.0.2j.tar.gz", - checksum='96322138f0b69e61b7212bc53d5e912b', + name="OpenSSL 1.0.2k", + url="https://www.openssl.org/source/openssl-1.0.2k.tar.gz", + checksum='f965fc0bf01bf882b31314b61391ae65', patches=[ "openssl_sdk_makedepend.patch", ], @@ -635,9 +635,9 @@ def checkEnvironment(): base_path = base_path + ':' + OLD_DEVELOPER_TOOLS os.environ['PATH'] = base_path print("Setting default PATH: %s"%(os.environ['PATH'])) - # Ensure ws have access to hg and to sphinx-build. + # Ensure ws have access to git and to sphinx-build. # You may have to create links in /usr/bin for them. - runCommand('hg --version') + runCommand('git --version') runCommand('sphinx-build --version') def parseOptions(args=None): @@ -1142,8 +1142,9 @@ def buildPython(): shellQuote(WORKDIR)[1:-1], shellQuote(WORKDIR)[1:-1])) - print("Running make touch") - runCommand("make touch") + # bpo-29550: avoid using make touch until it is fixed for git + # print("Running make touch") + # runCommand("make touch") print("Running make") runCommand("make") diff --git a/Mac/BuildScript/openssl_sdk_makedepend.patch b/Mac/BuildScript/openssl_sdk_makedepend.patch index e22d67e..0caac0a 100644 --- a/Mac/BuildScript/openssl_sdk_makedepend.patch +++ b/Mac/BuildScript/openssl_sdk_makedepend.patch @@ -1,6 +1,6 @@ # HG changeset patch # -# using openssl 1.0.2j +# using openssl 1.0.2k # # - support building with an OS X SDK diff --git a/Mac/IDLE/IDLE.app/Contents/Info.plist b/Mac/IDLE/IDLE.app/Contents/Info.plist index f7c3b35..5507687 100644 --- a/Mac/IDLE/IDLE.app/Contents/Info.plist +++ b/Mac/IDLE/IDLE.app/Contents/Info.plist @@ -36,7 +36,7 @@ CFBundleExecutable IDLE CFBundleGetInfoString - %version%, © 2001-2016 Python Software Foundation + %version%, © 2001-2017 Python Software Foundation CFBundleIconFile IDLE.icns CFBundleIdentifier diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index 4a5eeb5..f1ab79f 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -40,7 +40,7 @@ CFBundleExecutable Python Launcher CFBundleGetInfoString - %VERSION%, © 2001-2016 Python Software Foundation + %VERSION%, © 2001-2017 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier diff --git a/Mac/Resources/app/Info.plist.in b/Mac/Resources/app/Info.plist.in index a0bb971..a23166e 100644 --- a/Mac/Resources/app/Info.plist.in +++ b/Mac/Resources/app/Info.plist.in @@ -37,7 +37,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - %version%, (c) 2001-2016 Python Software Foundation. + %version%, (c) 2001-2017 Python Software Foundation. CFBundleName Python CFBundlePackageType diff --git a/Mac/Resources/framework/Info.plist.in b/Mac/Resources/framework/Info.plist.in index fcba7d9..7a64619 100644 --- a/Mac/Resources/framework/Info.plist.in +++ b/Mac/Resources/framework/Info.plist.in @@ -17,9 +17,9 @@ CFBundlePackageType FMWK CFBundleShortVersionString - %VERSION%, (c) 2001-2016 Python Software Foundation. + %VERSION%, (c) 2001-2017 Python Software Foundation. CFBundleLongVersionString - %VERSION%, (c) 2001-2016 Python Software Foundation. + %VERSION%, (c) 2001-2017 Python Software Foundation. CFBundleSignature ???? CFBundleVersion diff --git a/Makefile.pre.in b/Makefile.pre.in index cd7d33d..8f27d73 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -41,9 +41,9 @@ RANLIB= @RANLIB@ READELF= @READELF@ SOABI= @SOABI@ LDVERSION= @LDVERSION@ -HGVERSION= @HGVERSION@ -HGTAG= @HGTAG@ -HGBRANCH= @HGBRANCH@ +GITVERSION= @GITVERSION@ +GITTAG= @GITTAG@ +GITBRANCH= @GITBRANCH@ PGO_PROF_GEN_FLAG=@PGO_PROF_GEN_FLAG@ PGO_PROF_USE_FLAG=@PGO_PROF_USE_FLAG@ LLVM_PROF_MERGER=@LLVM_PROF_MERGER@ @@ -740,9 +740,9 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \ $(MODOBJS) \ $(srcdir)/Modules/getbuildinfo.c $(CC) -c $(PY_CORE_CFLAGS) \ - -DHGVERSION="\"`LC_ALL=C $(HGVERSION)`\"" \ - -DHGTAG="\"`LC_ALL=C $(HGTAG)`\"" \ - -DHGBRANCH="\"`LC_ALL=C $(HGBRANCH)`\"" \ + -DGITVERSION="\"`LC_ALL=C $(GITVERSION)`\"" \ + -DGITTAG="\"`LC_ALL=C $(GITTAG)`\"" \ + -DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \ -o $@ $(srcdir)/Modules/getbuildinfo.c Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile @@ -858,8 +858,8 @@ UNICODE_DEPS = \ $(srcdir)/Objects/stringlib/unicode_format.h \ $(srcdir)/Objects/stringlib/unicodedefs.h +Objects/bytes_methods.o: $(srcdir)/Objects/bytes_methods.c $(BYTESTR_DEPS) Objects/bytesobject.o: $(srcdir)/Objects/bytesobject.c $(BYTESTR_DEPS) - Objects/bytearrayobject.o: $(srcdir)/Objects/bytearrayobject.c $(BYTESTR_DEPS) Objects/unicodeobject.o: $(srcdir)/Objects/unicodeobject.c $(UNICODE_DEPS) @@ -1244,7 +1244,7 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ turtledemo \ multiprocessing multiprocessing/dummy \ unittest unittest/test unittest/test/testmock \ - venv venv/scripts venv/scripts/posix \ + venv venv/scripts venv/scripts/common venv/scripts/posix \ curses pydoc_data libinstall: build_all $(srcdir)/Modules/xxmodule.c @for i in $(SCRIPTDIR) $(LIBDEST); \ diff --git a/Misc/ACKS b/Misc/ACKS index 2a3a278..c3b29a4 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -41,6 +41,7 @@ A. Amoroso Mark Anacker Shashwat Anand Anders Andersen +Tycho Andersen John Anderson Pehr Anderson Erik Andersén @@ -156,6 +157,7 @@ Finn Bock Paul Boddie Matthew Boedicker Robin Boerdijk +Andra Bogildea Nikolay Bogoychev David Bolen Wouter Bolsterlee @@ -189,6 +191,7 @@ Tom Bridgman Anthony Briggs Keith Briggs Tobias Brink +Dillon Brock Richard Brodie Michael Broghton Ammar Brohi @@ -217,6 +220,7 @@ Alastair Burt Tarn Weisner Burton Lee Busby Katherine Busch +Matthias Bussonnier Ralph Butler Laurent De Buyst Zach Byrne @@ -265,6 +269,7 @@ Albert Chin-A-Young Adal Chiriliuc Matt Chisholm Lita Cho +Sayan Chowdhury Anders Chrigström Tom Christiansen Renee Chu @@ -343,6 +348,7 @@ A. Jesse Jiryu Davis Merlijn van Deen John DeGood Ned Deily +Jim DeLaHunt Vincent Delft Arnaud Delobelle Konrad Delong @@ -367,6 +373,7 @@ Daniel Dittmar Josip Djolonga Walter Dörwald Jaromir Dolecek +Brendan Donegan Ismail Donmez Robert Donohue Marcos Donolo @@ -679,6 +686,7 @@ John Interrante Bob Ippolito Roger Irwin Atsuo Ishimoto +Alexey Izbyshev Kasia Jachim Adam Jackson Ben Jackson @@ -850,6 +858,7 @@ Julia Lawall Chris Lawrence Mark Lawrence Chris Laws +Michael Layzell Michael Lazar Brian Leair Mathieu Leduc-Hamel @@ -1138,6 +1147,7 @@ Alecsandru Patrascu Randy Pausch Samuele Pedroni Justin Peel +Loic Pefferkorn Marcel van der Peijl Berker Peksag Andreas Pelme @@ -1702,7 +1712,6 @@ Nickolai Zeldovich Yuxiao Zeng Uwe Zessin Cheng Zhang -Xiang Zhang Kai Zhu Tarek Ziadé Jelle Zijlstra @@ -1710,3 +1719,4 @@ Gennadiy Zlobin Doug Zongker Peter Åstrand evilzero +Dhushyanth Ramasamy diff --git a/Misc/HISTORY b/Misc/HISTORY index 6cadaec..4ce431f 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -7,6 +7,2191 @@ As you read on you go back to the dark ages of Python's history. ====================================================================== +What's New in Python 3.4.6? +=========================== + +Release date: 2017-01-17 + +There were no changes between 3.4.6rc1 and 3.4.6 final. + + +What's New in Python 3.4.6rc1? +============================== + +Release date: 2017-01-02 + +Core and Builtins +----------------- + +- Issue #28648: Fixed crash in Py_DecodeLocale() in debug build on Mac OS X + when decode astral characters. Patch by Xiang Zhang. + +- Issue #28426: Fixed potential crash in PyUnicode_AsDecodedObject() in debug + build. + +Library +------- + +- Issue #28563: Fixed possible DoS and arbitrary code execution when handle + plural form selections in the gettext module. The expression parser now + supports exact syntax supported by GNU gettext. + +- In the curses module, raise an error if window.getstr() or window.instr() is + passed a negative value. + +- Issue #27783: Fix possible usage of uninitialized memory in operator.methodcaller. + +- Issue #27774: Fix possible Py_DECREF on unowned object in _sre. + +- Issue #27760: Fix possible integer overflow in binascii.b2a_qp. + +- Issue #27758: Fix possible integer overflow in the _csv module for large record + lengths. + +- Issue #27568: Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the + HTTP_PROXY variable when REQUEST_METHOD environment is set, which indicates + that the script is in CGI mode. + +- Issue #27759: Fix selectors incorrectly retain invalid file descriptors. + Patch by Mark Williams. + +Build +----- + +- Issue #28248: Update Windows build to use OpenSSL 1.0.2j. + +Tests +----- + +- Issue #27369: In test_pyexpat, avoid testing an error message detail that + changed in Expat 2.2.0. + + +What's New in Python 3.4.5? +=========================== + +Release date: 2016-06-26 + +Tests +----- + +- Issue #26867: Ubuntu's openssl OP_NO_SSLv3 is forced on by default; fix test. + + +What's New in Python 3.4.5rc1? +============================== + +Release date: 2016-06-11 + +Core and Builtins +----------------- + +- 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(). + +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 #25939: On Windows open the cert store readonly in ssl.enum_certificates. + +- 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. + +- Skip getaddrinfo if host is already resolved. + Patch by A. Jesse Jiryu Davis. + +- Add asyncio.timeout() context manager. + +- Issue #26050: Add asyncio.StreamReader.readuntil() method. + Patch by Марк Коренберг. + +Tests +----- + +- Issue #25940: Changed test_ssl to use self-signed.pythontest.net. This + avoids relying on svn.python.org, which recently changed root certificate. + + +What's New in Python 3.4.4? +=========================== + +Release date: 2015/12/20 + +Windows +------- + +- Issue #25844: Corrected =/== typo potentially leading to crash in launcher. + + +What's New in Python 3.4.4rc1? +============================== + +Release date: 2015/12/06 + +Core and Builtins +----------------- + +- Issue #25709: Fixed problem with in-place string concatenation and utf-8 + cache. + +- 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 #25388: Fixed tokenizer crash when processing undecodable source code + with a null byte. + +- Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now + rejects builtin types with not defined __new__. + +- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() + and eval() are passed bytes-like objects. These objects are not + necessarily terminated by a null byte, but the functions assumed they were. + +- Issue #24402: Fix input() to prompt to the redirected stdout when + sys.stdout.fileno() fails. + +- Issue #24806: Prevent builtin types that are not allowed to be subclassed from + being subclassed through multiple inheritance. + +- Issue #24848: Fixed a number of bugs in UTF-7 decoding of misformed data. + +- Issue #25280: Import trace messages emitted in verbose (-v) mode are no + longer formatted twice. + +- Issue #25003: os.urandom() doesn't use getentropy() on Solaris because + getentropy() is blocking, whereas os.urandom() should not block. getentropy() + is supported since Solaris 11.3. + +- Issue #25182: The stdprinter (used as sys.stderr before the io module is + imported at startup) now uses the backslashreplace error handler. + +- Issue #24891: Fix a race condition at Python startup if the file descriptor + of stdin (0), stdout (1) or stderr (2) is closed while Python is creating + sys.stdin, sys.stdout and sys.stderr objects. These attributes are now set + to None if the creation of the object failed, instead of raising an OSError + exception. Initial patch written by Marco Paolini. + +- Issue #21167: NAN operations are now handled correctly when python is + compiled with ICC even if -fp-model strict is not specified. + +- Issue #4395: Better testing and documentation of binary operators. + Patch by Martin Panter. + +- Issue #24467: Fixed possible buffer over-read in bytearray. The bytearray + object now always allocates place for trailing null byte and it's buffer now + is always null-terminated. + +- Issue #24115: Update uses of PyObject_IsTrue(), PyObject_Not(), + PyObject_IsInstance(), PyObject_RichCompareBool() and _PyDict_Contains() + to check for and handle errors correctly. + +- Issue #24257: Fixed system error in the comparison of faked + types.SimpleNamespace. + +- Issue #22939: Fixed integer overflow in iterator object. Patch by + Clement Rouault. + +- Issue #23985: Fix a possible buffer overrun when deleting a slice from + the front of a bytearray and then appending some other bytes data. + +- Issue #24102: Fixed exception type checking in standard error handlers. + +- Issue #23757: PySequence_Tuple() incorrectly called the concrete list API + when the data was a list subclass. + +- Issue #24407: Fix crash when dict is mutated while being updated. + +- Issue #24096: Make warnings.warn_explicit more robust against mutation of the + warnings.filters list. + +- Issue #23996: Avoid a crash when a delegated generator raises an + unnormalized StopIteration exception. Patch by Stefan Behnel. + +- Issue #24022: Fix tokenizer crash when processing undecodable source code. + +- Issue #23309: Avoid a deadlock at shutdown if a daemon thread is aborted + while it is holding a lock to a buffered I/O object, and the main thread + tries to use the same I/O object (typically stdout or stderr). A fatal + error is emitted instead. + +- Issue #22977: Fixed formatting Windows error messages on Wine. + Patch by Martin Panter. + +- Issue #23803: Fixed str.partition() and str.rpartition() when a separator + is wider then partitioned string. + +- Issue #23192: Fixed generator lambdas. Patch by Bruno Cauet. + +- Issue #23629: Fix the default __sizeof__ implementation for variable-sized + objects. + +- Issue #24044: Fix possible null pointer dereference in list.sort in out of + memory conditions. + +- Issue #21354: PyCFunction_New function is exposed by python DLL again. + +Library +------- + +- 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 #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. + +- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) + when the OS gives priority to errors such as EACCES over EEXIST. + +- Issue #25593: Change semantics of EventLoop.stop() in asyncio. + +- Issue #6973: When we know a subprocess.Popen process has died, do + not allow the send_signal(), terminate(), or kill() methods to do + anything as they could potentially signal a different process. + +- Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer(). + +- Issue #25590: In the Readline completer, only call getattr() once per + attribute. + +- Issue #25498: Fix a crash when garbage-collecting ctypes objects created + by wrapping a memoryview. This was a regression made in 3.4.3. Based + on patch by Eryksun. + +- Issue #18010: Fix the pydoc web server's module search function to handle + exceptions from importing packages. + +- Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' + at the end if the FileInput was opened with binary mode. + Patch by Ryosuke Ito. + +- Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating + ssl.SSLContext. + +- Issue #25569: Fix memory leak in SSLSocket.getpeercert(). + +- Issue #21827: Fixed textwrap.dedent() for the case when largest common + whitespace is a substring of smallest leading whitespace. + Based on patch by Robert Li. + +- Issue #25471: Sockets returned from accept() shouldn't appear to be + nonblocking. + +- Issue #25441: asyncio: Raise error from drain() when socket is closed. + +- Issue #25411: Improved Unicode support in SMTPHandler through better use of + the email package. Thanks to user simon04 for the patch. + +- Issue #25380: Fixed protocol for the STACK_GLOBAL opcode in + pickletools.opcodes. + +- Issue #23972: Updates asyncio datagram create method allowing reuseport + and reuseaddr socket options to be set prior to binding the socket. + Mirroring the existing asyncio create_server method the reuseaddr option + for datagram sockets defaults to True if the O/S is 'posix' (except if the + platform is Cygwin). Patch by Chris Laws. + +- Issue #25304: Add asyncio.run_coroutine_threadsafe(). This lets you + submit a coroutine to a loop from another thread, returning a + concurrent.futures.Future. By Vincent Michel. + +- Issue #25319: When threading.Event is reinitialized, the underlying condition + should use a regular lock rather than a recursive lock. + +- Issue #25232: Fix CGIRequestHandler to split the query from the URL at the + first question mark (?) rather than the last. Patch from Xiang Zhang. + +- Issue #24657: Prevent CGIRequestHandler from collapsing slashes in the + query part of the URL as if it were a path. Patch from Xiang Zhang. + +- Issue #22958: Constructor and update method of weakref.WeakValueDictionary + now accept the self and the dict keyword arguments. + +- Issue #22609: Constructor of collections.UserDict now accepts the self keyword + argument. + +- 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. + +- Issue #25034: Fix string.Formatter problem with auto-numbering and + nested format_specs. Patch by Anthon van der Neut. + +- Issue #25233: Rewrite the guts of asyncio.Queue and + asyncio.Semaphore to be more understandable and correct. + +- Issue #23600: Default implementation of tzinfo.fromutc() was returning + wrong results in some cases. + +- Issue #25203: Failed readline.set_completer_delims() no longer left the + module in inconsistent state. + +- Prevent overflow in _Unpickler_Read. + +- Issue #25047: The XML encoding declaration written by Element Tree now + respects the letter case given by the user. This restores the ability to + write encoding names in uppercase like "UTF-8", which worked in Python 2. + +- Issue #19143: platform module now reads Windows version from kernel32.dll to + avoid compatibility shims. + +- Issue #23517: Fix rounding in fromtimestamp() and utcfromtimestamp() methods + of datetime.datetime: microseconds are now rounded to nearest with ties + going to nearest even integer (ROUND_HALF_EVEN), instead of being rounding + towards zero (ROUND_DOWN). It's important that these methods use the same + rounding mode than datetime.timedelta to keep the property: + (datetime(1970,1,1) + timedelta(seconds=t)) == datetime.utcfromtimestamp(t). + It also the rounding mode used by round(float) for example. + +- Issue #24684: socket.socket.getaddrinfo() now calls + PyUnicode_AsEncodedString() instead of calling the encode() method of the + host, to handle correctly custom string with an encode() method which doesn't + return a byte string. The encoder of the IDNA codec is now called directly + instead of calling the encode() method of the string. + +- Issue #24982: shutil.make_archive() with the "zip" format now adds entries + for directories (including empty directories) in ZIP file. + +- Issue #24857: Comparing call_args to a long sequence now correctly returns a + boolean result instead of raising an exception. Patch by A Kaptur. + +- Issue #25019: Fixed a crash caused by setting non-string key of expat parser. + Based on patch by John Leitch. + +- Issue #24917: time_strftime() buffer over-read. + +- Issue #23144: Make sure that HTMLParser.feed() returns all the data, even + when convert_charrefs is True. + +- Issue #16180: Exit pdb if file has syntax error, instead of trapping user + in an infinite loop. Patch by Xavier de Gaye. + +- Issue #21112: Fix regression in unittest.expectedFailure on subclasses. + Patch from Berker Peksag. + +- Issue #24931: Instances of subclasses of namedtuples have their own __dict__ + which breaks the inherited __dict__ property and breaks the _asdict() method. + Removed the __dict__ property to prevent the conflict and fixed _asdict(). + +- Issue #24764: cgi.FieldStorage.read_multi() now ignores the Content-Length + header in part headers. Patch written by Peter Landry and reviewed by Pierre + Quentel. + +- Issue #24774: Fix docstring in http.server.test. Patch from Chiu-Hsiang Hsu. + +- Issue #21159: Improve message in configparser.InterpolationMissingOptionError. + Patch from Łukasz Langa. + +- Issue #23888: Handle fractional time in cookie expiry. Patch by ssh. + +- Issue #23004: mock_open() now reads binary data correctly when the type of + read_data is bytes. Initial patch by Aaron Hill. + +- Issue #23652: Make it possible to compile the select module against the + libc headers from the Linux Standard Base, which do not include some + EPOLL macros. Patch by Matt Frank. + +- Issue #22932: Fix timezones in email.utils.formatdate. + Patch from Dmitry Shachnev. + +- Issue #23779: imaplib raises TypeError if authenticator tries to abort. + Patch from Craig Holmquist. + +- Issue #23319: Fix ctypes.BigEndianStructure, swap correctly bytes. Patch + written by Matthieu Gautier. + +- Issue #23254: Document how to close the TCPServer listening socket. + Patch from Martin Panter. + +- Issue #19450: Update Windows and OS X installer builds to use SQLite 3.8.11. + +- Issue #23441: rcompleter now prints a tab character instead of displaying + possible completions for an empty word. Initial patch by Martin Sekera. + +- Issue #24735: Fix invalid memory access in + itertools.combinations_with_replacement(). + +- Issue #17527: Add PATCH to wsgiref.validator. Patch from Luca Sbardella. + +- Issue #24683: Fixed crashes in _json functions called with arguments of + inappropriate type. + +- Issue #21697: shutil.copytree() now correctly handles symbolic links that + point to directories. Patch by Eduardo Seabra and Thomas Kluyver. + +- Issue #24620: Random.setstate() now validates the value of state last element. + +- Issue #22153: Improve unittest docs. Patch from Martin Panter and evilzero. + +- Issue #24206: Fixed __eq__ and __ne__ methods of inspect classes. + +- Issue #21750: mock_open.read_data can now be read from each instance, as it + could in Python 3.3. + +- Issue #23247: Fix a crash in the StreamWriter.reset() of CJK codecs. + +- Issue #18622: unittest.mock.mock_open().reset_mock would recurse infinitely. + Patch from Nicola Palumbo and Laurent De Buyst. + +- Issue #24608: chunk.Chunk.read() now always returns bytes, not str. + +- Issue #18684: Fixed reading out of the buffer in the re module. + +- Issue #24259: tarfile now raises a ReadError if an archive is truncated + inside a data segment. + +- Issue #24552: Fix use after free in an error case of the _pickle module. + +- Issue #24514: tarfile now tolerates number fields consisting of only + whitespace. + +- Issue #19176: Fixed doctype() related bugs in C implementation of ElementTree. + A deprecation warning no longer issued by XMLParser subclass with default + doctype() method. Direct call of doctype() now issues a warning. Parser's + doctype() now is not called if target's doctype() is called. Based on patch + by Martin Panter. + +- Issue #20387: Restore semantic round-trip correctness in tokenize/untokenize + for tab-indented blocks. + +- Issue #24456: Fixed possible buffer over-read in adpcm2lin() and lin2adpcm() + functions of the audioop module. + +- Issue #24336: The contextmanager decorator now works with functions with + keyword arguments called "func" and "self". Patch by Martin Panter. + +- Issue #24489: ensure a previously set C errno doesn't disturb cmath.polar(). + +- Issue #5633: Fixed timeit when the statement is a string and the setup is not. + +- Issue #24326: Fixed audioop.ratecv() with non-default weightB argument. + Original patch by David Moore. + +- Issue #23840: tokenize.open() now closes the temporary binary file on error + to fix a resource warning. + +- Issue #24257: Fixed segmentation fault in sqlite3.Row constructor with faked + cursor type. + +- Issue #22107: tempfile.gettempdir() and tempfile.mkdtemp() now try again + when a directory with the chosen name already exists on Windows as well as + on Unix. tempfile.mkstemp() now fails early if parent directory is not + valid (not exists or is a file) on Windows. + +- Issue #6598: Increased time precision and random number range in + email.utils.make_msgid() to strengthen the uniqueness of the message ID. + +- Issue #24091: Fixed various crashes in corner cases in C implementation of + ElementTree. + +- Issue #21931: msilib.FCICreate() now raises TypeError in the case of a bad + argument instead of a ValueError with a bogus FCI error number. + Patch by Jeffrey Armstrong. + +- Issue #23796: peek and read1 methods of BufferedReader now raise ValueError + if they called on a closed object. Patch by John Hergenroeder. + +- Issue #24521: Fix possible integer overflows in the pickle module. + +- Issue #22931: Allow '[' and ']' in cookie values. + +- Issue #20274: Remove ignored and erroneous "kwargs" parameters from three + METH_VARARGS methods on _sqlite.Connection. + +- Issue #24094: Fix possible crash in json.encode with poorly behaved dict + subclasses. + +- Asyncio issue 222 / PR 231 (Victor Stinner) -- fix @coroutine + functions without __name__. + +- Issue #9246: On POSIX, os.getcwd() now supports paths longer than 1025 bytes. + Patch written by William Orr. + +- The keywords attribute of functools.partial is now always a dictionary. + +- Issues #24099, #24100, and #24101: Fix free-after-use bug in heapq's siftup + and siftdown functions. + +- Backport collections.deque fixes from Python 3.5. Prevents reentrant badness + during deletion by deferring the decref until the container has been restored + to a consistent state. + +- Issue #23008: Fixed resolving attributes with boolean value is False in pydoc. + +- Fix asyncio issue 235: LifoQueue and PriorityQueue's put didn't + increment unfinished tasks (this bug was introduced in 3.4.3 when + JoinableQueue was merged with Queue). + +- Issue #23908: os functions now reject paths with embedded null character + on Windows instead of silently truncate them. + +- Issue #23728: binascii.crc_hqx() could return an integer outside of the range + 0-0xffff for empty data. + +- Issue #23811: Add missing newline to the PyCompileError error message. + Patch by Alex Shkop. + +- Issue #17898: Fix exception in gettext.py when parsing certain plural forms. + +- Issue #22982: Improve BOM handling when seeking to multiple positions of + a writable text file. + +- Issue #23865: close() methods in multiple modules now are idempotent and more + robust at shutdown. If they need to release multiple resources, all are + released even if errors occur. + +- Issue #23881: urllib.request.ftpwrapper constructor now closes the socket if + the FTP connection failed to fix a ResourceWarning. + +- Issue #23400: Raise same exception on both Python 2 and 3 if sem_open is not + available. Patch by Davin Potts. + +- Issue #15133: _tkinter.tkapp.getboolean() now supports Tcl_Obj and always + returns bool. tkinter.BooleanVar now validates input values (accepted bool, + int, str, and Tcl_Obj). tkinter.BooleanVar.get() now always returns bool. + +- Issue #23338: Fixed formatting ctypes error messages on Cygwin. + Patch by Makoto Kato. + +- Issue #16840: Tkinter now supports 64-bit integers added in Tcl 8.4 and + arbitrary precision integers added in Tcl 8.5. + +- Issue #23834: Fix socket.sendto(), use the C Py_ssize_t type to store the + result of sendto() instead of the C int type. + +- Issue #21526: Tkinter now supports new boolean type in Tcl 8.5. + +- Issue #23838: linecache now clears the cache and returns an empty result on + MemoryError. + +- Issue #18473: Fixed 2to3 and 3to2 compatible pickle mappings. Fixed + ambigious reverse mappings. Added many new mappings. Import mapping is no + longer applied to modules already mapped with full name mapping. + +- Issue #23745: The new email header parser now handles duplicate MIME + parameter names without error, similar to how get_param behaves. + +- Issue #23792: Ignore KeyboardInterrupt when the pydoc pager is active. + This mimics the behavior of the standard unix pagers, and prevents + pipepager from shutting down while the pager itself is still running. + +- Issue #23742: ntpath.expandvars() no longer loses unbalanced single quotes. + +- Issue #21802: The reader in BufferedRWPair now is closed even when closing + writer failed in BufferedRWPair.close(). + +- Issue #23671: string.Template now allows to specify the "self" parameter as + keyword argument. string.Formatter now allows to specify the "self" and + the "format_string" parameters as keyword arguments. + +- Issue #21560: An attempt to write a data of wrong type no longer cause + GzipFile corruption. Original patch by Wolfgang Maier. + +- Issue #23647: Increase impalib's MAXLINE to accommodate modern mailbox sizes. + +- Issue #23539: If body is None, http.client.HTTPConnection.request now sets + Content-Length to 0 for PUT, POST, and PATCH headers to avoid 411 errors from + some web servers. + +- Issue #22351: The nntplib.NNTP constructor no longer leaves the connection + and socket open until the garbage collector cleans them up. Patch by + Martin Panter. + +- Issue #23136: _strptime now uniformly handles all days in week 0, including + Dec 30 of previous year. Based on patch by Jim Carroll. + +- Issue #23700: Iterator of NamedTemporaryFile now keeps a reference to + NamedTemporaryFile instance. Patch by Bohuslav Kabrda. + +- Issue #22903: The fake test case created by unittest.loader when it fails + importing a test module is now picklable. + +- Issue #23568: Add rdivmod support to MagicMock() objects. + Patch by HÃ¥kan Lövdahl. + +- Issue #23138: Fixed parsing cookies with absent keys or values in cookiejar. + Patch by Demian Brecht. + +- Issue #23051: multiprocessing.Pool methods imap() and imap_unordered() now + handle exceptions raised by an iterator. Patch by Alon Diamant and Davin + Potts. + +- Issue #22928: Disabled HTTP header injections in http.client. + Original patch by Demian Brecht. + +- Issue #23615: Modules bz2, tarfile and tokenize now can be reloaded with + imp.reload(). Patch by Thomas Kluyver. + +- Issue #23476: In the ssl module, enable OpenSSL's X509_V_FLAG_TRUSTED_FIRST + flag on certificate stores when it is available. + +- Issue #23576: Avoid stalling in SSL reads when EOF has been reached in the + SSL layer but the underlying connection hasn't been closed. + +- Issue #23504: Added an __all__ to the types module. + +- Issue #20204: Added the __module__ attribute to _tkinter classes. + +- Issue #23521: Corrected pure python implementation of timedelta division. + + * Eliminated OverflowError from timedelta * float for some floats; + * Corrected rounding in timedlta true division. + +- Issue #21619: Popen objects no longer leave a zombie after exit in the with + statement if the pipe was broken. Patch by Martin Panter. + +- Issue #6639: Module-level turtle functions no longer raise TclError after + closing the window. + +- Issues #814253, #9179: Warnings now are raised when group references and + conditional group references are used in lookbehind assertions in regular + expressions. + +- Issue #23215: Multibyte codecs with custom error handlers that ignores errors + consumed too much memory and raised SystemError or MemoryError. + Original patch by Aleksi Torhamo. + +- Issue #5700: io.FileIO() called flush() after closing the file. + flush() was not called in close() if closefd=False. + +- Issue #23374: Fixed pydoc failure with non-ASCII files when stdout encoding + differs from file system encoding (e.g. on Mac OS). + +- Issue #23481: Remove RC4 from the SSL module's default cipher list. + +- Issue #21548: Fix pydoc.synopsis() and pydoc.apropos() on modules with empty + docstrings. + +- Issue #22885: Fixed arbitrary code execution vulnerability in the dbm.dumb + module. Original patch by Claudiu Popa. + +- Issue #23146: Fix mishandling of absolute Windows paths with forward + slashes in pathlib. + +- Issue #23421: Fixed compression in tarfile CLI. Patch by wdv4758h. + +- Issue #23367: Fix possible overflows in the unicodedata module. + +- Issue #23361: Fix possible overflow in Windows subprocess creation code. + +- Issue #23801: Fix issue where cgi.FieldStorage did not always ignore the + entire preamble to a multipart body. + +- Issue #23310: Fix MagicMock's initializer to work with __methods__, just + like configure_mock(). Patch by Kasia Jachim. + +- asyncio: New event loop APIs: set_task_factory() and get_task_factory(). + +- asyncio: async() function is deprecated in favour of ensure_future(). + +- Issue #23898: Fix inspect.classify_class_attrs() to support attributes + with overloaded __eq__ and __bool__. Patch by Mike Bayer. + +- Issue #24298: Fix inspect.signature() to correctly unwrap wrappers + around bound methods. + +- Issue #23572: Fixed functools.singledispatch on classes with falsy + metaclasses. Patch by Ethan Furman. + +IDLE +---- + +- 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. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + 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 + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. + +- Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. + It is more or less IDLE Classic inverted, with a cobalt blue background. + Strings, comments, keywords, ... are still green, red, orange, ... . + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. + +- Issue #25224: README.txt is now an idlelib index for IDLE developers and + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. + +- Issue #24820: Users can now set breakpoint colors in + Settings -> Custom Highlighting. Original patch by Mark Roseman. + +- Issue #24972: Inactive selection background now matches active selection + background, as configured by users, on all systems. Found items are now + always highlighted on Windows. Initial patch by Mark Roseman. + +- Issue #24570: Idle: make calltip and completion boxes appear on Macs + affected by a tk regression. Initial patch by Mark Roseman. + +- Issue #24988: Idle ScrolledList context menus (used in debugger) + now work on Mac Aqua. Patch by Mark Roseman. + +- Issue #24801: Make right-click for context menu work on Mac Aqua. + Patch by Mark Roseman. + +- Issue #25173: Associate tkinter messageboxes with a specific widget. + For Mac OSX, make them a 'sheet'. Patch by Mark Roseman. + +- Issue #25198: Enhance the initial html viewer now used for Idle Help. + * Properly indent fixed-pitch text (patch by Mark Roseman). + * Give code snippet a very Sphinx-like light blueish-gray background. + * Re-use initial width and height set by users for shell and editor. + * When the Table of Contents (TOC) menu is used, put the section header + at the top of the screen. + +- Issue #25225: Condense and rewrite Idle doc section on text colors. + +- Issue #21995: Explain some differences between IDLE and console Python. + +- Issue #22820: Explain need for *print* when running file from Idle editor. + +- Issue #25224: Doc: augment Idle feature list and no-subprocess section. + +- Issue #25219: Update doc for Idle command line options. + Some were missing and notes were not correct. + +- Issue #24861: Most of idlelib is private and subject to change. + Use idleib.idle.* to start Idle. See idlelib.__init__.__doc__. + +- Issue #25199: Idle: add synchronization comments for future maintainers. + +- Issue #16893: Replace help.txt with help.html for Idle doc display. + The new idlelib/help.html is rstripped Doc/build/html/library/idle.html. + It looks better than help.txt and will better document Idle as released. + The tkinter html viewer that works for this file was written by Mark Roseman. + The now unused EditorWindow.HelpDialog class and helt.txt file are deprecated. + +- Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. + +- Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). + +- Issue #23672: Allow Idle to edit and run files with astral chars in name. + Patch by Mohd Sanad Zaki Rizvi. + +- Issue 24745: Idle editor default font. Switch from Courier to + platform-sensitive TkFixedFont. This should not affect current customized + font selections. If there is a problem, edit $HOME/.idlerc/config-main.cfg + and remove 'fontxxx' entries from [Editor Window]. Patch by Mark Roseman. + +- Issue #21192: Idle editor. When a file is run, put its name in the restart bar. + Do not print false prompts. Original patch by Adnan Umer. + +- Issue #13884: Idle menus. Remove tearoff lines. Patch by Roger Serwy. + +- Issue #23184: remove unused names and imports in idlelib. + Initial patch by Al Sweigart. + +Tests +----- + +- Issue #25616: Tests for OrderedDict are extracted from test_collections + into separate file test_ordered_dict. + +- Issue #25099: Make test_compileall not fail when an entry on sys.path cannot + be written to (commonly seen in administrative installs on Windows). + +- Issue #24751: When running regrtest with the ``-w`` command line option, + a test run is no longer marked as a failure if all tests succeed when + re-run. + +- Issue #21520: test_zipfile no longer fails if the word 'bad' appears + anywhere in the name of the current directory. + +- Issue #23799: Added test.support.start_threads() for running and + cleaning up multiple threads. + +- Issue #22390: test.regrtest now emits a warning if temporary files or + directories are left after running a test. + +- Issue #23583: Added tests for standard IO streams in IDLE. + +Build +----- + +- Issue #23445: pydebug builds now use "gcc -Og" where possible, to make + the resulting executable faster. + +- Issue #24603: Update Windows builds to use OpenSSL1.0.2d + and OS X 10.5 installer to use OpenSSL 1.0.2e. + +C API +----- + +- Issue #23998: PyImport_ReInitLock() now checks for lock allocation error + +Documentation +------------- + +- 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 + than the Expressions chapter. Added details of comparing range() objects, + and default behaviour and consistency suggestions for user-defined classes. + Patch from Andy Maier. + +- Issue #24952: Clarify the default size argument of stack_size() in + the "threading" and "_thread" modules. Patch from Mattip. + +- Issue #24808: Update the types of some PyTypeObject fields. Patch by + Joseph Weston. + +- Issue #22812: Fix unittest discovery examples. + Patch from Pam McA'Nulty. + +- Issue #24129: Clarify the reference documentation for name resolution. + This includes removing the assumption that readers will be familiar with the + name resolution scheme Python used prior to the introduction of lexical + scoping for function namespaces. Patch by Ivan Levkivskyi. + +- Issue #20769: Improve reload() docs. Patch by Dorian Pula. + +- Issue #23589: Remove duplicate sentence from the FAQ. Patch by Yongzhi Pan. + +- Issue #24729: Correct IO tutorial to match implementation regarding + encoding parameter to open function. + +- Issue #24351: Clarify what is meant by "identifier" in the context of + string.Template instances. + +- Issue #22155: Add File Handlers subsection with createfilehandler to tkinter + doc. Remove obsolete example from FAQ. Patch by Martin Panter. + +- Issue #24029: Document the name binding behavior for submodule imports. + +- Issue #24077: Fix typo in man page for -I command option: -s, not -S. + +Tools/Demos +----------- + +- Issue #25440: Fix output of python-config --extension-suffix. + +- Issue #23330: h2py now supports arbitrary filenames in #include. + +- Issue #24031: make patchcheck now supports git checkouts, too. + +Windows +------- + +- Issue #24306: Sets component ID for launcher to match 3.5 and later + to avoid downgrading. + +- Issue #25022: Removed very outdated PC/example_nt/ directory. + + +What's New in Python 3.4.3? +=========================== + +Release date: 2015-02-23 + +Core and Builtins +----------------- + +- Issue #22735: Fix many edge cases (including crashes) involving custom mro() + implementations. + +- Issue #22896: Avoid using PyObject_AsCharBuffer(), PyObject_AsReadBuffer() + and PyObject_AsWriteBuffer(). + +- Issue #21295: Revert some changes (issue #16795) to AST line numbers and + column offsets that constituted a regression. + +- Issue #21408: The default __ne__() now returns NotImplemented if __eq__() + returned NotImplemented. Original patch by Martin Panter. + +- Issue #23321: Fixed a crash in str.decode() when error handler returned + replacment string longer than mailformed input data. + +- Issue #23048: Fix jumping out of an infinite while loop in the pdb. + +- Issue #20335: bytes constructor now raises TypeError when encoding or errors + is specified with non-string argument. Based on patch by Renaud Blanch. + +- Issue #22335: Fix crash when trying to enlarge a bytearray to 0x7fffffff + bytes on a 32-bit platform. + +- Issue #22653: Fix an assertion failure in debug mode when doing a reentrant + dict insertion in debug mode. + +- Issue #22643: Fix integer overflow in Unicode case operations (upper, lower, + title, swapcase, casefold). + +- Issue #22604: Fix assertion error in debug mode when dividing a complex + number by (nan+0j). + +- Issue #22470: Fixed integer overflow issues in "backslashreplace", + "xmlcharrefreplace", and "surrogatepass" error handlers. + +- Issue #22520: Fix overflow checking when generating the repr of a unicode + object. + +- Issue #22519: Fix overflow checking in PyBytes_Repr. + +- Issue #22518: Fix integer overflow issues in latin-1 encoding. + +- Issue #23165: Perform overflow checks before allocating memory in the + _Py_char2wchar function. + +Library +------- + +- Issue #23399: pyvenv creates relative symlinks where possible. + +- Issue #23099: Closing io.BytesIO with exported buffer is rejected now to + prevent corrupting exported buffer. + +- Issue #23363: Fix possible overflow in itertools.permutations. + +- Issue #23364: Fix possible overflow in itertools.product. + +- Issue #23366: Fixed possible integer overflow in itertools.combinations. + +- Issue #23369: Fixed possible integer overflow in + _json.encode_basestring_ascii. + +- Issue #23353: Fix the exception handling of generators in + PyEval_EvalFrameEx(). At entry, save or swap the exception state even if + PyEval_EvalFrameEx() is called with throwflag=0. At exit, the exception state + is now always restored or swapped, not only if why is WHY_YIELD or + WHY_RETURN. Patch co-written with Antoine Pitrou. + +- Issue #18518: timeit now rejects statements which can't be compiled outside + a function or a loop (e.g. "return" or "break"). + +- Issue #23094: Fixed readline with frames in Python implementation of pickle. + +- Issue #23268: Fixed bugs in the comparison of ipaddress classes. + +- Issue #21408: Removed incorrect implementations of __ne__() which didn't + returned NotImplemented if __eq__() returned NotImplemented. The default + __ne__() now works correctly. + +- Issue #19996: :class:`email.feedparser.FeedParser` now handles (malformed) + headers with no key rather than assuming the body has started. + +- Issue #23248: Update ssl error codes from latest OpenSSL git master. + +- Issue #23098: 64-bit dev_t is now supported in the os module. + +- Issue #23250: In the http.cookies module, capitalize "HttpOnly" and "Secure" + as they are written in the standard. + +- Issue #23063: In the disutils' check command, fix parsing of reST with code or + code-block directives. + +- Issue #23209, #23225: selectors.BaseSelector.close() now clears its internal + reference to the selector mapping to break a reference cycle. Initial patch + written by Martin Richard. + +- Issue #21356: Make ssl.RAND_egd() optional to support LibreSSL. The + availability of the function is checked during the compilation. Patch written + by Bernard Spil. + +- Issue #20896, #22935: The :func:`ssl.get_server_certificate` function now + uses the :data:`~ssl.PROTOCOL_SSLv23` protocol by default, not + :data:`~ssl.PROTOCOL_SSLv3`, for maximum compatibility and support platforms + where :data:`~ssl.PROTOCOL_SSLv3` support is disabled. + +- Issue #23111: In the ftplib, make ssl.PROTOCOL_SSLv23 the default protocol + version. + +- Issue #23132: Mitigate regression in speed and clarity in functools.total_ordering. + +- Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(), + instead of reading /dev/urandom, to get pseudo-random bytes. + +- Issue #23112: Fix SimpleHTTPServer to correctly carry the query string and + fragment when it redirects to add a trailing slash. + +- Issue #23093: In the io, module allow more operations to work on detached + streams. + +- Issue #19104: pprint now produces evaluable output for wrapped strings. + +- Issue #23071: Added missing names to codecs.__all__. Patch by Martin Panter. + +- Issue #15513: Added a __sizeof__ implementation for pickle classes. + +- Issue #19858: pickletools.optimize() now aware of the MEMOIZE opcode, can + produce more compact result and no longer produces invalid output if input + data contains MEMOIZE opcodes together with PUT or BINPUT opcodes. + +- Issue #22095: Fixed HTTPConnection.set_tunnel with default port. The port + value in the host header was set to "None". Patch by Demian Brecht. + +- Issue #23016: A warning no longer produces an AttributeError when the program + 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. + 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. + +- Issue #1218234: Fix inspect.getsource() to load updated source of + reloaded module. Initial patch by Berker Peksag. + +- Issue #22959: In the constructor of http.client.HTTPSConnection, prefer the + context's check_hostname attribute over the *check_hostname* parameter. + +- Issue #16043: Add a default limit for the amount of data xmlrpclib.gzip_decode + will return. This resolves CVE-2013-1753. + +- Issue #22966: Fix __pycache__ pyc file name clobber when pyc_compile is + asked to compile a source file containing multiple dots in the source file + name. + +- Issue #21971: Update turtledemo doc and add module to the index. + +- Issue #21032. Fixed socket leak if HTTPConnection.getresponse() fails. + Original patch by Martin Panter. + +- Issue #22960: Add a context argument to xmlrpclib.ServerProxy constructor. + +- Issue #22915: SAX parser now supports files opened with file descriptor or + bytes path. + +- Issue #22609: Constructors and update methods of mapping classes in the + collections module now accept the self keyword argument. + +- Issue #22788: Add *context* parameter to logging.handlers.HTTPHandler. + +- Issue #22921: Allow SSLContext to take the *hostname* parameter even if + OpenSSL doesn't support SNI. + +- Issue #22894: TestCase.subTest() would cause the test suite to be stopped + when in failfast mode, even in the absence of failures. + +- Issue #22638: SSLv3 is now disabled throughout the standard library. + It can still be enabled by instantiating a SSLContext manually. + +- Issue #22370: Windows detection in pathlib is now more robust. + +- Issue #22841: Reject coroutines in asyncio add_signal_handler(). + Patch by Ludovic.Gasc. + +- Issue #22849: Fix possible double free in the io.TextIOWrapper constructor. + +- Issue #12728: Different Unicode characters having the same uppercase but + different lowercase are now matched in case-insensitive regular expressions. + +- Issue #22821: Fixed fcntl() with integer argument on 64-bit big-endian + platforms. + +- Issue #22406: Fixed the uu_codec codec incorrectly ported to 3.x. + Based on patch by Martin Panter. + +- Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat. + Based on patch by Aivars Kalvāns. + +- Issue #22769: Fixed ttk.Treeview.tag_has() when called without arguments. + +- Issue #22417: Verify certificates by default in httplib (PEP 476). + +- Issue #22775: Fixed unpickling of http.cookies.SimpleCookie with protocol 2 + and above. Patch by Tim Graham. + +- Issue #22366: urllib.request.urlopen will accept a context object + (SSLContext) as an argument which will then used be for HTTPS connection. + Patch by Alex Gaynor. + +- Issue #22776: Brought excluded code into the scope of a try block in + SysLogHandler.emit(). + +- Issue #22665: Add missing get_terminal_size and SameFileError to + shutil.__all__. + +- Issue #17381: Fixed handling of case-insensitive ranges in regular + expressions. + +- Issue #22410: Module level functions in the re module now cache compiled + locale-dependent regular expressions taking into account the locale. + +- Issue #22759: Query methods on pathlib.Path() (exists(), is_dir(), etc.) + now return False when the underlying stat call raises NotADirectoryError. + +- Issue #8876: distutils now falls back to copying files when hard linking + doesn't work. This allows use with special filesystems such as VirtualBox + shared folders. + +- Issue #18853: Fixed ResourceWarning in shlex.__nain__. + +- Issue #9351: Defaults set with set_defaults on an argparse subparser + are no longer ignored when also set on the parent parser. + +- Issue #21991: Make email.headerregistry's header 'params' attributes + be read-only (MappingProxyType). Previously the dictionary was modifiable + but a new one was created on each access of the attribute. + +- Issue #22641: In asyncio, the default SSL context for client connections + is now created using ssl.create_default_context(), for stronger security. + +- Issue #22435: Fix a file descriptor leak when SocketServer bind fails. + +- Issue #13096: Fixed segfault in CTypes POINTER handling of large + values. + +- Issue #11694: Raise ConversionError in xdrlib as documented. Patch + by Filip Gruszczyński and Claudiu Popa. + +- Issue #22462: Fix pyexpat's creation of a dummy frame to make it + appear in exception tracebacks. + +- Issue #21173: Fix len() on a WeakKeyDictionary when .clear() was called + with an iterator alive. + +- Issue #11866: Eliminated race condition in the computation of names + for new threads. + +- Issue #21905: Avoid RuntimeError in pickle.whichmodule() when sys.modules + is mutated while iterating. Patch by Olivier Grisel. + +- Issue #22219: The zipfile module CLI now adds entries for directories + (including empty directories) in ZIP file. + +- Issue #22449: In the ssl.SSLContext.load_default_certs, consult the + environmental variables SSL_CERT_DIR and SSL_CERT_FILE on Windows. + +- Issue #20076: Added non derived UTF-8 aliases to locale aliases table. + +- Issue #20079: Added locales supported in glibc 2.18 to locale alias table. + +- Issue #22396: On 32-bit AIX platform, don't expose os.posix_fadvise() nor + os.posix_fallocate() because their prototypes in system headers are wrong. + +- Issue #22517: When a io.BufferedRWPair object is deallocated, clear its + weakrefs. + +- Issue #22448: Improve canceled timer handles cleanup to prevent + unbound memory usage. Patch by Joshua Moore-Oliva. + +- Issue #23009: Make sure selectors.EpollSelecrtor.select() works when no + FD is registered. + +IDLE +---- + +- Issue #20577: Configuration of the max line length for the FormatParagraph + extension has been moved from the General tab of the Idle preferences dialog + to the FormatParagraph tab of the Config Extensions dialog. + Patch by Tal Einat. + +- Issue #16893: Update Idle doc chapter to match current Idle and add new + information. + +- Issue #3068: Add Idle extension configuration dialog to Options menu. + Changes are written to HOME/.idlerc/config-extensions.cfg. + Original patch by Tal Einat. + +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires an + editor window with a filename. When Class Browser is requested otherwise, + from a shell, output window, or 'Untitled' editor, Idle no longer displays + an error box. It now pops up an Open Module box (Alt+M). If a valid name + is entered and a module is opened, a corresponding browser is also opened. + +- Issue #4832: Save As to type Python files automatically adds .py to the + name you enter (even if your system does not display it). Some systems + automatically add .txt when type is Text files. + +- Issue #21986: Code objects are not normally pickled by the pickle module. + To match this, they are no longer pickled when running under Idle. + +- Issue #23180: Rename IDLE "Windows" menu item to "Window". + Patch by Al Sweigart. + +Tests +----- + +- Issue #23392: Added tests for marshal C API that works with FILE*. + +- Issue #18982: Add tests for CLI of the calendar module. + +- Issue #19548: Added some additional checks to test_codecs to ensure that + statements in the updated documentation remain accurate. Patch by Martin + Panter. + +- Issue #22838: All test_re tests now work with unittest test discovery. + +- Issue #22173: Update lib2to3 tests to use unittest test discovery. + +- Issue #16000: Convert test_curses to use unittest. + +- Issue #21456: Skip two tests in test_urllib2net.py if _ssl module not + present. Patch by Remi Pointel. + +- Issue #22770: Prevent some Tk segfaults on OS X when running gui tests. + +- Issue #23211: Workaround test_logging failure on some OS X 10.6 systems. + +- Issue #23345: Prevent test_ssl failures with large OpenSSL patch level + values (like 0.9.8zc). + +- Issue #22289: Prevent test_urllib2net failures due to ftp connection timeout. + +Build +----- + +- Issue #15506: Use standard PKG_PROG_PKG_CONFIG autoconf macro in the configure + script. + +- Issue #22935: Allow the ssl module to be compiled if openssl doesn't support + SSL 3. + +- Issue #16537: Check whether self.extensions is empty in setup.py. Patch by + Jonathan Hosmer. + +- Issue #18096: Fix library order returned by python-config. + +- Issue #17219: Add library build dir for Python extension cross-builds. + +- Issue #17128: Use private version of OpenSSL for 3.4.3 OS X 10.5+ installer. + +C API +----- + +- Issue #22079: PyType_Ready() now checks that statically allocated type has + no dynamically allocated bases. + +Documentation +------------- + +- Issue #19548: Update the codecs module documentation to better cover the + distinction between text encodings and other codecs, together with other + clarifications. Patch by Martin Panter. + +- Issue #22914: Update the Python 2/3 porting HOWTO to describe a more automated + approach. + +- Issue #21514: The documentation of the json module now refers to new JSON RFC + 7159 instead of obsoleted RFC 4627. + +Tools/Demos +----------- + +- Issue #22314: pydoc now works when the LINES environment variable is set. + +Windows +------- + +- Issue #17896: The Windows build scripts now expect external library sources + to be in ``PCbuild\..\externals`` rather than ``PCbuild\..\..``. + +- Issue #17717: The Windows build scripts now use a copy of NASM pulled from + svn.python.org to build OpenSSL. + +- Issue #22644: The bundled version of OpenSSL has been updated to 1.0.1j. + + +What's New in Python 3.4.2? +=========================== + +Release date: 2014-10-06 + +Library +------- + +- Issue #10510: distutils register and upload methods now use HTML standards + compliant CRLF line endings. + +- Issue #9850: Fixed macpath.join() for empty first component. Patch by + Oleg Oshmyan. + +- Issue #22427: TemporaryDirectory no longer attempts to clean up twice when + used in the with statement in generator. + +- Issue #20912: Now directories added to ZIP file have correct Unix and MS-DOS + directory attributes. + +- Issue #21866: ZipFile.close() no longer writes ZIP64 central directory + records if allowZip64 is false. + +- Issue #22415: Fixed debugging output of the GROUPREF_EXISTS opcode in the re + module. Removed trailing spaces in debugging output. + +- Issue #22423: Unhandled exception in thread no longer causes unhandled + AttributeError when sys.stderr is None. + +- Issue #21332: Ensure that ``bufsize=1`` in subprocess.Popen() selects + line buffering, rather than block buffering. Patch by Akira Li. + + +What's New in Python 3.4.2rc1? +============================== + +Release date: 2014-09-22 + +Core and Builtins +----------------- + +- Issue #22258: Fix the the internal function set_inheritable() on Illumos. + This platform exposes the function ``ioctl(FIOCLEX)``, but calling it fails + with errno is ENOTTY: "Inappropriate ioctl for device". set_inheritable() + now falls back to the slower ``fcntl()`` (``F_GETFD`` and then ``F_SETFD``). + +- Issue #21669: With the aid of heuristics in SyntaxError.__init__, the + parser now attempts to generate more meaningful (or at least more search + engine friendly) error messages when "exec" and "print" are used as + statements. + +- Issue #21642: In the conditional if-else expression, allow an integer written + with no space between itself and the ``else`` keyword (e.g. ``True if 42else + False``) to be valid syntax. + +- Issue #21523: Fix over-pessimistic computation of the stack effect of + some opcodes in the compiler. This also fixes a quadratic compilation + time issue noticeable when compiling code with a large number of "and" + and "or" operators. + +Library +------- + +- Issue #21091: Fix API bug: email.message.EmailMessage.is_attachment is now + a method. Since EmailMessage is provisional, we can change the API in a + maintenance release, but we use a trick to remain backward compatible with + 3.4.0/1. + +- Issue #21079: Fix email.message.EmailMessage.is_attachment to return the + correct result when the header has parameters as well as a value. + +- Issue #22247: Add NNTPError to nntplib.__all__. + +- Issue #4180: The warnings registries are now reset when the filters + are modified. + +- Issue #22419: Limit the length of incoming HTTP request in wsgiref server to + 65536 bytes and send a 414 error code for higher lengths. Patch contributed + by Devin Cook. + +- Lax cookie parsing in http.cookies could be a security issue when combined + with non-standard cookie handling in some Web browsers. Reported by + Sergey Bobrov. + +- Issue #22384: An exception in Tkinter callback no longer crashes the program + when it is run with pythonw.exe. + +- Issue #22168: Prevent turtle AttributeError with non-default Canvas on OS X. + +- Issue #21147: sqlite3 now raises an exception if the request contains a null + character instead of truncate it. Based on patch by Victor Stinner. + +- Issue #21951: Fixed a crash in Tkinter on AIX when called Tcl command with + empty string or tuple argument. + +- Issue #21951: Tkinter now most likely raises MemoryError instead of crash + if the memory allocation fails. + +- Issue #22338: Fix a crash in the json module on memory allocation failure. + +- Issue #22226: First letter no longer is stripped from the "status" key in + the result of Treeview.heading(). + +- Issue #19524: Fixed resource leak in the HTTP connection when an invalid + response is received. Patch by Martin Panter. + +- Issue #22051: turtledemo no longer reloads examples to re-run them. + Initialization of variables and gui setup should be done in main(), + which is called each time a demo is run, but not on import. + +- Issue #21933: Turtledemo users can change the code font size with a menu + selection or control(command) '-' or '+' or control-mousewheel. + Original patch by Lita Cho. + +- Issue #21597: The separator between the turtledemo text pane and the drawing + canvas can now be grabbed and dragged with a mouse. The code text pane can + be widened to easily view or copy the full width of the text. The canvas + can be widened on small screens. Original patches by Jan Kanis and Lita Cho. + +- Issue #18132: Turtledemo buttons no longer disappear when the window is + shrunk. Original patches by Jan Kanis and Lita Cho. + +- Issue #22216: smtplib now resets its state more completely after a quit. The + most obvious consequence of the previous behavior was a STARTTLS failure + during a connect/starttls/quit/connect/starttls sequence. + +- Issue #22185: Fix an occasional RuntimeError in threading.Condition.wait() + caused by mutation of the waiters queue without holding the lock. Patch + by Doug Zongker. + +- Issue #22182: Use e.args to unpack exceptions correctly in + distutils.file_util.move_file. Patch by Claudiu Popa. + +- The webbrowser module now uses subprocess's start_new_session=True rather + than a potentially risky preexec_fn=os.setsid call. + +- Issue #22236: Fixed Tkinter images copying operations in NoDefaultRoot mode. + +- Issue #22191: Fix warnings.__all__. + +- Issue #15696: Add a __sizeof__ implementation for mmap objects on Windows. + +- Issue #22068: Avoided reference loops with Variables and Fonts in Tkinter. + +- Issue #22165: SimpleHTTPRequestHandler now supports undecodable file names. + +- Issue #8797: Raise HTTPError on failed Basic Authentication immediately. + Initial patch by Sam Bull. + +- Issue #20729: Restored the use of lazy iterkeys()/itervalues()/iteritems() + in the mailbox module. + +- Issue #21448: Changed FeedParser feed() to avoid O(N**2) behavior when + parsing long line. Original patch by Raymond Hettinger. + +- Issue #22184: The functools LRU Cache decorator factory now gives an earlier + and clearer error message when the user forgets the required parameters. + +- Issue #17923: glob() patterns ending with a slash no longer match non-dirs on + AIX. Based on patch by Delhallt. + +- Issue #21121: Don't force 3rd party C extensions to be built with + -Werror=declaration-after-statement. + +- Issue #21975: Fixed crash when using uninitialized sqlite3.Row (in particular + when unpickling pickled sqlite3.Row). sqlite3.Row is now initialized in the + __new__() method. + +- Issue #21580: Now Tkinter correctly handles bytes arguments passed to Tk. + In particular this allows to initialize images from binary data. + +- Issue #17172: Make turtledemo start as active on OS X even when run with + subprocess. Patch by Lita Cho. + +- Issue #21704: Fix build error for _multiprocessing when semaphores + are not available. Patch by Arfrever Frehtes Taifersar Arahesis. + +- Fix repr(_socket.socket) on Windows 64-bit: don't fail with OverflowError + on closed socket. repr(socket.socket) already works fine. + +- Issue #16133: The asynchat.async_chat.handle_read() method now ignores + BlockingIOError exceptions. + +- Issue #22044: Fixed premature DECREF in call_tzinfo_method. + Patch by Tom Flanagan. + +- Issue #19884: readline: Disable the meta modifier key if stdout is not + a terminal to not write the ANSI sequence "\033[1034h" into stdout. This + sequence is used on some terminal (ex: TERM=xterm-256color") to enable + support of 8 bit characters. + +- Issue #21888: plistlib's load() and loads() now work if the fmt parameter is + specified. + +- Issue #21044: tarfile.open() now handles fileobj with an integer 'name' + attribute. Based on patch by Antoine Pietri. + +- Issue #21867: Prevent turtle crash due to invalid undo buffer size. + +- Issue #19076: Don't pass the redundant 'file' argument to self.error(). + +- Issue #21942: Fixed source file viewing in pydoc's server mode on Windows. + +- Issue #11259: asynchat.async_chat().set_terminator() now raises a ValueError + if the number of received bytes is negative. + +- Issue #12523: asynchat.async_chat.push() now raises a TypeError if it doesn't + get a bytes string + +- Issue #21707: Add missing kwonlyargcount argument to + ModuleFinder.replace_paths_in_code(). + +- Issue #20639: calling Path.with_suffix('') allows removing the suffix + again. Patch by July Tikhonov. + +- Issue #21714: Disallow the construction of invalid paths using + Path.with_name(). Original patch by Antony Lee. + +- Issue #21897: Fix a crash with the f_locals attribute with closure + variables when frame.clear() has been called. + +- Issue #21151: Fixed a segfault in the winreg module when ``None`` is passed + as a ``REG_BINARY`` value to SetValueEx. Patch by John Ehresman. + +- Issue #21090: io.FileIO.readall() does not ignore I/O errors anymore. Before, + it ignored I/O errors if at least the first C call read() succeed. + +- Issue #21781: ssl.RAND_add() now supports strings longer than 2 GB. + +- Issue #11453: asyncore: emit a ResourceWarning when an unclosed file_wrapper + object is destroyed. The destructor now closes the file if needed. The + close() method can now be called twice: the second call does nothing. + +- Issue #21858: Better handling of Python exceptions in the sqlite3 module. + +- Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is + discarded after parsing, so the input file isn't unexpectedly closed. + +- Issue #21729: Used the "with" statement in the dbm.dumb module to ensure + files closing. Patch by Claudiu Popa. + +- Issue #21491: socketserver: Fix a race condition in child processes reaping. + +- Issue #21832: Require named tuple inputs to be exact strings. + +- Issue #19145: The times argument for itertools.repeat now handles + negative values the same way for keyword arguments as it does for + positional arguments. + +- Issue #21812: turtle.shapetransform did not tranform the turtle on the + first call. (Issue identified and fixed by Lita Cho.) + +- Issue #21635: The difflib SequenceMatcher.get_matching_blocks() method + cache didn't match the actual result. The former was a list of tuples + and the latter was a list of named tuples. + +- Issue #21722: The distutils "upload" command now exits with a non-zero + return code when uploading fails. Patch by Martin Dengler. + +- Issue #21723: asyncio.Queue: support any type of number (ex: float) for the + maximum size. Patch written by Vajrasky Kok. + +- Issue #21326: Add a new is_closed() method to asyncio.BaseEventLoop. + run_forever() and run_until_complete() methods of asyncio.BaseEventLoop now + raise an exception if the event loop was closed. + +- Issue #21774: Fixed NameError for an incorrect variable reference in the + XML Minidom code for creating processing instructions. + (Found and fixed by Claudiu Popa.) + +- Issue #21766: Prevent a security hole in CGIHTTPServer by URL unquoting paths + before checking for a CGI script at that path. + +- Issue #21310: Fixed possible resource leak in failed open(). + +- Issue #21677: Fixed chaining nonnormalized exceptions in io close() methods. + +- Issue #11709: Fix the pydoc.help function to not fail when sys.stdin is not a + valid file. + +- Issue #13223: Fix pydoc.writedoc so that the HTML documentation for methods + that use 'self' in the example code is generated correctly. + +- Issue #21463: In urllib.request, fix pruning of the FTP cache. + +- Issue #21618: The subprocess module could fail to close open fds that were + inherited by the calling process and already higher than POSIX resource + limits would otherwise allow. On systems with a functioning /proc/self/fd + or /dev/fd interface the max is now ignored and all fds are closed. + +- Issue #21552: Fixed possible integer overflow of too long string lengths in + the tkinter module on 64-bit platforms. + +- Issue #14315: The zipfile module now ignores extra fields in the central + directory that are too short to be parsed instead of letting a struct.unpack + error bubble up as this "bad data" appears in many real world zip files in + the wild and is ignored by other zip tools. + +- Issue #21402: tkinter.ttk now works when default root window is not set. + +- Issue #10203: sqlite3.Row now truly supports sequence protocol. In particular + it supports reverse() and negative indices. Original patch by Claudiu Popa. + +- Issue #18807: If copying (no symlinks) specified for a venv, then the python + interpreter aliases (python, python3) are now created by copying rather than + symlinking. + +- Issue #14710: pkgutil.get_loader() no longer raises an exception when None is + found in sys.modules. + +- Issue #14710: pkgutil.find_loader() no longer raises an exception when a + module doesn't exist. + +- Issue #21481: Argparse equality and inequality tests now return + NotImplemented when comparing to an unknown type. + +- Issue #8743: Fix interoperability between set objects and the + collections.Set() abstract base class. + +- Issue #13355: random.triangular() no longer fails with a ZeroDivisionError + when low equals high. + +- Issue #21538: The plistlib module now supports loading of binary plist files + when reference or offset size is not a power of two. + +- Issue #21801: Validate that __signature__ is None or an instance of Signature. + +- Issue #21923: Prevent AttributeError in distutils.sysconfig.customize_compiler + due to possible uninitialized _config_vars. + +- Issue #21323: Fix http.server to again handle scripts in CGI subdirectories, + broken by the fix for security issue #19435. Patch by Zach Byrne. + +Extension Modules +----------------- + +- Issue #22176: Update the ctypes module's libffi to v3.1. This release + adds support for the Linux AArch64 and POWERPC ELF ABIv2 little endian + architectures. + +Build +----- + +- Issue #15661: python.org OS X installers are now distributed as signed + installer packages compatible with the Gatekeeper security feature. + +- Issue #21958: Define HAVE_ROUND when building with Visual Studio 2013 and + above. Patch by Zachary Turner. + +- Issue #15759: "make suspicious", "make linkcheck" and "make doctest" in Doc/ + now display special message when and only when there are failures. + +- Issue #17095: Fix Modules/Setup *shared* support. + +- Issue #21811: Anticipated fixes to support OS X versions > 10.9. + +- Issue #21166: Prevent possible segfaults and other random failures of + python --generate-posix-vars in pybuilddir.txt build target. + +IDLE +---- + +- Issue #17390: Adjust Editor window title; remove 'Python', + move version to end. + +- Issue #14105: Idle debugger breakpoints no longer disappear + when inseting 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. + Patch by Ramchandra Apt and Lita Cho. + +- Issue #21765: Add support for non-ascii identifiers to HyperParser. + +- Issue #21940: Add unittest for WidgetRedirector. Initial patch by Saimadhav + Heblikar. + +- Issue #18592: Add unittest for SearchDialogBase. Patch by Phil Webster. + +- Issue #21694: Add unittest for ParenMatch. Patch by Saimadhav Heblikar. + +- Issue #21686: add unittest for HyperParser. Original patch by Saimadhav + Heblikar. + +- Issue #12387: Add missing upper(lower)case versions of default Windows key + bindings for Idle so Caps Lock does not disable them. Patch by Roger Serwy. + +- Issue #21695: Closing a Find-in-files output window while the search is + still in progress no longer closes Idle. + +- Issue #18910: Add unittest for textView. Patch by Phil Webster. + +- Issue #18292: Add unittest for AutoExpand. Patch by Saihadhav Heblikar. + +- Issue #18409: Add unittest for AutoComplete. Patch by Phil Webster. + +Tests +----- + +- Issue #22166: With the assistance of a new internal _codecs._forget_codec + helping function, test_codecs now clears the encoding caches to avoid the + appearance of a reference leak + +- Issue #22236: Tkinter tests now don't reuse default root window. New root + window is created for every test class. + +- Issue #20746: Fix test_pdb to run in refleak mode (-R). Patch by Xavier + de Gaye. + +- Issue #22060: test_ctypes has been somewhat cleaned up and simplified; it + now uses unittest test discovery to find its tests. + +- Issue #22104: regrtest.py no longer holds a reference to the suite of tests + loaded from test modules that don't define test_main(). + +- Issue #22002: Added ``load_package_tests`` function to test.support and used + it to implement/augment test discovery in test_asyncio, test_email, + test_importlib, test_json, and test_tools. + +- Issue #21976: Fix test_ssl to accept LibreSSL version strings. Thanks + to William Orr. + +- Issue #21918: Converted test_tools from a module to a package containing + separate test files for each tested script. + +- Issue #20155: Changed HTTP method names in failing tests in test_httpservers + so that packet filtering software (specifically Windows Base Filtering Engine) + does not interfere with the transaction semantics expected by the tests. + +- Issue #19493: Refactored the ctypes test package to skip tests explicitly + rather than silently. + +- Issue #18492: All resources are now allowed when tests are not run by + regrtest.py. + +- Issue #21634: Fix pystone micro-benchmark: use floor division instead of true + division to benchmark integers instead of floating point numbers. Set pystone + version to 1.2. Patch written by Lennart Regebro. + +- Issue #21605: Added tests for Tkinter images. + +- Issue #21493: Added test for ntpath.expanduser(). Original patch by + Claudiu Popa. + +- Issue #19925: Added tests for the spwd module. Original patch by Vajrasky Kok. + +- Issue #21522: Added Tkinter tests for Listbox.itemconfigure(), + PanedWindow.paneconfigure(), and Menu.entryconfigure(). + +Documentation +------------- + +- Issue #21777: The binary sequence methods on bytes and bytearray are now + documented explicitly, rather than assuming users will be able to derive + the expected behaviour from the behaviour of the corresponding str methods. + +Windows +------- + +- Issue #21671, #22160, CVE-2014-0224: The bundled version of OpenSSL has been + updated to 1.0.1i. + +- Issue #10747: Use versioned labels in the Windows start menu. + Patch by Olive Kilburn. + +Tools/Demos +----------- + +- Issue #22201: Command-line interface of the zipfile module now correctly + extracts ZIP files with directory entries. Patch by Ryan Wilson. + +- Issue #21906: Make Tools/scripts/md5sum.py work in Python 3. + Patch by Zachary Ware. + +- Issue #21629: Fix Argument Clinic's "--converters" feature. + + +What's New in Python 3.4.1? +=========================== + +Release date: 2014-05-18 + +Core and Builtins +----------------- + +- Issue #21418: Fix a crash in the builtin function super() when called without + argument and without current frame (ex: embedded Python). + +- Issue #21425: Fix flushing of standard streams in the interactive + interpreter. + +- Issue #21435: In rare cases, when running finalizers on objects in cyclic + trash a bad pointer dereference could occur due to a subtle flaw in + internal iteration logic. + +Library +------- + +- Issue #10744: Fix PEP 3118 format strings on ctypes objects with a nontrivial + shape. + +- Issue #20998: Fixed re.fullmatch() of repeated single character pattern + with ignore case. Original patch by Matthew Barnett. + +- Issue #21075: fileinput.FileInput now reads bytes from standard stream if + binary mode is specified. Patch by Sam Kimbrel. + +- Issue #21396: Fix TextIOWrapper(..., write_through=True) to not force a + flush() on the underlying binary stream. Patch by akira. + +- Issue #21470: Do a better job seeding the random number generator by + using enough bytes to span the full state space of the Mersenne Twister. + +- Issue #21398: Fix an unicode error in the pydoc pager when the documentation + contains characters not encodable to the stdout encoding. + +Tests +----- + +- Issue #17756: Fix test_code test when run from the installed location. + +- Issue #17752: Fix distutils tests when run from the installed location. + +IDLE +---- + +- Issue #18104: Add idlelib/idle_test/htest.py with a few sample tests to begin + consolidating and improving human-validated tests of Idle. Change other files + as needed to work with htest. Running the module as __main__ runs all tests. + + +What's New in Python 3.4.1rc1? +============================== + +Release date: 2014-05-05 + +Core and Builtins +----------------- + +- Issue #21274: Define PATH_MAX for GNU/Hurd in Python/pythonrun.c. + +- Issue #21209: Fix sending tuples to custom generator objects with the yield + from syntax. + +- Issue #21134: Fix segfault when str is called on an uninitialized + UnicodeEncodeError, UnicodeDecodeError, or UnicodeTranslateError object. + +- Issue #19537: Fix PyUnicode_DATA() alignment under m68k. Patch by + Andreas Schwab. + +- Issue #20929: Add a type cast to avoid shifting a negative number. + +- Issue #20731: Properly position in source code files even if they + are opened in text mode. Patch by Serhiy Storchaka. + +- Issue #20637: Key-sharing now also works for instance dictionaries of + subclasses. Patch by Peter Ingebretson. + +- Issue #12546: Allow ``\x00`` to be used as a fill character when using str, int, + float, and complex __format__ methods. + +- Issue #13598: Modify string.Formatter to support auto-numbering of + replacement fields. It now matches the behavior of str.format() in + this regard. Patches by Phil Elson and Ramchandra Apte. + +Library +------- + +- Issue #21088: Bugfix for curses.window.addch() regression in 3.4.0. + In porting to Argument Clinic, the first two arguments were reversed. + +- Issue #21469: Reduced the risk of false positives in robotparser by + checking to make sure that robots.txt has been read or does not exist + prior to returning True in can_fetch(). + +- Issue #21321: itertools.islice() now releases the reference to the source + iterator when the slice is exhausted. Patch by Anton Afanasyev. + +- Issue #9815: assertRaises now tries to clear references to local variables + in the exception's traceback. + +- Issue #13204: Calling sys.flags.__new__ would crash the interpreter, + now it raises a TypeError. + +- Issue #19385: Make operations on a closed dbm.dumb database always raise the + same exception. + +- Issue #21207: Detect when the os.urandom cached fd has been closed or + replaced, and open it anew. + +- Issue #21291: subprocess's Popen.wait() is now thread safe so that + multiple threads may be calling wait() or poll() on a Popen instance + at the same time without losing the Popen.returncode value. + +- Issue #21127: Path objects can now be instantiated from str subclass + instances (such as ``numpy.str_``). + +- Issue #15002: urllib.response object to use _TemporaryFileWrapper (and + _TemporaryFileCloser) facility. Provides a better way to handle file + descriptor close. Patch contributed by Christian Theune. + +- Issue #12220: mindom now raises a custom ValueError indicating it doesn't + support spaces in URIs instead of letting a 'split' ValueError bubble up. + +- Issue #21239: patch.stopall() didn't work deterministically when the same + name was patched more than once. + +- Issue #21222: Passing name keyword argument to mock.create_autospec now + works. + +- Issue #21197: Add lib64 -> lib symlink in venvs on 64-bit non-OS X POSIX. + +- Issue #17498: Some SMTP servers disconnect after certain errors, violating + strict RFC conformance. Instead of losing the error code when we issue the + subsequent RSET, smtplib now returns the error code and defers raising the + SMTPServerDisconnected error until the next command is issued. + +- Issue #17826: setting an iterable side_effect on a mock function created by + create_autospec now works. Patch by Kushal Das. + +- Issue #7776: Fix ``Host:`` header and reconnection when using + http.client.HTTPConnection.set_tunnel(). Patch by Nikolaus Rath. + +- Issue #20968: unittest.mock.MagicMock now supports division. + Patch by Johannes Baiter. + +- 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 + replace error handler. + +- Issue #21171: Fixed undocumented filter API of the rot13 codec. + Patch by Berker Peksag. + +- Issue #21172: isinstance check relaxed from dict to collections.Mapping. + +- Issue #21155: asyncio.EventLoop.create_unix_server() now raises a ValueError + if path and sock are specified at the same time. + +- Issue #21149: Improved thread-safety in logging cleanup during interpreter + shutdown. Thanks to Devin Jeanpierre for the patch. + +- Issue #20145: `assertRaisesRegex` and `assertWarnsRegex` now raise a + TypeError if the second argument is not a string or compiled regex. + +- Issue #21058: Fix a leak of file descriptor in + :func:`tempfile.NamedTemporaryFile`, close the file descriptor if + :func:`io.open` fails + +- Issue #21200: Return None from pkgutil.get_loader() when __spec__ is missing. + +- Issue #21013: Enhance ssl.create_default_context() when used for server side + sockets to provide better security by default. + +- Issue #20633: Replace relative import by absolute import. + +- Issue #20980: Stop wrapping exception when using ThreadPool. + +- Issue #21082: In os.makedirs, do not set the process-wide umask. Note this + changes behavior of makedirs when exist_ok=True. + +- Issue #20990: Fix issues found by pyflakes for multiprocessing. + +- Issue #21015: SSL contexts will now automatically select an elliptic + curve for ECDH key exchange on OpenSSL 1.0.2 and later, and otherwise + default to "prime256v1". + +- Issue #20995: Enhance default ciphers used by the ssl module to enable + better security an prioritize perfect forward secrecy. + +- Issue #20884: Don't assume that __file__ is defined on importlib.__init__. + +- Issue #21499: Ignore __builtins__ in several test_importlib.test_api tests. + +- Issue #20879: Delay the initialization of encoding and decoding tables for + base32, ascii85 and base85 codecs in the base64 module, and delay the + initialization of the unquote_to_bytes() table of the urllib.parse module, to + not waste memory if these modules are not used. + +- Issue #19157: Include the broadcast address in the usuable hosts for IPv6 + in ipaddress. + +- Issue #11599: When an external command (e.g. compiler) fails, distutils now + prints out the whole command line (instead of just the command name) if the + environment variable DISTUTILS_DEBUG is set. + +- Issue #4931: distutils should not produce unhelpful "error: None" messages + anymore. distutils.util.grok_environment_error is kept but doc-deprecated. + +- Issue #20875: Prevent possible gzip "'read' is not defined" NameError. + Patch by Claudiu Popa. + +- Issue #11558: ``email.message.Message.attach`` now returns a more + useful error message if ``attach`` is called on a message for which + ``is_multipart`` is False. + +- Issue #20283: RE pattern methods now accept the string keyword parameters + as documented. The pattern and source keyword parameters are left as + deprecated aliases. + +- Issue #20778: Fix modulefinder to work with bytecode-only modules. + +- Issue #20791: copy.copy() now doesn't make a copy when the input is + a bytes object. Initial patch by Peter Otten. + +- Issue #19748: On AIX, time.mktime() now raises an OverflowError for year + outsize range [1902; 2037]. + +- Issue #20816: Fix inspect.getcallargs() to raise correct TypeError for + missing keyword-only arguments. Patch by Jeremiah Lowin. + +- Issue #20817: Fix inspect.getcallargs() to fail correctly if more + than 3 arguments are missing. Patch by Jeremiah Lowin. + +- Issue #6676: Ensure a meaningful exception is raised when attempting + to parse more than one XML document per pyexpat xmlparser instance. + (Original patches by Hirokazu Yamamoto and Amaury Forgeot d'Arc, with + suggested wording by David Gutteridge) + +- Issue #21117: Fix inspect.signature to better support functools.partial. + Due to the specifics of functools.partial implementation, + positional-or-keyword arguments passed as keyword arguments become + keyword-only. + +- Issue #21209: Fix asyncio.tasks.CoroWrapper to workaround a bug + in yield-from implementation in CPythons prior to 3.4.1. + +- asyncio: Add gi_{frame,running,code} properties to CoroWrapper + (upstream issue #163). + +- Issue #21311: Avoid exception in _osx_support with non-standard compiler + configurations. Patch by John Szakmeister. + +- Issue #11571: Ensure that the turtle window becomes the topmost window + when launched on OS X. + +Extension Modules +----------------- + +- Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd. + +- Issue #21226: Set up modules properly in PyImport_ExecCodeModuleObject + (and friends). + +IDLE +---- + +- Issue #21139: Change default paragraph width to 72, the PEP 8 recommendation. + +- Issue #21284: Paragraph reformat test passes after user changes reformat width. + +- Issue #17654: Ensure IDLE menus are customized properly on OS X for + non-framework builds and for all variants of Tk. + +Build +----- + +- The Windows build now includes OpenSSL 1.0.1g + +- Issue #21285: Refactor and fix curses configure check to always search + in a ncursesw directory. + +- Issue #15234: For BerkelyDB and Sqlite, only add the found library and + include directories if they aren't already being searched. This avoids + an explicit runtime library dependency. + +- Issue #20644: OS X installer build support for documentation build changes + in 3.4.1: assume externally supplied sphinx-build is available in /usr/bin. + +C API +----- + +- Issue #20942: PyImport_ImportFrozenModuleObject() no longer sets __file__ to + match what importlib does; this affects _frozen_importlib as well as any + module loaded using imp.init_frozen(). + +Documentation +------------- + +- Issue #17386: Expanded functionality of the ``Doc/make.bat`` script to make + it much more comparable to ``Doc/Makefile``. + +- Issue #21043: Remove the recommendation for specific CA organizations and to + mention the ability to load the OS certificates. + +- Issue #20765: Add missing documentation for PurePath.with_name() and + PurePath.with_suffix(). + +- Issue #19407: New package installation and distribution guides based on + the Python Packaging Authority tools. Existing guides have been retained + as legacy links from the distutils docs, as they still contain some + required reference material for tool developers that isn't recorded + anywhere else. + +- Issue #19697: Document cases where __main__.__spec__ is None. + +Tests +----- + +- Issue #18604: Consolidated checks for GUI availability. All platforms now + at least check whether Tk can be instantiated when the GUI resource is + requested. + +- Issue #21275: Fix a socket test on KFreeBSD. + +- Issue #21223: Pass test_site/test_startup_imports when some of the extensions + are built as builtins. + +- Issue #20635: Added tests for Tk geometry managers. + +- Add test case for freeze. + +- Issue #20743: Fix a reference leak in test_tcl. + +- Issue #21097: Move test_namespace_pkgs into test_importlib. + +- Issue #20939: Avoid various network test failures due to new + redirect of http://www.python.org/ to https://www.python.org: + use http://www.example.com instead. + +- Issue #20668: asyncio tests no longer rely on tests.txt file. + (Patch by Vajrasky Kok) + +- Issue #21093: Prevent failures of ctypes test_macholib on OS X if a + copy of libz exists in $HOME/lib or /usr/local/lib. + +Tools/Demos +----------- + +- Add support for ``yield from`` to 2to3. + +- Add support for the PEP 465 matrix multiplication operator to 2to3. + +- Issue #16047: Fix module exception list and __file__ handling in freeze. + Patch by Meador Inge. + +- Issue #11824: Consider ABI tags in freeze. Patch by Meador Inge. + +- Issue #20535: PYTHONWARNING no longer affects the run_tests.py script. + Patch by Arfrever Frehtes Taifersar Arahesis. + What's New in Python 3.4.0? =========================== @@ -154,7 +2339,7 @@ Core and Builtins - Issue #20588: Make Python-ast.c C89 compliant. -- Issue #20437: Fixed 22 potential bugs when deleting object references. +- Issue #20437: Fixed 22 potential bugs when deleting objects references. - Issue #20500: Displaying an exception at interpreter shutdown no longer risks triggering an assertion failure in PyObject_Str. @@ -1059,8 +3244,8 @@ Core and Builtins when the creation of the replacement exception won't lose any information. - Issue #19466: Clear the frames of daemon threads earlier during the - Python shutdown to call object destructors. So "unclosed file" resource - warnings are now correctly emitted for daemon threads. + Python shutdown to call objects destructors. So "unclosed file" resource + warnings are now corretly emitted for daemon threads. - Issue #19514: Deduplicate some _Py_IDENTIFIER declarations. Patch by Andrei Dorian Duma. @@ -1077,9 +3262,6 @@ Core and Builtins - Issue #19369: Optimized the usage of __length_hint__(). -- Issue #28026: Raise ImportError when exec_module() exists but - create_module() is missing. - - Issue #18603: Ensure that PyOS_mystricmp and PyOS_mystrnicmp are in the Python executable and not removed by the linker's optimizer. @@ -1204,8 +3386,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. - (Initial patch by Claudiu Popa) +- Issue #19282: dbm.open now supports the context management protocol. (Inital + patch by Claudiu Popa) - Issue #8311: Added support for writing any bytes-like objects in the aifc, sunau, and wave modules. @@ -1299,7 +3481,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 initialization code of +- Issue #19420: Fix reference leak in module initalization code of _hashopenssl.c - Issue #19329: Optimized compiling charsets in regular expressions. @@ -1967,9 +4149,6 @@ Library - Issue #16809: Tkinter's splitlist() and split() methods now accept Tcl_Obj argument. -- Issue #17211: Yield a namedtuple in pkgutil. - Patch by Ramchandra Apte. - - Issue #18324: set_payload now correctly handles binary input. This also supersedes the previous fixes for #14360, #1717, and #16564. @@ -1979,8 +4158,6 @@ Library - Issue #17119: Fixed integer overflows when processing large strings and tuples in the tkinter module. -- Issue #15352: Rebuild frozen modules when marshal.c is changed. - - Issue #18747: Re-seed OpenSSL's pseudo-random number generator after fork. A pthread_atfork() parent handler is used to seed the PRNG with pid, time and some stack data. @@ -1998,7 +4175,7 @@ Library - Issue #18709: Fix CVE-2013-4238. The SSL module now handles NULL bytes inside subjectAltName correctly. Formerly the module has used OpenSSL's - GENERAL_NAME_print() function to get the string representation of ASN.1 + GENERAL_NAME_print() function to get the string represention of ASN.1 strings for ``rfc822Name`` (email), ``dNSName`` (DNS) and ``uniformResourceIdentifier`` (URI). @@ -2091,7 +4268,7 @@ IDLE Documentation ------------- -- Issue #18743: Fix references to non-existent "StringIO" module. +- Issue #18743: Fix references to non-existant "StringIO" module. - Issue #18783: Removed existing mentions of Python long type in docstrings, error messages and comments. @@ -2188,9 +4365,6 @@ Core and Builtins - Issue #18137: Detect integer overflow on precision in float.__format__() and complex.__format__(). -- Issue #15767: Introduce ModuleNotFoundError which is raised when a module - could not be found. - - Issue #18183: Fix various unicode operations on strings with large unicode codepoints. @@ -2321,7 +4495,7 @@ Core and Builtins - Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.) in the interpreter. -- Issue #17137: When a Unicode string is resized, the internal wide character +- Issue #17137: When an 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 @@ -2658,7 +4832,7 @@ Library on Windows and adds no value over and above python -m pydoc ... - Issue #18155: The csv module now correctly handles csv files that use - a delimiter character that has a special meaning in regexes, instead of + a delimter character that has a special meaning in regexes, instead of throwing an exception. - Issue #14360: encode_quopri can now be successfully used as an encoder @@ -2848,7 +5022,7 @@ Library Thomas Barlow. - Issue #17358: Modules loaded by imp.load_source() and load_compiled() (and by - extension load_module()) now have a better chance of working when reloaded. + extention load_module()) now have a better chance of working when reloaded. - Issue #17804: New function ``struct.iter_unpack`` allows for streaming struct unpacking. @@ -2961,8 +5135,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 overridden with the CC environment variable, use the new compiler as - the default for linking if LDSHARED is not also overridden. This restores + is overriden with the CC environment variable, use the new compiler as + the default for linking if LDSHARED is not also overriden. 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 @@ -3033,7 +5207,7 @@ Library specifically addresses a stack misalignment issue on x86 and issues on some more recent platforms. -- Issue #8862: Fixed curses cleanup when getkey is interrupted by a signal. +- Issue #8862: Fixed curses cleanup when getkey is interrputed by a signal. - Issue #17443: imaplib.IMAP4_stream was using the default unbuffered IO in subprocess, but the imap code assumes buffered IO. In Python2 this @@ -3169,7 +5343,7 @@ Library symlinks on POSIX platforms. - Issue #13773: sqlite3.connect() gets a new `uri` parameter to pass the - filename as a URI, allowing custom options to be passed. + filename as a URI, allowing to pass custom options. - Issue #16564: Fixed regression relative to Python2 in the operation of email.encoders.encode_noop when used with binary data. @@ -3208,7 +5382,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 occurred when PyArg_ParseTuple +- Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple parses nested mutating sequence. - Issue #5289: Fix ctypes.util.find_library on Solaris. @@ -3430,7 +5604,7 @@ Library - Issue #7719: Make distutils ignore ``.nfs*`` files instead of choking later on. Initial patch by SilentGhost and Jeff Ramnani. -- Issue #13120: Allow calling pdb.set_trace() from thread. +- Issue #13120: Allow to call pdb.set_trace() from thread. Patch by Ilya Sandler. - Issue #16585: Make CJK encoders support error handlers that return bytes per @@ -3531,7 +5705,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 of the lists changes +- Issue #16230: Fix a crash in select.select() when one 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 @@ -3560,7 +5734,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 @@ -3591,7 +5765,7 @@ Library - Issue #16176: Properly identify Windows 8 via platform.platform() - Issue #16088: BaseHTTPRequestHandler's send_error method includes a - Content-Length header in its response now. Patch by Antoine Pitrou. + Content-Length header in it's 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 @@ -4111,10 +6285,6 @@ C-API PyImport_ExecCodeModuleWithPathnames() (and thus by extension PyImport_ExecCodeModule() and PyImport_ExecCodeModuleEx()). -- Issue #15767: Added PyErr_SetImportErrorSubclass(). - -- PyErr_SetImportError() now sets TypeError when its msg argument is set. - - Issue #9369: The types of `char*` arguments of PyObject_CallFunction() and PyObject_CallMethod() now changed to `const char*`. Based on patches by Jörg Müller and Lars Buitinck. @@ -4142,10 +6312,6 @@ C-API Documentation ------------- -- Issue #23006: Improve the documentation and indexing of dict.__missing__. - Add an entry in the language datamodel special methods section. - Revise and index its discussion in the stdtypes mapping/dict section. - - Issue #17701: Improving strftime documentation. - Issue #18440: Clarify that `hash()` can truncate the value returned from an @@ -6495,7 +8661,7 @@ Core and Builtins NULL). - Issue #10829: Refactor PyUnicode_FromFormat(), use the same function to parse - the format string in the 3 steps, fix crashs on invalid format strings. + the format string in the 3 steps, fix crashes on invalid format strings. - Issue #13007: whichdb should recognize gdbm 1.9 magic numbers. diff --git a/Misc/NEWS b/Misc/NEWS index 848add0..4807bd0 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,339 @@ Python News +++++++++++ +What's New in Python 3.6.1? +=========================== + +*Release date: 2017-03-21* + +Core and Builtins +----------------- + +- bpo-29723: The ``sys.path[0]`` initialization change for bpo-29139 caused a + regression by revealing an inconsistency in how sys.path is initialized when + executing ``__main__`` from a zipfile, directory, or other import location. + The interpreter now consistently avoids ever adding the import location's + parent directory to ``sys.path``, and ensures no other ``sys.path`` entries + are inadvertently modified when inserting the import location named on the + command line. + +Build +----- + +- bpo-27593: fix format of git information used in sys.version + +- Fix incompatible comment in python.h + + +What's New in Python 3.6.1 release candidate 1 +============================================== + +*Release date: 2017-03-04* + +Core and Builtins +----------------- + +- bpo-28893: Set correct __cause__ for errors about invalid awaitables + returned from __aiter__ and __anext__. + +- bpo-29683: Fixes to memory allocation in _PyCode_SetExtra. Patch by + Brian Coleman. + +- bpo-29684: Fix minor regression of PyEval_CallObjectWithKeywords. + It should raise TypeError when kwargs is not a dict. But it might + cause segv when args=NULL and kwargs is not a dict. + +- Issue #28598: Support __rmod__ for subclasses of str being called before + str.__mod__. Patch by Martijn Pieters. + +- bpo-29572: Update Windows build and OS X installers to use OpenSSL 1.0.2k. + +- bpo-29607: Fix stack_effect computation for CALL_FUNCTION_EX. + Patch by Matthieu Dartiailh. + +- bpo-29602: Fix incorrect handling of signed zeros in complex constructor for + complex subclasses and for inputs having a __complex__ method. Patch + by Serhiy Storchaka. + +- bpo-29347: Fixed possibly dereferencing undefined pointers + when creating weakref objects. + +- bpo-29438: Fixed use-after-free problem in key sharing dict. + +- Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0]. + +- Issue #29337: Fixed possible BytesWarning when compare the code objects. + Warnings could be emitted at compile time. + +- Issue #29327: Fixed a crash when pass the iterable keyword argument to + sorted(). + +- Issue #29034: Fix memory leak and use-after-free in os module (path_converter). + +- Issue #29159: Fix regression in bytes(x) when x.__index__() raises Exception. + +- Issue #28932: Do not include if it does not exist. + +- Issue #25677: Correct the positioning of the syntax error caret for + indented blocks. Based on patch by Michael Layzell. + +- Issue #29000: Fixed bytes formatting of octals with zero padding in alternate + form. + +- Issue #26919: On Android, operating system data is now always encoded/decoded + to/from UTF-8, instead of the locale encoding to avoid inconsistencies with + os.fsencode() and os.fsdecode() which are already using UTF-8. + +- Issue #28991: functools.lru_cache() was susceptible to an obscure reentrancy + bug triggerable by a monkey-patched len() function. + +- Issue #28739: f-string expressions are no longer accepted as docstrings and + by ast.literal_eval() even if they do not include expressions. + +- Issue #28512: Fixed setting the offset attribute of SyntaxError by + PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject(). + +- Issue #28918: Fix the cross compilation of xxlimited when Python has been + built with Py_DEBUG defined. + +- Issue #28731: Optimize _PyDict_NewPresized() to create correct size dict. + Improve speed of dict literal with constant keys up to 30%. + +Extension Modules +----------------- + +- Issue #29169: Update zlib to 1.2.11. + +Library +------- + +- bpo-29623: Allow use of path-like object as a single argument in + ConfigParser.read(). Patch by David Ellis. + +- bpo-28963: Fix out of bound iteration in asyncio.Future.remove_done_callback + implemented in C. + +- bpo-29704: asyncio.subprocess.SubprocessStreamProtocol no longer closes + before all pipes are closed. + +- bpo-29271: Fix Task.current_task and Task.all_tasks implemented in C + to accept None argument as their pure Python implementation. + +- bpo-29703: Fix asyncio to support instantiation of new event loops + in child processes. + +- bpo-29376: Fix assertion error in threading._DummyThread.is_alive(). + +- bpo-28624: Add a test that checks that cwd parameter of Popen() accepts + PathLike objects. Patch by Sayan Chowdhury. + +- bpo-28518: Start a transaction implicitly before a DML statement. + Patch by Aviv Palivoda. + +- bpo-29532: Altering a kwarg dictionary passed to functools.partial() + no longer affects a partial object after creation. + +- bpo-29110: Fix file object leak in aifc.open() when file is given as a + filesystem path and is not in valid AIFF format. Patch by Anthony Zhang. + +- Issue #28556: Various updates to typing module: typing.Counter, typing.ChainMap, + improved ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi, + Manuel Krebber, and Łukasz Langa. + +- Issue #29100: Fix datetime.fromtimestamp() regression introduced in Python + 3.6.0: check minimum and maximum years. + +- Issue #29519: Fix weakref spewing exceptions during interpreter shutdown + when used with a rare combination of multiprocessing and custom codecs. + +- Issue #29416: Prevent infinite loop in pathlib.Path.mkdir + +- Issue #29444: Fixed out-of-bounds buffer access in the group() method of + the match object. Based on patch by WGH. + +- Issue #29335: Fix subprocess.Popen.wait() when the child process has + exited to a stopped instead of terminated state (ex: when under ptrace). + +- Issue #29290: Fix a regression in argparse that help messages would wrap at + non-breaking spaces. + +- Issue #28735: Fixed the comparison of mock.MagickMock with mock.ANY. + +- Issue #29316: Restore the provisional status of typing module, add + corresponding note to documentation. Patch by Ivan L. + +- Issue #29219: Fixed infinite recursion in the repr of uninitialized + ctypes.CDLL instances. + +- Issue #29011: Fix an important omission by adding Deque to the typing module. + +- Issue #28969: Fixed race condition in C implementation of functools.lru_cache. + KeyError could be raised when cached function with full cache was + simultaneously called from differen threads with the same uncached arguments. + +- Issue #29142: In urllib.request, suffixes in no_proxy environment variable with + leading dots could match related hostnames again (e.g. .b.c matches a.b.c). + Patch by Milan Oberkirch. + +- Issue #28961: Fix unittest.mock._Call helper: don't ignore the name parameter + anymore. Patch written by Jiajun Huang. + +- Issue #29203: functools.lru_cache() now respects PEP 468 and preserves + the order of keyword arguments. f(a=1, b=2) is now cached separately + from f(b=2, a=1) since both calls could potentially give different results. + +- Issue #15812: inspect.getframeinfo() now correctly shows the first line of + a context. Patch by Sam Breese. + +- Issue #29094: Offsets in a ZIP file created with extern file object and modes + "w" and "x" now are relative to the start of the file. + +- Issue #29085: Allow random.Random.seed() to use high quality OS randomness + rather than the pid and time. + +- Issue #29061: Fixed bug in secrets.randbelow() which would hang when given + a negative input. Patch by Brendan Donegan. + +- Issue #29079: Prevent infinite loop in pathlib.resolve() on Windows + +- Issue #13051: Fixed recursion errors in large or resized + curses.textpad.Textbox. Based on patch by Tycho Andersen. + +- Issue #29119: Fix weakrefs in the pure python version of + collections.OrderedDict move_to_end() method. + Contributed by Andra Bogildea. + +- Issue #9770: curses.ascii predicates now work correctly with negative + integers. + +- Issue #28427: old keys should not remove new values from + WeakValueDictionary when collecting from another thread. + +- Issue 28923: Remove editor artifacts from Tix.py. + +- Issue #29055: Neaten-up empty population error on random.choice() + by suppressing the upstream exception. + +- Issue #28871: Fixed a crash when deallocate deep ElementTree. + +- Issue #19542: Fix bugs in WeakValueDictionary.setdefault() and + WeakValueDictionary.pop() when a GC collection happens in another + thread. + +- Issue #20191: Fixed a crash in resource.prlimit() when passing a sequence that + doesn't own its elements as limits. + +- Issue #28779: multiprocessing.set_forkserver_preload() would crash the + forkserver process if a preloaded module instantiated some + multiprocessing objects such as locks. + +- Issue #28847: dbm.dumb now supports reading read-only files and no longer + writes the index file when it is not changed. + +- Issue #26937: The chown() method of the tarfile.TarFile class does not fail + now when the grp module cannot be imported, as for example on Android + platforms. + +Windows +------- + +- bpo-29579: Removes readme.txt from the installer + +- Issue #29326: Ignores blank lines in ._pth files (Patch by Alexey Izbyshev) + +- Issue #28164: Correctly handle special console filenames (patch by Eryk Sun) + +- Issue #29409: Implement PEP 529 for io.FileIO (Patch by Eryk Sun) + +- Issue #29392: Prevent crash when passing invalid arguments into msvcrt module. + +- Issue #25778: winreg does not truncate string correctly (Patch by Eryk Sun) + +- Issue #28896: Deprecate WindowsRegistryFinder and disable it by default. + +C API +----- + +- Issue #27867: Function PySlice_GetIndicesEx() is replaced with a macro if + Py_LIMITED_API is not set or set to the value between 0x03050400 + and 0x03060000 (not including) or 0x03060100 or higher. + +- Issue #29083: Fixed the declaration of some public API functions. + PyArg_VaParse() and PyArg_VaParseTupleAndKeywords() were not available in + limited API. PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and + Py_BuildValue() were not available in limited API of version < 3.3 when + PY_SSIZE_T_CLEAN is defined. + +- Issue #29058: All stable API extensions added after Python 3.2 are now + available only when Py_LIMITED_API is set to the PY_VERSION_HEX value of + the minimum Python version supporting this API. + +Documentation +------------- + +- bpo-28929: Link the documentation to its source file on GitHub. + +- bpo-25008: Document smtpd.py as effectively deprecated and add a pointer to + aiosmtpd, a third-party asyncio-based replacement. + +- Issue #26355: Add canonical header link on each page to corresponding major + version of the documentation. Patch by Matthias Bussonnier. + +- Issue #29349: Fix Python 2 syntax in code for building the documentation. + +Tests +----- + +- bpo-28087: Skip test_asyncore and test_eintr poll failures on macOS. + Skip some tests of select.poll when running on macOS due to unresolved + issues with the underlying system poll function on some macOS versions. + +- Issue #29571: to match the behaviour of the ``re.LOCALE`` flag, + test_re.test_locale_flag now uses ``locale.getpreferredencoding(False)`` to + determine the candidate encoding for the test regex (allowing it to correctly + skip the test when the default locale encoding is a multi-byte encoding) + +- Issue #28950: Disallow -j0 to be combined with -T/-l in regrtest + command line arguments. + +- Issue #28683: Fix the tests that bind() a unix socket and raise + PermissionError on Android for a non-root user. + +- Issue #26939: Add the support.setswitchinterval() function to fix + test_functools hanging on the Android armv7 qemu emulator. + +Build +----- + +- bpo-27593: sys.version and the platform module python_build(), + python_branch(), and python_revision() functions now use + git information rather than hg when building from a repo. + +- bpo-29572: Update Windows build and OS X installers to use OpenSSL 1.0.2k. + +- Issue #26851: Set Android compilation and link flags. + +- Issue #28768: Fix implicit declaration of function _setmode. Patch by + Masayuki Yamamoto + +- Issue #29080: Removes hard dependency on hg.exe from PCBuild/build.bat + +- Issue #23903: Added missed names to PC/python3.def. + +- Issue #28762: lockf() is available on Android API level 24, but the F_LOCK + macro is not defined in android-ndk-r13. + +- Issue #28538: Fix the compilation error that occurs because if_nameindex() is + available on Android API level 24, but the if_nameindex structure is not + defined. + +- Issue #20211: Do not add the directory for installing C header files and the + directory for installing object code libraries to the cross compilation + search paths. Original patch by Thomas Petazzoni. + +- Issue #28849: Do not define sys.implementation._multiarch on Android. + + What's New in Python 3.6.0? =========================== @@ -22,7 +355,7 @@ Core and Builtins must not convert combined table into split table. Patch written by INADA Naoki. -- Issue #28990: Fix asynchio SSL hanging if connection is closed before +- Issue #28990: Fix asyncio SSL hanging if connection is closed before handshake is completed. (Patch by HoHo-Ho) Tools/Demos @@ -76,6 +409,10 @@ Library may be revisited again after the Python 2.7 branch is no longer officially supported. +- Issue #26273: Add new :data:`socket.TCP_CONGESTION` (Linux 2.6.13) and + :data:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by + Omar Sandoval. + - Issue #24142: Reading a corrupt config file left configparser in an invalid state. Original patch by Florian Höch. @@ -143,10 +480,6 @@ Core and Builtins Library ------- -- Issue #26273: Add new :data:`socket.TCP_CONGESTION` (Linux 2.6.13) and - :data:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by - Omar Sandoval. - - Issue #28752: Restored the __reduce__() methods of datetime objects. - Issue #28727: Regular expression patterns, _sre.SRE_Pattern objects created @@ -446,9 +779,9 @@ Library - Issue #28227: gzip now supports pathlib. Patch by Ethan Furman. - Issue #27358: Optimized merging var-keyword arguments and improved error - message when pass a non-mapping as a var-keyword argument. + message when passing a non-mapping as a var-keyword argument. -- Issue #28257: Improved error message when pass a non-iterable as +- Issue #28257: Improved error message when passing a non-iterable as a var-positional argument. Added opcode BUILD_TUPLE_UNPACK_WITH_CALL. - Issue #28322: Fixed possible crashes when unpickle itertools objects from @@ -1076,7 +1409,7 @@ Build - Issue #26307: The profile-opt build now applies PGO to the built-in modules. -- Issue #26539: Add the --with-optimizations flag to turn on LTO and PGO build +- Issue #26359: Add the --with-optimizations flag to turn on LTO and PGO build support when available. - Issue #27917: Set platform triplets for Android builds. @@ -3157,122 +3490,1572 @@ C API instead of TypeError on programmical error in parsing format string. -What's New in Python 3.5.1 final? -================================= - -Release date: 2015-12-06 - -Core and Builtins ------------------ - -- Issue #25709: Fixed problem with in-place string concatenation and - utf-8 cache. +What's New in Python 3.5.3? +=========================== -Windows -------- +Release date: 2017-01-17 -- Issue #25715: Python 3.5.1 installer shows wrong upgrade path and incorrect - logic for launcher detection. +There were no code changes between 3.5.3rc1 and 3.5.3 final. -What's New in Python 3.5.1 release candidate 1? +What's New in Python 3.5.3 release candidate 1? =============================================== -Release date: 2015-11-22 +Release date: 2017-01-02 Core and Builtins ----------------- -- Issue #25630: Fix a possible segfault during argument parsing in functions - that accept filesystem paths. +- Issue #29073: bytearray formatting no longer truncates on first null byte. -- Issue #23564: Fixed a partially broken sanity check in the _posixsubprocess - internals regarding how fds_to_pass were passed to the child. The bug had - no actual impact as subprocess.py already avoided it. +- Issue #28932: Do not include if it does not exist. -- Issue #25388: Fixed tokenizer crash when processing undecodable source code - with a null byte. +- Issue #28147: Fix a memory leak in split-table dictionaries: setattr() + must not convert combined table into split table. -- Issue #25462: The hash of the key now is calculated only once in most - operations in C implementation of OrderedDict. +- Issue #25677: Correct the positioning of the syntax error caret for + indented blocks. Based on patch by Michael Layzell. -- Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now - rejects builtin types with not defined __new__. +- Issue #29000: Fixed bytes formatting of octals with zero padding in alternate + form. -- Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node - when compiling AST from Python objects. +- Issue #28512: Fixed setting the offset attribute of SyntaxError by + PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject(). -- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() - and eval() are passed bytes-like objects. These objects are not - necessarily terminated by a null byte, but the functions assumed they were. +- Issue #28991: functools.lru_cache() was susceptible to an obscure reentrancy + bug caused by a monkey-patched len() function. -- Issue #24726: Fixed a crash and leaking NULL in repr() of OrderedDict that - was mutated by direct calls of dict methods. +- Issue #28648: Fixed crash in Py_DecodeLocale() in debug build on Mac OS X + when decode astral characters. Patch by Xiang Zhang. -- Issue #25449: Iterating OrderedDict with keys with unstable hash now raises - KeyError in C implementations as well as in Python implementation. +- Issue #19398: Extra slash no longer added to sys.path components in case of + empty compile-time PYTHONPATH components. -- Issue #25395: Fixed crash when highly nested OrderedDict structures were - garbage collected. +- Issue #28426: Fixed potential crash in PyUnicode_AsDecodedObject() in debug + build. -- Issue #25274: sys.setrecursionlimit() now raises a RecursionError if the new - recursion limit is too low depending at the current recursion depth. Modify - also the "lower-water mark" formula to make it monotonic. This mark is used - to decide when the overflowed flag of the thread state is reset. +- Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception + loss in PyTraceBack_Here(). -- Issue #24402: Fix input() to prompt to the redirected stdout when - sys.stdout.fileno() fails. +- Issue #28379: Added sanity checks and tests for PyUnicode_CopyCharacters(). + Patch by Xiang Zhang. -- Issue #24806: Prevent builtin types that are not allowed to be subclassed from - being subclassed through multiple inheritance. +- Issue #28376: The type of long range iterator is now registered as Iterator. + Patch by Oren Milman. -- Issue #24848: Fixed a number of bugs in UTF-7 decoding of misformed data. +- Issue #28376: The constructor of range_iterator now checks that step is not 0. + Patch by Oren Milman. -- Issue #25280: Import trace messages emitted in verbose (-v) mode are no - longer formatted twice. +- Issue #26906: Resolving special methods of uninitialized type now causes + implicit initialization of the type instead of a fail. -- Issue #25003: On Solaris 11.3 or newer, os.urandom() now uses the - getrandom() function instead of the getentropy() function. The getentropy() - function is blocking to generate very good quality entropy, os.urandom() - doesn't need such high-quality entropy. +- Issue #18287: PyType_Ready() now checks that tp_name is not NULL. + Original patch by Niklas Koep. -- Issue #25182: The stdprinter (used as sys.stderr before the io module is - imported at startup) now uses the backslashreplace error handler. +- Issue #24098: Fixed possible crash when AST is changed in process of + compiling it. -- Issue #25131: Make the line number and column offset of set/dict literals and - comprehensions correspond to the opening brace. +- Issue #28350: String constants with null character no longer interned. -- Issue #25150: Hide the private _Py_atomic_xxx symbols from the public - Python.h header to fix a compilation error with OpenMP. PyThreadState_GET() - becomes an alias to PyThreadState_Get() to avoid ABI incompatibilies. +- Issue #26617: Fix crash when GC runs during weakref callbacks. -Library -------- +- Issue #27942: String constants now interned recursively in tuples and frozensets. -- Issue #25626: Change three zlib functions to accept sizes that fit in - Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a - regression in 3.5 where GzipFile.read() failed to read chunks larger than 2 - or 4 GiB. The change affects the zlib.Decompress.decompress() max_length - parameter, the zlib.decompress() bufsize parameter, and the - zlib.Decompress.flush() length parameter. +- Issue #21578: Fixed misleading error message when ImportError called with + invalid keyword args. -- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) - when the OS gives priority to errors such as EACCES over EEXIST. +- Issue #28203: Fix incorrect type in error message from + ``complex(1.0, {2:3})``. Patch by Soumya Sharma. -- Issue #25593: Change semantics of EventLoop.stop() in asyncio. +- Issue #27955: Fallback on reading /dev/urandom device when the getrandom() + syscall fails with EPERM, for example when blocked by SECCOMP. -- Issue #6973: When we know a subprocess.Popen process has died, do - not allow the send_signal(), terminate(), or kill() methods to do - anything as they could potentially signal a different process. +- Issue #28131: Fix a regression in zipimport's compile_source(). zipimport + should use the same optimization level as the interpreter. -- Issue #25590: In the Readline completer, only call getattr() once per - attribute. +- Issue #25221: Fix corrupted result from PyLong_FromLong(0) when + Python is compiled with NSMALLPOSINTS = 0. -- Issue #25498: Fix a crash when garbage-collecting ctypes objects created - by wrapping a memoryview. This was a regression made in 3.5a1. Based - on patch by Eryksun. +- Issue #25758: Prevents zipimport from unnecessarily encoding a filename + (patch by Eryk Sun) -- Issue #25584: Added "escape" to the __all__ list in the glob module. +- Issue #28189: dictitems_contains no longer swallows compare errors. + (Patch by Xiang Zhang) + +- Issue #27812: Properly clear out a generator's frame's backreference to the + generator to prevent crashes in frame.clear(). + +- Issue #27811: Fix a crash when a coroutine that has not been awaited is + finalized with warnings-as-errors enabled. + +- Issue #27587: Fix another issue found by PVS-Studio: Null pointer check + after use of 'def' in _PyState_AddModule(). + Initial patch by Christian Heimes. + +- Issue #26020: set literal evaluation order did not match documented behaviour. + +- Issue #27782: Multi-phase extension module import now correctly allows the + ``m_methods`` field to be used to add module level functions to instances + of non-module types returned from ``Py_create_mod``. Patch by Xiang Zhang. + +- Issue #27936: The round() function accepted a second None argument + for some types but not for others. Fixed the inconsistency by + accepting None for all numeric types. + +- Issue #27487: Warn if a submodule argument to "python -m" or + runpy.run_module() is found in sys.modules after parent packages are + imported, but before the submodule is executed. + +- Issue #27558: Fix a SystemError in the implementation of "raise" statement. + In a brand new thread, raise a RuntimeError since there is no active + exception to reraise. Patch written by Xiang Zhang. + +- Issue #27419: Standard __import__() no longer look up "__import__" in globals + or builtins for importing submodules or "from import". Fixed handling an + error of non-string package name. + +- Issue #27083: Respect the PYTHONCASEOK environment variable under Windows. + +- Issue #27514: Make having too many statically nested blocks a SyntaxError + instead of SystemError. + +- Issue #27473: Fixed possible integer overflow in bytes and bytearray + concatenations. Patch by Xiang Zhang. + +- Issue #27507: Add integer overflow check in bytearray.extend(). Patch by + Xiang Zhang. + +- Issue #27581: Don't rely on wrapping for overflow check in + PySequence_Tuple(). Patch by Xiang Zhang. + +- Issue #27443: __length_hint__() of bytearray iterators no longer return a + negative integer for a resized bytearray. + +- Issue #27942: Fix memory leak in codeobject.c + +Library +------- + +- Issue #15812: inspect.getframeinfo() now correctly shows the first line of + a context. Patch by Sam Breese. + +- Issue #29094: Offsets in a ZIP file created with extern file object and modes + "w" and "x" now are relative to the start of the file. + +- Issue #13051: Fixed recursion errors in large or resized + curses.textpad.Textbox. Based on patch by Tycho Andersen. + +- Issue #29119: Fix weakrefs in the pure python version of + collections.OrderedDict move_to_end() method. + Contributed by Andra Bogildea. + +- Issue #9770: curses.ascii predicates now work correctly with negative + integers. + +- Issue #28427: old keys should not remove new values from + WeakValueDictionary when collecting from another thread. + +- Issue 28923: Remove editor artifacts from Tix.py. + +- Issue #28871: Fixed a crash when deallocate deep ElementTree. + +- Issue #19542: Fix bugs in WeakValueDictionary.setdefault() and + WeakValueDictionary.pop() when a GC collection happens in another + thread. + +- Issue #20191: Fixed a crash in resource.prlimit() when pass a sequence that + doesn't own its elements as limits. + +- Issue #28779: multiprocessing.set_forkserver_preload() would crash the + forkserver process if a preloaded module instantiated some + multiprocessing objects such as locks. + +- Issue #28847: dbm.dumb now supports reading read-only files and no longer + writes the index file when it is not changed. + +- Issue #25659: In ctypes, prevent a crash calling the from_buffer() and + from_buffer_copy() methods on abstract classes like Array. + +- Issue #28732: Fix crash in os.spawnv() with no elements in args + +- Issue #28485: Always raise ValueError for negative + compileall.compile_dir(workers=...) parameter, even when multithreading is + unavailable. + +- Issue #28387: Fixed possible crash in _io.TextIOWrapper deallocator when + the garbage collector is invoked in other thread. Based on patch by + Sebastian Cufre. + +- Issue #27517: LZMA compressor and decompressor no longer raise exceptions if + given empty data twice. Patch by Benjamin Fogle. + +- Issue #28549: Fixed segfault in curses's addch() with ncurses6. + +- Issue #28449: tarfile.open() with mode "r" or "r:" now tries to open a tar + file with compression before trying to open it without compression. Otherwise + it had 50% chance failed with ignore_zeros=True. + +- Issue #23262: The webbrowser module now supports Firefox 36+ and derived + browsers. Based on patch by Oleg Broytman. + +- Issue #27939: Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused + by representing the scale as float value internally in Tk. tkinter.IntVar + now works if float value is set to underlying Tk variable. + +- Issue #28255: calendar.TextCalendar().prmonth() no longer prints a space + at the start of new line after printing a month's calendar. Patch by + Xiang Zhang. + +- Issue #20491: The textwrap.TextWrapper class now honors non-breaking spaces. + Based on patch by Kaarle Ritvanen. + +- Issue #28353: os.fwalk() no longer fails on broken links. + +- Issue #25464: Fixed HList.header_exists() in tkinter.tix module by addin + a workaround to Tix library bug. + +- Issue #28488: shutil.make_archive() no longer add entry "./" to ZIP archive. + +- Issue #24452: Make webbrowser support Chrome on Mac OS X. + +- Issue #20766: Fix references leaked by pdb in the handling of SIGINT + handlers. + +- Issue #26293: Fixed writing ZIP files that starts not from the start of the + file. Offsets in ZIP file now are relative to the start of the archive in + conforming to the specification. + +- Issue #28321: Fixed writing non-BMP characters with binary format in plistlib. + +- Issue #28322: Fixed possible crashes when unpickle itertools objects from + incorrect pickle data. Based on patch by John Leitch. + +- Fix possible integer overflows and crashes in the mmap module with unusual + usage patterns. + +- Issue #1703178: Fix the ability to pass the --link-objects option to the + distutils build_ext command. + +- Issue #28253: Fixed calendar functions for extreme months: 0001-01 + and 9999-12. + + Methods itermonthdays() and itermonthdays2() are reimplemented so + that they don't call itermonthdates() which can cause datetime.date + under/overflow. + +- Issue #28275: Fixed possible use after free in the decompress() + methods of the LZMADecompressor and BZ2Decompressor classes. + Original patch by John Leitch. + +- Issue #27897: Fixed possible crash in sqlite3.Connection.create_collation() + if pass invalid string-like object as a name. Patch by Xiang Zhang. + +- Issue #18893: Fix invalid exception handling in Lib/ctypes/macholib/dyld.py. + Patch by Madison May. + +- Issue #27611: Fixed support of default root window in the tkinter.tix module. + +- Issue #27348: In the traceback module, restore the formatting of exception + messages like "Exception: None". This fixes a regression introduced in + 3.5a2. + +- Issue #25651: Allow falsy values to be used for msg parameter of subTest(). + +- Issue #27932: Prevent memory leak in win32_ver(). + +- Fix UnboundLocalError in socket._sendfile_use_sendfile. + +- Issue #28075: Check for ERROR_ACCESS_DENIED in Windows implementation of + os.stat(). Patch by Eryk Sun. + +- Issue #25270: Prevent codecs.escape_encode() from raising SystemError when + an empty bytestring is passed. + +- Issue #28181: Get antigravity over HTTPS. Patch by Kaartic Sivaraam. + +- Issue #25895: Enable WebSocket URL schemes in urllib.parse.urljoin. + Patch by Gergely Imreh and Markus Holtermann. + +- Issue #27599: Fixed buffer overrun in binascii.b2a_qp() and binascii.a2b_qp(). + +- Issue #19003:m email.generator now replaces only \r and/or \n line + endings, per the RFC, instead of all unicode line endings. + +- Issue #28019: itertools.count() no longer rounds non-integer step in range + between 1.0 and 2.0 to 1. + +- Issue #25969: Update the lib2to3 grammar to handle the unpacking + generalizations added in 3.5. + +- Issue #14977: mailcap now respects the order of the lines in the mailcap + files ("first match"), as required by RFC 1542. Patch by Michael Lazar. + +- Issue #24594: Validates persist parameter when opening MSI database + +- Issue #17582: xml.etree.ElementTree nows preserves whitespaces in attributes + (Patch by Duane Griffin. Reviewed and approved by Stefan Behnel.) + +- Issue #28047: Fixed calculation of line length used for the base64 CTE + in the new email policies. + +- Issue #27445: Don't pass str(_charset) to MIMEText.set_payload(). + Patch by Claude Paroz. + +- Issue #22450: urllib now includes an "Accept: */*" header among the + default headers. This makes the results of REST API requests more + consistent and predictable especially when proxy servers are involved. + +- lib2to3.pgen3.driver.load_grammar() now creates a stable cache file + between runs given the same Grammar.txt input regardless of the hash + randomization setting. + +- Issue #27570: Avoid zero-length memcpy() etc calls with null source + pointers in the "ctypes" and "array" modules. + +- Issue #22233: Break email header lines *only* on the RFC specified CR and LF + characters, not on arbitrary unicode line breaks. This also fixes a bug in + HTTP header parsing. + +- Issue 27988: Fix email iter_attachments incorrect mutation of payload list. + +- Issue #27691: Fix ssl module's parsing of GEN_RID subject alternative name + fields in X.509 certs. + +- Issue #27850: Remove 3DES from ssl module's default cipher list to counter + measure sweet32 attack (CVE-2016-2183). + +- Issue #27766: Add ChaCha20 Poly1305 to ssl module's default ciper list. + (Required OpenSSL 1.1.0 or LibreSSL). + +- Issue #26470: Port ssl and hashlib module to OpenSSL 1.1.0. + +- Remove support for passing a file descriptor to os.access. It never worked but + previously didn't raise. + +- Issue #12885: Fix error when distutils encounters symlink. + +- Issue #27881: Fixed possible bugs when setting sqlite3.Connection.isolation_level. + Based on patch by Xiang Zhang. + +- Issue #27861: Fixed a crash in sqlite3.Connection.cursor() when a factory + creates not a cursor. Patch by Xiang Zhang. + +- Issue #19884: Avoid spurious output on OS X with Gnu Readline. + +- Issue #27706: Restore deterministic behavior of random.Random().seed() + for string seeds using seeding version 1. Allows sequences of calls + to random() to exactly match those obtained in Python 2. + Patch by Nofar Schnider. + +- Issue #10513: Fix a regression in Connection.commit(). Statements should + not be reset after a commit. + +- A new version of typing.py from https://github.com/python/typing: + - Collection (only for 3.6) (Issue #27598) + - Add FrozenSet to __all__ (upstream #261) + - fix crash in _get_type_vars() (upstream #259) + - Remove the dict constraint in ForwardRef._eval_type (upstream #252) + +- Issue #27539: Fix unnormalised ``Fraction.__pow__`` result in the case + of negative exponent and negative base. + +- Issue #21718: cursor.description is now available for queries using CTEs. + +- Issue #2466: posixpath.ismount now correctly recognizes mount points which + the user does not have permission to access. + +- Issue #27773: Correct some memory management errors server_hostname in + _ssl.wrap_socket(). + +- Issue #26750: unittest.mock.create_autospec() now works properly for + subclasses of property() and other data descriptors. + +- In the curses module, raise an error if window.getstr() or window.instr() is + passed a negative value. + +- Issue #27783: Fix possible usage of uninitialized memory in + operator.methodcaller. + +- Issue #27774: Fix possible Py_DECREF on unowned object in _sre. + +- Issue #27760: Fix possible integer overflow in binascii.b2a_qp. + +- Issue #27758: Fix possible integer overflow in the _csv module for large + record lengths. + +- Issue #27568: Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the + HTTP_PROXY variable when REQUEST_METHOD environment is set, which indicates + that the script is in CGI mode. + +- Issue #27656: Do not assume sched.h defines any SCHED_* constants. + +- Issue #27130: In the "zlib" module, fix handling of large buffers + (typically 4 GiB) when compressing and decompressing. Previously, inputs + were limited to 4 GiB, and compression and decompression operations did not + properly handle results of 4 GiB. + +- Issue #27533: Release GIL in nt._isdir + +- Issue #17711: Fixed unpickling by the persistent ID with protocol 0. + Original patch by Alexandre Vassalotti. + +- Issue #27522: Avoid an unintentional reference cycle in email.feedparser. + +- Issue #26844: Fix error message for imp.find_module() to refer to 'path' + instead of 'name'. Patch by Lev Maximov. + +- Issue #23804: Fix SSL zero-length recv() calls to not block and not raise + an error about unclean EOF. + +- Issue #27466: Change time format returned by http.cookie.time2netscape, + confirming the netscape cookie format and making it consistent with + documentation. + +- Issue #26664: Fix activate.fish by removing mis-use of ``$``. + +- Issue #22115: Fixed tracing Tkinter variables: trace_vdelete() with wrong + mode no longer break tracing, trace_vinfo() now always returns a list of + pairs of strings, tracing in the "u" mode now works. + +- Fix a scoping issue in importlib.util.LazyLoader which triggered an + UnboundLocalError when lazy-loading a module that was already put into + sys.modules. + +- Issue #27079: Fixed curses.ascii functions isblank(), iscntrl() and ispunct(). + +- Issue #26754: Some functions (compile() etc) accepted a filename argument + encoded as an iterable of integers. Now only strings and byte-like objects + are accepted. + +- Issue #27048: Prevents distutils failing on Windows when environment + variables contain non-ASCII characters + +- Issue #27330: Fixed possible leaks in the ctypes module. + +- Issue #27238: Got rid of bare excepts in the turtle module. Original patch + by Jelle Zijlstra. + +- Issue #27122: When an exception is raised within the context being managed + by a contextlib.ExitStack() and one of the exit stack generators + catches and raises it in a chain, do not re-raise the original exception + when exiting, let the new chained one through. This avoids the PEP 479 + bug described in issue25782. + +- [Security] Issue #27278: Fix os.urandom() implementation using getrandom() on + Linux. Truncate size to INT_MAX and loop until we collected enough random + bytes, instead of casting a directly Py_ssize_t to int. + +- Issue #26386: Fixed ttk.TreeView selection operations with item id's + containing spaces. + +- [Security] Issue #22636: Avoid shell injection problems with + ctypes.util.find_library(). + +- Issue #16182: Fix various functions in the "readline" module to use the + locale encoding, and fix get_begidx() and get_endidx() to return code point + indexes. + +- Issue #27392: Add loop.connect_accepted_socket(). + Patch by Jim Fulton. + +- Issue #27930: Improved behaviour of logging.handlers.QueueListener. + Thanks to Paulo Andrade and Petr Viktorin for the analysis and patch. + +- Issue #21201: Improves readability of multiprocessing error message. Thanks + to Wojciech Walczak for patch. + +- Issue #27456: asyncio: Set TCP_NODELAY by default. + +- Issue #27906: Fix socket accept exhaustion during high TCP traffic. + Patch by Kevin Conway. + +- Issue #28174: Handle when SO_REUSEPORT isn't properly supported. + Patch by Seth Michael Larson. + +- Issue #26654: Inspect functools.partial in asyncio.Handle.__repr__. + Patch by iceboy. + +- Issue #26909: Fix slow pipes IO in asyncio. + Patch by INADA Naoki. + +- Issue #28176: Fix callbacks race in asyncio.SelectorLoop.sock_connect. + +- Issue #27759: Fix selectors incorrectly retain invalid file descriptors. + Patch by Mark Williams. + +- Issue #28368: Refuse monitoring processes if the child watcher has + no loop attached. + Patch by Vincent Michel. + +- Issue #28369: Raise RuntimeError when transport's FD is used with + add_reader, add_writer, etc. + +- Issue #28370: Speedup asyncio.StreamReader.readexactly. + Patch by Коренберг Марк. + +- Issue #28371: Deprecate passing asyncio.Handles to run_in_executor. + +- Issue #28372: Fix asyncio to support formatting of non-python coroutines. + +- Issue #28399: Remove UNIX socket from FS before binding. + Patch by Коренберг Марк. + +- Issue #27972: Prohibit Tasks to await on themselves. + +- Issue #26923: Fix asyncio.Gather to refuse being cancelled once all + children are done. + Patch by Johannes Ebke. + +- Issue #26796: Don't configure the number of workers for default + threadpool executor. + Initial patch by Hans Lawrenz. + +- Issue #28600: Optimize loop.call_soon(). + +- Issue #28613: Fix get_event_loop() return the current loop if + called from coroutines/callbacks. + +- Issue #28639: Fix inspect.isawaitable to always return bool + Patch by Justin Mayfield. + +- Issue #28652: Make loop methods reject socket kinds they do not support. + +- Issue #28653: Fix a refleak in functools.lru_cache. + +- Issue #28703: Fix asyncio.iscoroutinefunction to handle Mock objects. + +- Issue #24142: Reading a corrupt config file left the parser in an + invalid state. Original patch by Florian Höch. + +- Issue #28990: Fix SSL hanging if connection is closed before handshake + completed. + (Patch by HoHo-Ho) + +IDLE +---- + +- Issue #15308: Add 'interrupt execution' (^C) to Shell menu. + Patch by Roger Serwy, updated by Bayard Randel. + +- Issue #27922: Stop IDLE tests from 'flashing' gui widgets on the screen. + +- Add version to title of IDLE help window. + +- Issue #25564: In section on IDLE -- console differences, mention that + using exec means that __builtins__ is defined for each statement. + +- Issue #27714: text_textview and test_autocomplete now pass when re-run + in the same process. This occurs when test_idle fails when run with the + -w option but without -jn. Fix warning from test_config. + +- Issue #25507: IDLE no longer runs buggy code because of its tkinter imports. + Users must include the same imports required to run directly in Python. + +- Issue #27452: add line counter and crc to IDLE configHandler test dump. + +- Issue #27365: Allow non-ascii chars in IDLE NEWS.txt, for contributor names. + +- Issue #27245: IDLE: Cleanly delete custom themes and key bindings. + Previously, when IDLE was started from a console or by import, a cascade + of warnings was emitted. Patch by Serhiy Storchaka. + +C API +----- + +- Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions. + +- Issue #26754: PyUnicode_FSDecoder() accepted a filename argument encoded as + an iterable of integers. Now only strings and bytes-like objects are accepted. + +Documentation +------------- + +- Issue #28513: Documented command-line interface of zipfile. + +Tests +----- + +- Issue #28950: Disallow -j0 to be combined with -T/-l/-M in regrtest + command line arguments. + +- Issue #28666: Now test.support.rmtree is able to remove unwritable or + unreadable directories. + +- Issue #23839: Various caches now are cleared before running every test file. + +- Issue #28409: regrtest: fix the parser of command line arguments. + +- Issue #27787: Call gc.collect() before checking each test for "dangling + threads", since the dangling threads are weak references. + +- Issue #27369: In test_pyexpat, avoid testing an error message detail that + changed in Expat 2.2.0. + +Tools/Demos +----------- + +- Issue #27952: Get Tools/scripts/fixcid.py working with Python 3 and the + current "re" module, avoid invalid Python backslash escapes, and fix a bug + parsing escaped C quote signs. + +- Issue #27332: Fixed the type of the first argument of module-level functions + generated by Argument Clinic. Patch by Petr Viktorin. + +- Issue #27418: Fixed Tools/importbench/importbench.py. + +Windows +------- + +- Issue #28251: Improvements to help manuals on Windows. + +- Issue #28110: launcher.msi has different product codes between 32-bit and + 64-bit + +- Issue #25144: Ensures TargetDir is set before continuing with custom + install. + +- Issue #27469: Adds a shell extension to the launcher so that drag and drop + works correctly. + +- Issue #27309: Enabled proper Windows styles in python[w].exe manifest. + +Build +----- + +- Issue #29080: Removes hard dependency on hg.exe from PCBuild/build.bat + +- Issue #23903: Added missed names to PC/python3.def. + +- Issue #10656: Fix out-of-tree building on AIX. Patch by Tristan Carel and + Michael Haubenwallner. + +- Issue #26359: Rename --with-optimiations to --enable-optimizations. + +- Issue #28444: Fix missing extensions modules when cross compiling. + +- Issue #28248: Update Windows build and OS X installers to use OpenSSL 1.0.2j. + +- Issue #28258: Fixed build with Estonian locale (python-config and distclean + targets in Makefile). Patch by Arfrever Frehtes Taifersar Arahesis. + +- Issue #26661: setup.py now detects system libffi with multiarch wrapper. + +- Issue #28066: Fix the logic that searches build directories for generated + include files when building outside the source tree. + +- Issue #15819: Remove redundant include search directory option for building + outside the source tree. + +- Issue #27566: Fix clean target in freeze makefile (patch by Lisa Roach) + +- Issue #27705: Update message in validate_ucrtbase.py + +- Issue #27983: Cause lack of llvm-profdata tool when using clang as + required for PGO linking to be a configure time error rather than + make time when --with-optimizations is enabled. Also improve our + ability to find the llvm-profdata tool on MacOS and some Linuxes. + +- Issue #26307: The profile-opt build now applies PGO to the built-in modules. + +- Issue #26359: Add the --with-optimizations configure flag. + +- Issue #27713: Suppress spurious build warnings when updating importlib's + bootstrap files. Patch by Xiang Zhang + +- Issue #25825: Correct the references to Modules/python.exp and ld_so_aix, + which are required on AIX. This updates references to an installation path + that was changed in 3.2a4, and undoes changed references to the build tree + that were made in 3.5.0a1. + +- Issue #27453: CPP invocation in configure must use CPPFLAGS. Patch by + Chi Hsuan Yen. + +- Issue #27641: The configure script now inserts comments into the makefile + to prevent the pgen and _freeze_importlib executables from being cross- + compiled. + +- Issue #26662: Set PYTHON_FOR_GEN in configure as the Python program to be + used for file generation during the build. + +- Issue #10910: Avoid C++ compilation errors on FreeBSD and OS X. + Also update FreedBSD version checks for the original ctype UTF-8 workaround. + +- Issue #28676: Prevent missing 'getentropy' declaration warning on macOS. + Patch by Gareth Rees. + + +What's New in Python 3.5.2? +=========================== + +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 +------- + +- [Security] Issue #26556: Update expat to 2.1.1, fixes CVE-2015-1283. + +- [Security] Fix TLS stripping vulnerability in smtplib, 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. + +- [Security] 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. + +- [Security] 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. + +- [Security] 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. + +- [Security] 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 #19489: Moved the search box from the sidebar to the header and footer + of each page. Patch by Ammar Askar. + +- 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? +================================= + +Release date: 2015-12-06 + +Core and Builtins +----------------- + +- Issue #25709: Fixed problem with in-place string concatenation and + utf-8 cache. + +Windows +------- + +- Issue #25715: Python 3.5.1 installer shows wrong upgrade path and incorrect + logic for launcher detection. + + +What's New in Python 3.5.1 release candidate 1? +=============================================== + +Release date: 2015-11-22 + +Core and Builtins +----------------- + +- Issue #25630: Fix a possible segfault during argument parsing in functions + that accept filesystem paths. + +- Issue #23564: Fixed a partially broken sanity check in the _posixsubprocess + internals regarding how fds_to_pass were passed to the child. The bug had + no actual impact as subprocess.py already avoided it. + +- Issue #25388: Fixed tokenizer crash when processing undecodable source code + with a null byte. + +- Issue #25462: The hash of the key now is calculated only once in most + operations in C implementation of OrderedDict. + +- Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now + rejects builtin types with not defined __new__. + +- Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node + when compiling AST from Python objects. + +- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() + and eval() are passed bytes-like objects. These objects are not + necessarily terminated by a null byte, but the functions assumed they were. + +- Issue #24726: Fixed a crash and leaking NULL in repr() of OrderedDict that + was mutated by direct calls of dict methods. + +- Issue #25449: Iterating OrderedDict with keys with unstable hash now raises + KeyError in C implementations as well as in Python implementation. + +- Issue #25395: Fixed crash when highly nested OrderedDict structures were + garbage collected. + +- Issue #25274: sys.setrecursionlimit() now raises a RecursionError if the new + recursion limit is too low depending at the current recursion depth. Modify + also the "lower-water mark" formula to make it monotonic. This mark is used + to decide when the overflowed flag of the thread state is reset. + +- Issue #24402: Fix input() to prompt to the redirected stdout when + sys.stdout.fileno() fails. + +- Issue #24806: Prevent builtin types that are not allowed to be subclassed from + being subclassed through multiple inheritance. + +- Issue #24848: Fixed a number of bugs in UTF-7 decoding of misformed data. + +- Issue #25280: Import trace messages emitted in verbose (-v) mode are no + longer formatted twice. + +- Issue #25003: On Solaris 11.3 or newer, os.urandom() now uses the + getrandom() function instead of the getentropy() function. The getentropy() + function is blocking to generate very good quality entropy, os.urandom() + doesn't need such high-quality entropy. + +- Issue #25182: The stdprinter (used as sys.stderr before the io module is + imported at startup) now uses the backslashreplace error handler. + +- Issue #25131: Make the line number and column offset of set/dict literals and + comprehensions correspond to the opening brace. + +- Issue #25150: Hide the private _Py_atomic_xxx symbols from the public + Python.h header to fix a compilation error with OpenMP. PyThreadState_GET() + becomes an alias to PyThreadState_Get() to avoid ABI incompatibilies. + +Library +------- + +- Issue #25626: Change three zlib functions to accept sizes that fit in + Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a + regression in 3.5 where GzipFile.read() failed to read chunks larger than 2 + or 4 GiB. The change affects the zlib.Decompress.decompress() max_length + parameter, the zlib.decompress() bufsize parameter, and the + zlib.Decompress.flush() length parameter. + +- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) + when the OS gives priority to errors such as EACCES over EEXIST. + +- Issue #25593: Change semantics of EventLoop.stop() in asyncio. + +- Issue #6973: When we know a subprocess.Popen process has died, do + not allow the send_signal(), terminate(), or kill() methods to do + anything as they could potentially signal a different process. + +- Issue #25590: In the Readline completer, only call getattr() once per + attribute. + +- Issue #25498: Fix a crash when garbage-collecting ctypes objects created + by wrapping a memoryview. This was a regression made in 3.5a1. Based + on patch by Eryksun. + +- Issue #25584: Added "escape" to the __all__ list in the glob module. - Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'. @@ -3576,6 +5359,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 @@ -3905,6 +5691,12 @@ Library - Issue #24631: Fixed regression in the timeit module with multiline setup. +- Issue #18622: unittest.mock.mock_open().reset_mock would recurse infinitely. + Patch from Nicola Palumbo and Laurent De Buyst. + +- Issue #23661: unittest.mock side_effects can now be exceptions again. This + was a regression vs Python 3.4. Patch from Ignacio Rossi + - Issue #24608: chunk.Chunk.read() now always returns bytes, not str. - Issue #18684: Fixed reading out of the buffer in the re module. @@ -3915,9 +5707,6 @@ Library - Issue #15014: SMTP.auth() and SMTP.login() now support RFC 4954's optional initial-response argument to the SMTP AUTH command. -- Issue #6549: Remove hyphen from ttk.Style().element options. Only return result - from ttk.Style().configure if a result was generated or a query submitted. - - Issue #24669: Fix inspect.getsource() for 'async def' functions. Patch by Kai Groner. @@ -3929,6 +5718,7 @@ Build - Issue #24603: Update Windows builds and OS X 10.5 installer to use OpenSSL 1.0.2d. + What's New in Python 3.5.0 beta 3? ================================== @@ -4089,9 +5879,6 @@ Core and Builtins - Issue #24268: PEP 489: Multi-phase extension module initialization. Patch by Petr Viktorin. -- Issue #23359: Optimize set object internals by specializing the - hash table search into a lookup function and an insert function. - - Issue #23955: Add pyvenv.cfg option to suppress registry/environment lookup for generating sys.path on Windows. @@ -4212,8 +5999,8 @@ Library - Issue #1322: platform.dist() and platform.linux_distribution() functions are now deprecated. Initial patch by Vajrasky Kok. -- Issue #22486: Added the math.gcd() function. The fractions.gcd() function now is - deprecated. Based on patch by Mark Dickinson. +- Issue #22486: Added the math.gcd() function. The fractions.gcd() function + now is deprecated. Based on patch by Mark Dickinson. - Issue #24064: Property() docstrings are now writeable. (Patch by Berker Peksag.) @@ -4634,8 +6421,8 @@ Library writer failed in BufferedRWPair.close(). - Issue #23622: Unknown escapes in regular expressions that consist of ``'\'`` - and an ASCII letter now raise a deprecation warning and will be forbidden - in Python 3.6. + and ASCII letter now raise a deprecation warning and will be forbidden in + Python 3.6. - Issue #23671: string.Template now allows specifying the "self" parameter as a keyword argument. string.Formatter now allows specifying the "self" and diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 4e8f74a..a77ff96 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -521,7 +521,7 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) return NULL; } - for (i = 0; i < len; i++) { + for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) { int ret; PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i); @@ -1327,7 +1327,7 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop) return -1; } - res = _PyObject_CallMethodId(all_tasks, &PyId_add, "O", self, NULL); + res = _PyObject_CallMethodIdObjArgs(all_tasks, &PyId_add, self, NULL); if (res == NULL) { return -1; } @@ -1413,7 +1413,7 @@ TaskObj_get_fut_waiter(TaskObj *task) @classmethod _asyncio.Task.current_task - loop: 'O' = NULL + loop: 'O' = None Return the currently running task in an event loop or None. @@ -1424,12 +1424,12 @@ None is returned when called not in the context of a Task. static PyObject * _asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop) -/*[clinic end generated code: output=99fbe7332c516e03 input=cd784537f02cf833]*/ +/*[clinic end generated code: output=99fbe7332c516e03 input=a0d6cdf2e3b243e1]*/ { PyObject *res; - if (loop == NULL) { - loop = PyObject_CallObject(asyncio_get_event_loop, NULL); + if (loop == Py_None) { + loop = _PyObject_CallNoArg(asyncio_get_event_loop); if (loop == NULL) { return NULL; } @@ -1500,7 +1500,7 @@ fail: @classmethod _asyncio.Task.all_tasks - loop: 'O' = NULL + loop: 'O' = None Return a set of all tasks for an event loop. @@ -1509,12 +1509,12 @@ By default all tasks for the current event loop are returned. static PyObject * _asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop) -/*[clinic end generated code: output=11f9b20749ccca5d input=cd64aa5f88bd5c49]*/ +/*[clinic end generated code: output=11f9b20749ccca5d input=c6f5b53bd487488f]*/ { PyObject *res; - if (loop == NULL) { - loop = PyObject_CallObject(asyncio_get_event_loop, NULL); + if (loop == Py_None) { + loop = _PyObject_CallNoArg(asyncio_get_event_loop); if (loop == NULL) { return NULL; } @@ -1838,8 +1838,8 @@ task_call_wakeup(TaskObj *task, PyObject *fut) } else { /* `task` is a subclass of Task */ - return _PyObject_CallMethodId( - (PyObject*)task, &PyId__wakeup, "O", fut, NULL); + return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__wakeup, + fut, NULL); } } @@ -1854,8 +1854,8 @@ task_call_step(TaskObj *task, PyObject *arg) if (arg == NULL) { arg = Py_None; } - return _PyObject_CallMethodId( - (PyObject*)task, &PyId__step, "O", arg, NULL); + return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__step, + arg, NULL); } } @@ -1869,8 +1869,8 @@ task_call_step_soon(TaskObj *task, PyObject *arg) return -1; } - handle = _PyObject_CallMethodId( - task->task_loop, &PyId_call_soon, "O", cb, NULL); + handle = _PyObject_CallMethodIdObjArgs(task->task_loop, &PyId_call_soon, + cb, NULL); Py_DECREF(cb); if (handle == NULL) { return -1; @@ -2135,8 +2135,9 @@ task_step_impl(TaskObj *task, PyObject *exc) if (wrapper == NULL) { goto fail; } - res = _PyObject_CallMethodId( - result, &PyId_add_done_callback, "O", wrapper, NULL); + res = _PyObject_CallMethodIdObjArgs(result, + &PyId_add_done_callback, + wrapper, NULL); Py_DECREF(wrapper); if (res == NULL) { goto fail; diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 6608798..e6111c6 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -2234,7 +2234,7 @@ static PyTypeObject defdict_type = { PyDoc_STRVAR(_count_elements_doc, "_count_elements(mapping, iterable) -> None\n\ \n\ -Count elements in the iterable, updating the mappping"); +Count elements in the iterable, updating the mapping"); static PyObject * _count_elements(PyObject *self, PyObject *args) diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 629ddf6..59d56d0 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -44,6 +44,19 @@ _testfunc_cbk_large_struct(Test in, void (*func)(Test)) func(in); } +/* + * See issue 29565. Update a structure passed by value; + * the caller should not see any change. + */ + +EXPORT(void) +_testfunc_large_struct_update_value(Test in) +{ + in.first = 0x0badf00d; + in.second = 0x0badf00d; + in.third = 0x0badf00d; +} + EXPORT(void)testfunc_array(int values[4]) { printf("testfunc_array %d %d %d %d\n", diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c index 1d82929..91a27dc 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ b/Modules/_ctypes/libffi_msvc/ffi.c @@ -239,6 +239,16 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, break; #else case FFI_SYSV: + /* If a single argument takes more than 8 bytes, + then a copy is passed by reference. */ + for (unsigned i = 0; i < cif->nargs; i++) { + size_t z = cif->arg_types[i]->size; + if (z > 8) { + void *temp = alloca(z); + memcpy(temp, avalue[i], z); + avalue[i] = temp; + } + } /*@-usedef@*/ return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index c09cce9..c784d0f 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -120,6 +120,8 @@ static PyTypeObject PyDateTime_TimeType; static PyTypeObject PyDateTime_TZInfoType; static PyTypeObject PyDateTime_TimeZoneType; +static int check_tzinfo_subclass(PyObject *p); + _Py_IDENTIFIER(as_integer_ratio); _Py_IDENTIFIER(fromutc); _Py_IDENTIFIER(isoformat); @@ -400,8 +402,7 @@ check_date_args(int year, int month, int day) { if (year < MINYEAR || year > MAXYEAR) { - PyErr_SetString(PyExc_ValueError, - "year is out of range"); + PyErr_Format(PyExc_ValueError, "year %i is out of range", year); return -1; } if (month < 1 || month > 12) { @@ -672,6 +673,10 @@ new_date_ex(int year, int month, int day, PyTypeObject *type) { PyDateTime_Date *self; + if (check_date_args(year, month, day) < 0) { + return NULL; + } + self = (PyDateTime_Date *) (type->tp_alloc(type, 0)); if (self != NULL) set_date_fields(self, year, month, day); @@ -689,6 +694,16 @@ new_datetime_ex2(int year, int month, int day, int hour, int minute, PyDateTime_DateTime *self; char aware = tzinfo != Py_None; + if (check_date_args(year, month, day) < 0) { + return NULL; + } + if (check_time_args(hour, minute, second, usecond, fold) < 0) { + return NULL; + } + if (check_tzinfo_subclass(tzinfo) < 0) { + return NULL; + } + self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware)); if (self != NULL) { self->hastzinfo = aware; @@ -726,6 +741,13 @@ new_time_ex2(int hour, int minute, int second, int usecond, PyDateTime_Time *self; char aware = tzinfo != Py_None; + if (check_time_args(hour, minute, second, usecond, fold) < 0) { + return NULL; + } + if (check_tzinfo_subclass(tzinfo) < 0) { + return NULL; + } + self = (PyDateTime_Time *) (type->tp_alloc(type, aware)); if (self != NULL) { self->hastzinfo = aware; @@ -2500,8 +2522,6 @@ date_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws, &year, &month, &day)) { - if (check_date_args(year, month, day) < 0) - return NULL; self = new_date_ex(year, month, day, type); } return self; @@ -3586,10 +3606,6 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws, &hour, &minute, &second, &usecond, &tzinfo, &fold)) { - if (check_time_args(hour, minute, second, usecond, fold) < 0) - return NULL; - if (check_tzinfo_subclass(tzinfo) < 0) - return NULL; self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold, type); } @@ -3843,11 +3859,11 @@ time_hash(PyDateTime_Time *self) { if (self->hashcode == -1) { PyObject *offset, *self0; - if (DATE_GET_FOLD(self)) { - self0 = new_time_ex2(DATE_GET_HOUR(self), - DATE_GET_MINUTE(self), - DATE_GET_SECOND(self), - DATE_GET_MICROSECOND(self), + if (TIME_GET_FOLD(self)) { + self0 = new_time_ex2(TIME_GET_HOUR(self), + TIME_GET_MINUTE(self), + TIME_GET_SECOND(self), + TIME_GET_MICROSECOND(self), HASTZINFO(self) ? self->tzinfo : Py_None, 0, Py_TYPE(self)); if (self0 == NULL) @@ -4176,12 +4192,6 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws, &year, &month, &day, &hour, &minute, &second, &usecond, &tzinfo, &fold)) { - if (check_date_args(year, month, day) < 0) - return NULL; - if (check_time_args(hour, minute, second, usecond, fold) < 0) - return NULL; - if (check_tzinfo_subclass(tzinfo) < 0) - return NULL; self = new_datetime_ex2(year, month, day, hour, minute, second, usecond, tzinfo, fold, type); @@ -4203,7 +4213,15 @@ static long long utc_to_seconds(int year, int month, int day, int hour, int minute, int second) { - long long ordinal = ymd_to_ord(year, month, day); + long long ordinal; + + /* ymd_to_ord() doesn't support year <= 0 */ + if (year < MINYEAR || year > MAXYEAR) { + PyErr_Format(PyExc_ValueError, "year %i is out of range", year); + return -1; + } + + ordinal = ymd_to_ord(year, month, day); return ((ordinal * 24 + hour) * 60 + minute) * 60 + second; } @@ -4219,7 +4237,6 @@ local(long long u) "timestamp out of range for platform time_t"); return -1; } - /* XXX: add bounds checking */ if (_PyTime_localtime(t, &local_time) != 0) return -1; return utc_to_seconds(local_time.tm_year + 1900, @@ -4257,6 +4274,7 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, */ second = Py_MIN(59, tm.tm_sec); + /* local timezone requires to compute fold */ if (tzinfo == Py_None && f == _PyTime_localtime) { long long probe_seconds, result_seconds, transition; @@ -4516,12 +4534,13 @@ add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta, assert(factor == 1 || factor == -1); if (normalize_datetime(&year, &month, &day, - &hour, &minute, &second, µsecond) < 0) + &hour, &minute, &second, µsecond) < 0) { return NULL; - else - return new_datetime(year, month, day, - hour, minute, second, microsecond, - HASTZINFO(date) ? date->tzinfo : Py_None, 0); + } + + return new_datetime(year, month, day, + hour, minute, second, microsecond, + HASTZINFO(date) ? date->tzinfo : Py_None, 0); } static PyObject * diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 9956786..fcc1f15 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -1118,12 +1118,12 @@ context_getattr(PyObject *self, PyObject *name) PyObject *retval; if (PyUnicode_Check(name)) { - if (_PyUnicode_EqualToASCIIString(name, "traps")) { + if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { retval = ((PyDecContextObject *)self)->traps; Py_INCREF(retval); return retval; } - if (_PyUnicode_EqualToASCIIString(name, "flags")) { + if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { retval = ((PyDecContextObject *)self)->flags; Py_INCREF(retval); return retval; @@ -1143,10 +1143,10 @@ context_setattr(PyObject *self, PyObject *name, PyObject *value) } if (PyUnicode_Check(name)) { - if (_PyUnicode_EqualToASCIIString(name, "traps")) { + if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { return context_settraps_dict(self, value); } - if (_PyUnicode_EqualToASCIIString(name, "flags")) { + if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { return context_setstatus_dict(self, value); } } @@ -2449,14 +2449,14 @@ dectuple_as_str(PyObject *dectuple) tmp = PyTuple_GET_ITEM(dectuple, 2); if (PyUnicode_Check(tmp)) { /* special */ - if (_PyUnicode_EqualToASCIIString(tmp, "F")) { + if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) { strcat(sign_special, "Inf"); is_infinite = 1; } - else if (_PyUnicode_EqualToASCIIString(tmp, "n")) { + else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) { strcat(sign_special, "NaN"); } - else if (_PyUnicode_EqualToASCIIString(tmp, "N")) { + else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) { strcat(sign_special, "sNaN"); } else { diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 5937520..2cda98e 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -626,6 +626,7 @@ static void element_dealloc(ElementObject* self) { PyObject_GC_UnTrack(self); + Py_TRASHCAN_SAFE_BEGIN(self) if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); @@ -636,6 +637,7 @@ element_dealloc(ElementObject* self) RELEASE(sizeof(ElementObject), "destroy element"); Py_TYPE(self)->tp_free((PyObject *)self); + Py_TRASHCAN_SAFE_END(self) } /* -------------------------------------------------------------------- */ diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 2269d05..7abc9f4 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -88,10 +88,13 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (kw == NULL) { pto->kw = PyDict_New(); } - else { + else if (Py_REFCNT(kw) == 1) { Py_INCREF(kw); pto->kw = kw; } + else { + pto->kw = PyDict_Copy(kw); + } } else { pto->kw = PyDict_Copy(pkw); @@ -704,8 +707,8 @@ static PyTypeObject lru_cache_type; static PyObject * lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) { - PyObject *key, *sorted_items; - Py_ssize_t key_size, pos, key_pos; + PyObject *key, *keyword, *value; + Py_ssize_t key_size, pos, key_pos, kwds_size; /* short path, key will match args anyway, which is a tuple */ if (!typed && !kwds) { @@ -713,28 +716,18 @@ lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) return args; } - if (kwds && PyDict_Size(kwds) > 0) { - sorted_items = PyDict_Items(kwds); - if (!sorted_items) - return NULL; - if (PyList_Sort(sorted_items) < 0) { - Py_DECREF(sorted_items); - return NULL; - } - } else - sorted_items = NULL; + kwds_size = kwds ? PyDict_Size(kwds) : 0; + assert(kwds_size >= 0); key_size = PyTuple_GET_SIZE(args); - if (sorted_items) - key_size += PyList_GET_SIZE(sorted_items); + if (kwds_size) + key_size += kwds_size * 2 + 1; if (typed) - key_size *= 2; - if (sorted_items) - key_size++; + key_size += PyTuple_GET_SIZE(args) + kwds_size; key = PyTuple_New(key_size); if (key == NULL) - goto done; + return NULL; key_pos = 0; for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { @@ -742,14 +735,16 @@ lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) Py_INCREF(item); PyTuple_SET_ITEM(key, key_pos++, item); } - if (sorted_items) { + if (kwds_size) { Py_INCREF(kwd_mark); PyTuple_SET_ITEM(key, key_pos++, kwd_mark); - for (pos = 0; pos < PyList_GET_SIZE(sorted_items); ++pos) { - PyObject *item = PyList_GET_ITEM(sorted_items, pos); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); + for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { + Py_INCREF(keyword); + PyTuple_SET_ITEM(key, key_pos++, keyword); + Py_INCREF(value); + PyTuple_SET_ITEM(key, key_pos++, value); } + assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1); } if (typed) { for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { @@ -757,20 +752,15 @@ lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) Py_INCREF(item); PyTuple_SET_ITEM(key, key_pos++, item); } - if (sorted_items) { - for (pos = 0; pos < PyList_GET_SIZE(sorted_items); ++pos) { - PyObject *tp_items = PyList_GET_ITEM(sorted_items, pos); - PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(tp_items, 1)); + if (kwds_size) { + for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { + PyObject *item = (PyObject *)Py_TYPE(value); Py_INCREF(item); PyTuple_SET_ITEM(key, key_pos++, item); } } } assert(key_pos == key_size); - -done: - if (sorted_items) - Py_DECREF(sorted_items); return key; } @@ -876,42 +866,56 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds } if (self->full && self->root.next != &self->root) { /* Use the oldest item to store the new key and result. */ - PyObject *oldkey, *oldresult; + PyObject *oldkey, *oldresult, *popresult; /* Extricate the oldest item. */ link = self->root.next; lru_cache_extricate_link(link); /* Remove it from the cache. The cache dict holds one reference to the link, and the linked list holds yet one reference to it. */ - if (_PyDict_DelItem_KnownHash(self->cache, link->key, - link->hash) < 0) { + popresult = _PyDict_Pop_KnownHash(self->cache, + link->key, link->hash, + Py_None); + if (popresult == Py_None) { + /* Getting here means that this same key was added to the + cache while the lock was released. Since the link + update is already done, we need only return the + computed result and update the count of misses. */ + Py_DECREF(popresult); + Py_DECREF(link); + Py_DECREF(key); + } + else if (popresult == NULL) { lru_cache_append_link(self, link); Py_DECREF(key); Py_DECREF(result); return NULL; } - /* Keep a reference to the old key and old result to - prevent their ref counts from going to zero during the - update. That will prevent potentially arbitrary object - clean-up code (i.e. __del__) from running while we're - still adjusting the links. */ - oldkey = link->key; - oldresult = link->result; - - link->hash = hash; - link->key = key; - link->result = result; - if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, - hash) < 0) { - Py_DECREF(link); + else { + Py_DECREF(popresult); + /* Keep a reference to the old key and old result to + prevent their ref counts from going to zero during the + update. That will prevent potentially arbitrary object + clean-up code (i.e. __del__) from running while we're + still adjusting the links. */ + oldkey = link->key; + oldresult = link->result; + + link->hash = hash; + link->key = key; + link->result = result; + if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, + hash) < 0) { + Py_DECREF(link); + Py_DECREF(oldkey); + Py_DECREF(oldresult); + return NULL; + } + lru_cache_append_link(self, link); + Py_INCREF(result); /* for return */ Py_DECREF(oldkey); Py_DECREF(oldresult); - return NULL; } - lru_cache_append_link(self, link); - Py_INCREF(result); /* for return */ - Py_DECREF(oldkey); - Py_DECREF(oldresult); } else { /* Put result in a new link at the front of the queue. */ link = (lru_list_elem *)PyObject_GC_New(lru_list_elem, diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 60f8b54..f4d3cbd 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -683,7 +683,7 @@ PyInit__io(void) /* UnsupportedOperation inherits from ValueError and IOError */ state->unsupported_operation = PyObject_CallFunction( (PyObject *)&PyType_Type, "s(OO){}", - "UnsupportedOperation", PyExc_ValueError, PyExc_IOError); + "UnsupportedOperation", PyExc_OSError, PyExc_ValueError); if (state->unsupported_operation == NULL) goto fail; Py_INCREF(state->unsupported_operation); diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 54cfb7f..7f3bcab 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -9,6 +9,9 @@ #ifdef HAVE_SYS_STAT_H #include #endif +#ifdef HAVE_IO_H +#include +#endif #ifdef HAVE_FCNTL_H #include #endif @@ -227,12 +230,13 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, int closefd, PyObject *opener) /*[clinic end generated code: output=23413f68e6484bbd input=193164e293d6c097]*/ { - const char *name = NULL; - PyObject *stringobj = NULL; - const char *s; #ifdef MS_WINDOWS Py_UNICODE *widename = NULL; +#else + const char *name = NULL; #endif + PyObject *stringobj = NULL; + const char *s; int ret = 0; int rwa = 0, plus = 0; int flags = 0; @@ -274,24 +278,21 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, PyErr_Clear(); } + if (fd < 0) { #ifdef MS_WINDOWS - if (PyUnicode_Check(nameobj)) { Py_ssize_t length; - widename = PyUnicode_AsUnicodeAndSize(nameobj, &length); - if (widename == NULL) - return -1; - if (wcslen(widename) != length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); + if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { return -1; } - } else -#endif - if (fd < 0) - { + widename = PyUnicode_AsUnicodeAndSize(stringobj, &length); + if (widename == NULL) + return -1; +#else if (!PyUnicode_FSConverter(nameobj, &stringobj)) { return -1; } name = PyBytes_AS_STRING(stringobj); +#endif } s = mode; @@ -383,11 +384,10 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, do { Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (widename != NULL) - self->fd = _wopen(widename, flags, 0666); - else + self->fd = _wopen(widename, flags, 0666); +#else + self->fd = open(name, flags, 0666); #endif - self->fd = open(name, flags, 0666); Py_END_ALLOW_THREADS } while (self->fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 1c7200b..4df5562 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1012,7 +1012,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, errors); if (self->encoder == NULL) goto error; - /* Get the normalized named of the codec */ + /* Get the normalized name of the codec */ res = _PyObject_GetAttrId(codec_info, &PyId_name); if (res == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 7b00a9e..1d169e2 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -60,51 +60,80 @@ char _get_console_type(HANDLE handle) { } char _PyIO_get_console_type(PyObject *path_or_fd) { - int fd; - - fd = PyLong_AsLong(path_or_fd); + int fd = PyLong_AsLong(path_or_fd); PyErr_Clear(); if (fd >= 0) { HANDLE handle; _Py_BEGIN_SUPPRESS_IPH handle = (HANDLE)_get_osfhandle(fd); _Py_END_SUPPRESS_IPH - if (!handle) + if (handle == INVALID_HANDLE_VALUE) return '\0'; return _get_console_type(handle); } - PyObject *decoded, *decoded_upper; + PyObject *decoded; + wchar_t *decoded_wstr; - int d = PyUnicode_FSDecoder(path_or_fd, &decoded); - if (!d) { + if (!PyUnicode_FSDecoder(path_or_fd, &decoded)) { PyErr_Clear(); return '\0'; } - if (!PyUnicode_Check(decoded)) { - Py_CLEAR(decoded); - return '\0'; - } - decoded_upper = PyObject_CallMethod(decoded, "upper", ""); + decoded_wstr = PyUnicode_AsWideCharString(decoded, NULL); Py_CLEAR(decoded); - if (!decoded_upper) { + if (!decoded_wstr) { PyErr_Clear(); return '\0'; } char m = '\0'; - if (_PyUnicode_EqualToASCIIString(decoded_upper, "CONIN$")) { + if (!_wcsicmp(decoded_wstr, L"CONIN$")) { m = 'r'; - } else if (_PyUnicode_EqualToASCIIString(decoded_upper, "CONOUT$")) { + } else if (!_wcsicmp(decoded_wstr, L"CONOUT$")) { m = 'w'; - } else if (_PyUnicode_EqualToASCIIString(decoded_upper, "CON")) { + } else if (!_wcsicmp(decoded_wstr, L"CON")) { m = 'x'; } + if (m) { + PyMem_Free(decoded_wstr); + return m; + } - Py_CLEAR(decoded_upper); + DWORD length; + wchar_t name_buf[MAX_PATH], *pname_buf = name_buf; + + length = GetFullPathNameW(decoded_wstr, MAX_PATH, pname_buf, NULL); + if (length > MAX_PATH) { + pname_buf = PyMem_New(wchar_t, length); + if (pname_buf) + length = GetFullPathNameW(decoded_wstr, length, pname_buf, NULL); + else + length = 0; + } + PyMem_Free(decoded_wstr); + + if (length) { + wchar_t *name = pname_buf; + if (length >= 4 && name[3] == L'\\' && + (name[2] == L'.' || name[2] == L'?') && + name[1] == L'\\' && name[0] == L'\\') { + name += 4; + } + if (!_wcsicmp(name, L"CONIN$")) { + m = 'r'; + } else if (!_wcsicmp(name, L"CONOUT$")) { + m = 'w'; + } else if (!_wcsicmp(name, L"CON")) { + m = 'x'; + } + } + + if (pname_buf != name_buf) + PyMem_Free(pname_buf); return m; } + /*[clinic input] module _io class _io._WindowsConsoleIO "winconsoleio *" "&PyWindowsConsoleIO_Type" @@ -289,6 +318,11 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, Py_CLEAR(decodedname); if (name == NULL) return -1; + if (console_type == '\0') { + PyErr_SetString(PyExc_ValueError, + "Cannot open non-console file"); + return -1; + } if (wcslen(name) != length) { PyMem_Free(name); @@ -370,6 +404,11 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, if (console_type == '\0') console_type = _get_console_type(self->handle); + if (console_type == '\0') { + PyErr_SetString(PyExc_ValueError, + "Cannot open non-console file"); + goto error; + } if (self->writable && console_type != 'w') { PyErr_SetString(PyExc_ValueError, "Cannot open console input buffer for writing"); diff --git a/Modules/_json.c b/Modules/_json.c index d3dbf98..faa2134 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -845,14 +845,16 @@ _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssi int kind; Py_ssize_t end_idx; PyObject *val = NULL; - PyObject *rval = PyList_New(0); + PyObject *rval; Py_ssize_t next_idx; - if (rval == NULL) - return NULL; if (PyUnicode_READY(pystr) == -1) return NULL; + rval = PyList_New(0); + if (rval == NULL) + return NULL; + str = PyUnicode_DATA(pystr); kind = PyUnicode_KIND(pystr); end_idx = PyUnicode_GET_LENGTH(pystr) - 1; @@ -1559,8 +1561,11 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, return -1; } - if (Py_EnterRecursiveCall(" while encoding a JSON object")) + if (Py_EnterRecursiveCall(" while encoding a JSON object")) { + Py_DECREF(newobj); + Py_XDECREF(ident); return -1; + } rv = encoder_listencode_obj(s, acc, newobj, indent_level); Py_LeaveRecursiveCall(); @@ -1604,7 +1609,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) return -1; } - if (Py_SIZE(dct) == 0) + if (PyDict_Size(dct) == 0) /* Fast path */ return _PyAccu_Accumulate(acc, empty_dict); if (s->markers != Py_None) { diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 79113e0..920b46f 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -1560,9 +1560,9 @@ memo_put(PicklerObject *self, PyObject *obj) } static PyObject * -get_dotted_path(PyObject *obj, PyObject *name) { +get_dotted_path(PyObject *obj, PyObject *name) +{ _Py_static_string(PyId_dot, "."); - _Py_static_string(PyId_locals, ""); PyObject *dotted_path; Py_ssize_t i, n; @@ -1573,12 +1573,7 @@ get_dotted_path(PyObject *obj, PyObject *name) { assert(n >= 1); for (i = 0; i < n; i++) { PyObject *subpath = PyList_GET_ITEM(dotted_path, i); - PyObject *result = PyUnicode_RichCompare( - subpath, _PyUnicode_FromId(&PyId_locals), Py_EQ); - int is_equal = (result == Py_True); - assert(PyBool_Check(result)); - Py_DECREF(result); - if (is_equal) { + if (_PyUnicode_EqualToASCIIString(subpath, "")) { if (obj == NULL) PyErr_Format(PyExc_AttributeError, "Can't pickle local object %R", name); @@ -3552,12 +3547,11 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) } else if (PyUnicode_Check(name)) { _Py_IDENTIFIER(__newobj_ex__); - use_newobj_ex = PyUnicode_Compare( - name, _PyUnicode_FromId(&PyId___newobj_ex__)) == 0; + use_newobj_ex = _PyUnicode_EqualToASCIIId( + name, &PyId___newobj_ex__); if (!use_newobj_ex) { _Py_IDENTIFIER(__newobj__); - use_newobj = PyUnicode_Compare( - name, _PyUnicode_FromId(&PyId___newobj__)) == 0; + use_newobj = _PyUnicode_EqualToASCIIId(name, &PyId___newobj__); } } Py_XDECREF(name); diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 63759d5..e5dd2c9 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------ The code in this module was based on a download from: - http://www.math.keio.ac.jp/~matumoto/MT2002/emt19937ar.html + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html It was modified in 2002 by Raymond Hettinger as follows: @@ -60,8 +60,8 @@ Any feedback is very welcome. - http://www.math.keio.ac.jp/matumoto/emt.html - email: matumoto@math.keio.ac.jp + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) */ /* ---------------------------------------------------------------*/ @@ -245,7 +245,7 @@ random_seed(RandomObject *self, PyObject *args) return NULL; if (arg == NULL || arg == Py_None) { - if (random_seed_urandom(self) >= 0) { + if (random_seed_urandom(self) < 0) { PyErr_Clear(); /* Reading system entropy failed, fall back on the worst entropy: diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 39f7a65..8341fb8 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -511,10 +511,9 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* pysqlite_statement_reset(self->statement); pysqlite_statement_mark_dirty(self->statement); - /* For backwards compatibility reasons, do not start a transaction if a - DDL statement is encountered. If anybody wants transactional DDL, - they can issue a BEGIN statement manually. */ - if (self->connection->begin_statement && !sqlite3_stmt_readonly(self->statement->st) && !self->statement->is_ddl) { + /* We start a transaction implicitly before a DML statement. + SELECT is the only exception. See #9924. */ + if (self->connection->begin_statement && self->statement->is_dml) { if (sqlite3_get_autocommit(self->connection->db)) { result = _pysqlite_connection_begin(self->connection); if (!result) { @@ -609,7 +608,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* } } - if (!sqlite3_stmt_readonly(self->statement->st)) { + if (self->statement->is_dml) { self->rowcount += (long)sqlite3_changes(self->connection->db); } else { self->rowcount= -1L; diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 0df661b..087375b 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -73,8 +73,9 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con Py_INCREF(sql); self->sql = sql; - /* determine if the statement is a DDL statement */ - self->is_ddl = 0; + /* Determine if the statement is a DML statement. + SELECT is the only exception. See #9924. */ + self->is_dml = 0; for (p = sql_cstr; *p != 0; p++) { switch (*p) { case ' ': @@ -84,9 +85,10 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con continue; } - self->is_ddl = (PyOS_strnicmp(p, "create ", 7) == 0) - || (PyOS_strnicmp(p, "drop ", 5) == 0) - || (PyOS_strnicmp(p, "reindex ", 8) == 0); + self->is_dml = (PyOS_strnicmp(p, "insert ", 7) == 0) + || (PyOS_strnicmp(p, "update ", 7) == 0) + || (PyOS_strnicmp(p, "delete ", 7) == 0) + || (PyOS_strnicmp(p, "replace ", 8) == 0); break; } diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index 6eef168..8db10f6 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -38,7 +38,7 @@ typedef struct sqlite3_stmt* st; PyObject* sql; int in_use; - int is_ddl; + int is_dml; PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Statement; diff --git a/Modules/_sre.c b/Modules/_sre.c index 979e61f..d092496 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2003,6 +2003,7 @@ match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def) Py_buffer view; PyObject *result; void* ptr; + Py_ssize_t i, j; if (index < 0 || index >= self->groups) { /* raise IndexError if we were given a bad group number */ @@ -2024,8 +2025,12 @@ match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def) ptr = getstring(self->string, &length, &isbytes, &charsize, &view); if (ptr == NULL) return NULL; - result = getslice(isbytes, ptr, - self->string, self->mark[index], self->mark[index+1]); + + i = self->mark[index]; + j = self->mark[index+1]; + i = Py_MIN(i, length); + j = Py_MIN(j, length); + result = getslice(isbytes, ptr, self->string, i, j); if (isbytes && view.buf != NULL) PyBuffer_Release(&view); return result; diff --git a/Modules/_ssl.c b/Modules/_ssl.c index b198857..c0a7b8e 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2729,12 +2729,12 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) #endif -#ifndef OPENSSL_NO_ECDH +#if !defined(OPENSSL_NO_ECDH) && !defined(OPENSSL_VERSION_1_1) /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use prime256v1 by default. This is Apache mod_ssl's initialization policy, so we should be safe. OpenSSL 1.1 has it enabled by default. */ -#if defined(SSL_CTX_set_ecdh_auto) && !defined(OPENSSL_VERSION_1_1) +#if defined(SSL_CTX_set_ecdh_auto) SSL_CTX_set_ecdh_auto(self->ctx, 1); #else { diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 13d3ccc..4e1ce68 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -13,7 +13,7 @@ PyObject *Struct = NULL; PyObject *calcsize = NULL; /* cache simple format string */ -static const char simple_fmt[] = "B"; +static const char *simple_fmt = "B"; PyObject *simple_format = NULL; #define SIMPLE_FORMAT(fmt) (fmt == NULL || strcmp(fmt, "B") == 0) #define FIX_FORMAT(fmt) (fmt == NULL ? "B" : fmt) @@ -850,6 +850,7 @@ seq_as_ssize_array(PyObject *seq, Py_ssize_t len, int is_shape) Py_ssize_t *dest; Py_ssize_t x, i; + /* ndim = len <= ND_MAX_NDIM, so PyMem_New() is actually not needed. */ dest = PyMem_New(Py_ssize_t, len); if (dest == NULL) { PyErr_NoMemory(); diff --git a/Modules/_weakref.c b/Modules/_weakref.c index 805d6d0..f9c68d6 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -35,6 +35,46 @@ _weakref_getweakrefcount_impl(PyObject *module, PyObject *object) } +static int +is_dead_weakref(PyObject *value) +{ + if (!PyWeakref_Check(value)) { + PyErr_SetString(PyExc_TypeError, "not a weakref"); + return -1; + } + return PyWeakref_GET_OBJECT(value) == Py_None; +} + +/*[clinic input] + +_weakref._remove_dead_weakref -> object + + dct: object(subclass_of='&PyDict_Type') + key: object + / + +Atomically remove key from dict if it points to a dead weakref. +[clinic start generated code]*/ + +static PyObject * +_weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, + PyObject *key) +/*[clinic end generated code: output=d9ff53061fcb875c input=19fc91f257f96a1d]*/ +{ + if (_PyDict_DelItemIf(dct, key, is_dead_weakref) < 0) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) + /* This function is meant to allow safe weak-value dicts + with GC in another thread (see issue #28427), so it's + ok if the key doesn't exist anymore. + */ + PyErr_Clear(); + else + return NULL; + } + Py_RETURN_NONE; +} + + PyDoc_STRVAR(weakref_getweakrefs__doc__, "getweakrefs(object) -- return a list of all weak reference objects\n" "that point to 'object'."); @@ -88,6 +128,7 @@ weakref_proxy(PyObject *self, PyObject *args) static PyMethodDef weakref_functions[] = { _WEAKREF_GETWEAKREFCOUNT_METHODDEF + _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF {"getweakrefs", weakref_getweakrefs, METH_O, weakref_getweakrefs__doc__}, {"proxy", weakref_proxy, METH_VARARGS, diff --git a/Modules/binascii.c b/Modules/binascii.c index 9b9cd7f..ee66a48 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -900,12 +900,12 @@ binascii.crc_hqx -> unsigned_int crc: unsigned_int(bitwise=True) / -Compute hqx CRC incrementally. +Compute CRC-CCITT incrementally. [clinic start generated code]*/ static unsigned int binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc) -/*[clinic end generated code: output=8ec2a78590d19170 input=add8c53712ccceda]*/ +/*[clinic end generated code: output=8ec2a78590d19170 input=f18240ff8c705b79]*/ { const unsigned char *bin_data; Py_ssize_t len; diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 052d252..41f11f4 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -278,7 +278,7 @@ _asyncio_Task_current_task(PyTypeObject *type, PyObject **args, Py_ssize_t nargs PyObject *return_value = NULL; static const char * const _keywords[] = {"loop", NULL}; static _PyArg_Parser _parser = {"|O:current_task", _keywords, 0}; - PyObject *loop = NULL; + PyObject *loop = Py_None; if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser, &loop)) { @@ -310,7 +310,7 @@ _asyncio_Task_all_tasks(PyTypeObject *type, PyObject **args, Py_ssize_t nargs, P PyObject *return_value = NULL; static const char * const _keywords[] = {"loop", NULL}; static _PyArg_Parser _parser = {"|O:all_tasks", _keywords, 0}; - PyObject *loop = NULL; + PyObject *loop = Py_None; if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser, &loop)) { @@ -517,4 +517,4 @@ _asyncio_Task__wakeup(TaskObj *self, PyObject **args, Py_ssize_t nargs, PyObject exit: return return_value; } -/*[clinic end generated code: output=8f036321bb083066 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=40ca6c9da517da73 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index c192e72..ab84c30 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -29,4 +29,34 @@ _weakref_getweakrefcount(PyObject *module, PyObject *object) exit: return return_value; } -/*[clinic end generated code: output=e1ad587147323e19 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_weakref__remove_dead_weakref__doc__, +"_remove_dead_weakref($module, dct, key, /)\n" +"--\n" +"\n" +"Atomically remove key from dict if it points to a dead weakref."); + +#define _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF \ + {"_remove_dead_weakref", (PyCFunction)_weakref__remove_dead_weakref, METH_VARARGS, _weakref__remove_dead_weakref__doc__}, + +static PyObject * +_weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, + PyObject *key); + +static PyObject * +_weakref__remove_dead_weakref(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *dct; + PyObject *key; + + if (!PyArg_ParseTuple(args, "O!O:_remove_dead_weakref", + &PyDict_Type, &dct, &key)) { + goto exit; + } + return_value = _weakref__remove_dead_weakref_impl(module, dct, key); + +exit: + return return_value; +} +/*[clinic end generated code: output=e860dd818a44bc9b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index acafcbf..743bf46 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -263,7 +263,7 @@ PyDoc_STRVAR(binascii_crc_hqx__doc__, "crc_hqx($module, data, crc, /)\n" "--\n" "\n" -"Compute hqx CRC incrementally."); +"Compute CRC-CCITT incrementally."); #define BINASCII_CRC_HQX_METHODDEF \ {"crc_hqx", (PyCFunction)binascii_crc_hqx, METH_VARARGS, binascii_crc_hqx__doc__}, @@ -550,4 +550,4 @@ exit: return return_value; } -/*[clinic end generated code: output=1f8d6e48f75f6d1e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=458eb09731cb7877 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index f63a3be..0d3ce6e 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -9,7 +9,8 @@ PyDoc_STRVAR(os_stat__doc__, "Perform a stat system call on the given path.\n" "\n" " path\n" -" Path to be examined; can be string, bytes, or open-file-descriptor int.\n" +" Path to be examined; can be string, bytes, path-like object or\n" +" open-file-descriptor int.\n" " dir_fd\n" " If not None, it should be a file descriptor open to a directory,\n" " and path should be a relative string; path will then be relative to\n" @@ -6149,4 +6150,4 @@ exit: #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=50cfb7ebc44efb67 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=455def991740915a input=a9049054013a1b77]*/ diff --git a/Modules/getbuildinfo.c b/Modules/getbuildinfo.c index 0971a64..5f941a2 100644 --- a/Modules/getbuildinfo.c +++ b/Modules/getbuildinfo.c @@ -21,47 +21,47 @@ #endif /* XXX Only unix build process has been tested */ -#ifndef HGVERSION -#define HGVERSION "" +#ifndef GITVERSION +#define GITVERSION "" #endif -#ifndef HGTAG -#define HGTAG "" +#ifndef GITTAG +#define GITTAG "" #endif -#ifndef HGBRANCH -#define HGBRANCH "" +#ifndef GITBRANCH +#define GITBRANCH "" #endif const char * Py_GetBuildInfo(void) { - static char buildinfo[50 + sizeof(HGVERSION) + - ((sizeof(HGTAG) > sizeof(HGBRANCH)) ? - sizeof(HGTAG) : sizeof(HGBRANCH))]; - const char *revision = _Py_hgversion(); + static char buildinfo[50 + sizeof(GITVERSION) + + ((sizeof(GITTAG) > sizeof(GITBRANCH)) ? + sizeof(GITTAG) : sizeof(GITBRANCH))]; + const char *revision = _Py_gitversion(); const char *sep = *revision ? ":" : ""; - const char *hgid = _Py_hgidentifier(); - if (!(*hgid)) - hgid = "default"; + const char *gitid = _Py_gitidentifier(); + if (!(*gitid)) + gitid = "default"; PyOS_snprintf(buildinfo, sizeof(buildinfo), - "%s%s%s, %.20s, %.9s", hgid, sep, revision, + "%s%s%s, %.20s, %.9s", gitid, sep, revision, DATE, TIME); return buildinfo; } const char * -_Py_hgversion(void) +_Py_gitversion(void) { - return HGVERSION; + return GITVERSION; } const char * -_Py_hgidentifier(void) +_Py_gitidentifier(void) { - const char *hgtag, *hgid; - hgtag = HGTAG; - if ((*hgtag) && strcmp(hgtag, "tip") != 0) - hgid = hgtag; + const char *gittag, *gitid; + gittag = GITTAG; + if ((*gittag) && strcmp(gittag, "undefined") != 0) + gitid = gittag; else - hgid = HGBRANCH; - return hgid; + gitid = GITBRANCH; + return gitid; } diff --git a/Modules/main.c b/Modules/main.c index d75f64a..dd50211 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -7,6 +7,9 @@ #if defined(MS_WINDOWS) || defined(__CYGWIN__) #include +#ifdef HAVE_IO_H +#include +#endif #ifdef HAVE_FCNTL_H #include #endif @@ -222,45 +225,60 @@ static int RunModule(wchar_t *modname, int set_argv0) return 0; } -static int -RunMainFromImporter(wchar_t *filename) +static PyObject * +AsImportPathEntry(wchar_t *filename) { - PyObject *argv0 = NULL, *importer, *sys_path; - int sts; + PyObject *sys_path0 = NULL, *importer; - argv0 = PyUnicode_FromWideChar(filename, wcslen(filename)); - if (argv0 == NULL) + sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename)); + if (sys_path0 == NULL) goto error; - importer = PyImport_GetImporter(argv0); + importer = PyImport_GetImporter(sys_path0); if (importer == NULL) goto error; if (importer == Py_None) { - Py_DECREF(argv0); + Py_DECREF(sys_path0); Py_DECREF(importer); - return -1; + return NULL; } Py_DECREF(importer); + return sys_path0; + +error: + Py_XDECREF(sys_path0); + PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n"); + PyErr_Print(); + PyErr_Clear(); + return NULL; +} - /* argv0 is usable as an import source, so put it in sys.path[0] - and import __main__ */ + +static int +RunMainFromImporter(PyObject *sys_path0) +{ + PyObject *sys_path; + int sts; + + /* Assume sys_path0 has already been checked by AsImportPathEntry, + * so put it in sys.path[0] and import __main__ */ sys_path = PySys_GetObject("path"); if (sys_path == NULL) { PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path"); goto error; } - if (PyList_SetItem(sys_path, 0, argv0)) { - argv0 = NULL; + sts = PyList_Insert(sys_path, 0, sys_path0); + if (sts) { + sys_path0 = NULL; goto error; } - Py_INCREF(argv0); sts = RunModule(L"__main__", 0); return sts != 0; error: - Py_XDECREF(argv0); + Py_XDECREF(sys_path0); PyErr_Print(); return 1; } @@ -345,6 +363,7 @@ Py_Main(int argc, wchar_t **argv) int saw_unbuffered_flag = 0; char *opt; PyCompilerFlags cf; + PyObject *main_importer_path = NULL; PyObject *warning_option = NULL; PyObject *warning_options = NULL; @@ -701,7 +720,17 @@ Py_Main(int argc, wchar_t **argv) argv[_PyOS_optind] = L"-m"; } - PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); + if (filename != NULL) { + main_importer_path = AsImportPathEntry(filename); + } + + if (main_importer_path != NULL) { + /* Let RunMainFromImporter adjust sys.path[0] later */ + PySys_SetArgvEx(argc-_PyOS_optind, argv+_PyOS_optind, 0); + } else { + /* Use config settings to decide whether or not to update sys.path[0] */ + PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); + } if ((Py_InspectFlag || (command == NULL && filename == NULL && module == NULL)) && isatty(fileno(stdin)) && @@ -731,11 +760,11 @@ Py_Main(int argc, wchar_t **argv) sts = -1; /* keep track of whether we've already run __main__ */ - if (filename != NULL) { - sts = RunMainFromImporter(filename); + if (main_importer_path != NULL) { + sts = RunMainFromImporter(main_importer_path); } - if (sts==-1 && filename!=NULL) { + if (sts==-1 && filename != NULL) { fp = _Py_wfopen(filename, L"r"); if (fp == NULL) { char *cfilename_buffer; diff --git a/Modules/makesetup b/Modules/makesetup index e204a05..8db8de8 100755 --- a/Modules/makesetup +++ b/Modules/makesetup @@ -259,7 +259,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | for mod in $MODS do EXTDECLS="${EXTDECLS}extern PyObject* PyInit_$mod(void);$NL" - INITBITS="${INITBITS} {\"$mod\", PyInit_$mod},$NL" + INITBITS="${INITBITS} {\"$mod\", PyInit_$mod},$NL" done diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index ae25102..8f8ba25 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -785,7 +785,9 @@ dir_fd_converter(PyObject *o, void *p) * The length of the path in characters, if specified as * a string. * path.object - * The original object passed in. + * The original object passed in (if get a PathLike object, + * the result of PyOS_FSPath() is treated as the original object). + * Own a reference to the object. * path.cleanup * For internal use only. May point to a temporary object. * (Pay no attention to the man behind the curtain.) @@ -836,24 +838,22 @@ typedef struct { #endif static void -path_cleanup(path_t *path) { - if (path->cleanup) { - Py_CLEAR(path->cleanup); - } +path_cleanup(path_t *path) +{ + Py_CLEAR(path->object); + Py_CLEAR(path->cleanup); } static int path_converter(PyObject *o, void *p) { path_t *path = (path_t *)p; - PyObject *bytes, *to_cleanup = NULL; - Py_ssize_t length; + PyObject *bytes = NULL; + Py_ssize_t length = 0; int is_index, is_buffer, is_bytes, is_unicode; - /* Default to failure, forcing explicit signaling of succcess. */ - int ret = 0; const char *narrow; #ifdef MS_WINDOWS - PyObject *wo; + PyObject *wo = NULL; const wchar_t *wide; #endif @@ -870,7 +870,9 @@ path_converter(PyObject *o, void *p) } /* Ensure it's always safe to call path_cleanup(). */ - path->cleanup = NULL; + path->object = path->cleanup = NULL; + /* path->object owns a reference to the original object */ + Py_INCREF(o); if ((o == Py_None) && path->nullable) { path->wide = NULL; @@ -879,10 +881,8 @@ path_converter(PyObject *o, void *p) #else path->narrow = NULL; #endif - path->length = 0; - path->object = o; path->fd = -1; - return 1; + goto success_exit; } /* Only call this here so that we don't treat the return value of @@ -899,10 +899,11 @@ path_converter(PyObject *o, void *p) func = _PyObject_LookupSpecial(o, &PyId___fspath__); if (NULL == func) { - goto error_exit; + goto error_format; } - - o = to_cleanup = PyObject_CallFunctionObjArgs(func, NULL); + /* still owns a reference to the original object */ + Py_DECREF(o); + o = _PyObject_CallNoArg(func); Py_DECREF(func); if (NULL == o) { goto error_exit; @@ -914,7 +915,7 @@ path_converter(PyObject *o, void *p) is_bytes = 1; } else { - goto error_exit; + goto error_format; } } @@ -922,26 +923,24 @@ path_converter(PyObject *o, void *p) #ifdef MS_WINDOWS wide = PyUnicode_AsUnicodeAndSize(o, &length); if (!wide) { - goto exit; + goto error_exit; } if (length > 32767) { FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); - goto exit; + goto error_exit; } if (wcslen(wide) != length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); - goto exit; + goto error_exit; } path->wide = wide; - path->length = length; - path->object = o; + path->narrow = FALSE; path->fd = -1; - ret = 1; - goto exit; + goto success_exit; #else if (!PyUnicode_FSConverter(o, &bytes)) { - goto exit; + goto error_exit; } #endif } @@ -961,16 +960,16 @@ path_converter(PyObject *o, void *p) path->nullable ? "string, bytes, os.PathLike or None" : "string, bytes or os.PathLike", Py_TYPE(o)->tp_name)) { - goto exit; + goto error_exit; } bytes = PyBytes_FromObject(o); if (!bytes) { - goto exit; + goto error_exit; } } else if (is_index) { if (!_fd_converter(o, &path->fd)) { - goto exit; + goto error_exit; } path->wide = NULL; #ifdef MS_WINDOWS @@ -978,13 +977,10 @@ path_converter(PyObject *o, void *p) #else path->narrow = NULL; #endif - path->length = 0; - path->object = o; - ret = 1; - goto exit; + goto success_exit; } else { - error_exit: + error_format: PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s", path->function_name ? path->function_name : "", path->function_name ? ": " : "", @@ -995,15 +991,14 @@ path_converter(PyObject *o, void *p) path->nullable ? "string, bytes, os.PathLike or None" : "string, bytes or os.PathLike", Py_TYPE(o)->tp_name); - goto exit; + goto error_exit; } length = PyBytes_GET_SIZE(bytes); narrow = PyBytes_AS_STRING(bytes); if ((size_t)length != strlen(narrow)) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); - Py_DECREF(bytes); - goto exit; + goto error_exit; } #ifdef MS_WINDOWS @@ -1012,43 +1007,51 @@ path_converter(PyObject *o, void *p) length ); if (!wo) { - goto exit; + goto error_exit; } - wide = PyUnicode_AsWideCharString(wo, &length); - Py_DECREF(wo); - + wide = PyUnicode_AsUnicodeAndSize(wo, &length); if (!wide) { - goto exit; + goto error_exit; } if (length > 32767) { FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); - goto exit; + goto error_exit; } if (wcslen(wide) != length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); - goto exit; + goto error_exit; } path->wide = wide; path->narrow = TRUE; + path->cleanup = wo; + Py_DECREF(bytes); #else path->wide = NULL; path->narrow = narrow; -#endif - path->length = length; - path->object = o; - path->fd = -1; if (bytes == o) { + /* Still a reference owned by path->object, don't have to + worry about path->narrow is used after free. */ Py_DECREF(bytes); - ret = 1; } else { path->cleanup = bytes; - ret = Py_CLEANUP_SUPPORTED; } - exit: - Py_XDECREF(to_cleanup); - return ret; +#endif + path->fd = -1; + + success_exit: + path->length = length; + path->object = o; + return Py_CLEANUP_SUPPORTED; + + error_exit: + Py_XDECREF(o); + Py_XDECREF(bytes); +#ifdef MS_WINDOWS + Py_XDECREF(wo); +#endif + return 0; } static void @@ -2383,7 +2386,8 @@ class sched_param_converter(CConverter): os.stat path : path_t(allow_fd=True) - Path to be examined; can be string, bytes, or open-file-descriptor int. + Path to be examined; can be string, bytes, path-like object or + open-file-descriptor int. * @@ -2410,7 +2414,7 @@ It's an error to use dir_fd or follow_symlinks when specifying path as static PyObject * os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/ +/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/ { return posix_do_stat("stat", path, dir_fd, follow_symlinks); } @@ -11861,7 +11865,6 @@ ScandirIterator_finalize(ScandirIterator *iterator) } } - Py_CLEAR(iterator->path.object); path_cleanup(&iterator->path); /* Restore the saved exception. */ @@ -11965,12 +11968,6 @@ posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs) path_converter, &iterator->path)) goto error; - /* path_converter doesn't keep path.object around, so do it - manually for the lifetime of the iterator here (the refcount - is decremented in ScandirIterator_dealloc) - */ - Py_XINCREF(iterator->path.object); - #ifdef MS_WINDOWS iterator->first_time = 1; diff --git a/Modules/resource.c b/Modules/resource.c index 6702b7a..113ad5c 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -107,29 +107,46 @@ resource_getrusage(PyObject *self, PyObject *args) } static int -py2rlimit(PyObject *curobj, PyObject *maxobj, struct rlimit *rl_out) +py2rlimit(PyObject *limits, struct rlimit *rl_out) { + PyObject *curobj, *maxobj; + limits = PySequence_Tuple(limits); + if (!limits) + /* Here limits is a borrowed reference */ + return -1; + + if (PyTuple_GET_SIZE(limits) != 2) { + PyErr_SetString(PyExc_ValueError, + "expected a tuple of 2 integers"); + goto error; + } + curobj = PyTuple_GET_ITEM(limits, 0); + maxobj = PyTuple_GET_ITEM(limits, 1); #if !defined(HAVE_LARGEFILE_SUPPORT) rl_out->rlim_cur = PyLong_AsLong(curobj); if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) - return -1; + goto error; rl_out->rlim_max = PyLong_AsLong(maxobj); if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred()) - return -1; + goto error; #else /* The limits are probably bigger than a long */ rl_out->rlim_cur = PyLong_AsLongLong(curobj); if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) - return -1; + goto error; rl_out->rlim_max = PyLong_AsLongLong(maxobj); if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred()) - return -1; + goto error; #endif + Py_DECREF(limits); rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY; rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY; return 0; +error: + Py_DECREF(limits); + return -1; } static PyObject* @@ -170,7 +187,7 @@ resource_setrlimit(PyObject *self, PyObject *args) { struct rlimit rl; int resource; - PyObject *limits, *curobj, *maxobj; + PyObject *limits; if (!PyArg_ParseTuple(args, "iO:setrlimit", &resource, &limits)) return NULL; @@ -181,21 +198,8 @@ resource_setrlimit(PyObject *self, PyObject *args) return NULL; } - limits = PySequence_Tuple(limits); - if (!limits) - /* Here limits is a borrowed reference */ + if (py2rlimit(limits, &rl) < 0) { return NULL; - - if (PyTuple_GET_SIZE(limits) != 2) { - PyErr_SetString(PyExc_ValueError, - "expected a tuple of 2 integers"); - goto error; - } - curobj = PyTuple_GET_ITEM(limits, 0); - maxobj = PyTuple_GET_ITEM(limits, 1); - - if (py2rlimit(curobj, maxobj, &rl) < 0) { - goto error; } if (setrlimit(resource, &rl) == -1) { @@ -207,15 +211,9 @@ resource_setrlimit(PyObject *self, PyObject *args) "not allowed to raise maximum limit"); else PyErr_SetFromErrno(PyExc_OSError); - goto error; + return NULL; } - Py_DECREF(limits); - Py_INCREF(Py_None); - return Py_None; - - error: - Py_DECREF(limits); - return NULL; + Py_RETURN_NONE; } #ifdef HAVE_PRLIMIT @@ -225,10 +223,10 @@ resource_prlimit(PyObject *self, PyObject *args) struct rlimit old_limit, new_limit; int resource, retval; pid_t pid; - PyObject *curobj=NULL, *maxobj=NULL; + PyObject *limits = NULL; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i|(OO):prlimit", - &pid, &resource, &curobj, &maxobj)) + if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i|O:prlimit", + &pid, &resource, &limits)) return NULL; if (resource < 0 || resource >= RLIM_NLIMITS) { @@ -237,8 +235,8 @@ resource_prlimit(PyObject *self, PyObject *args) return NULL; } - if (curobj != NULL) { - if (py2rlimit(curobj, maxobj, &new_limit) < 0) { + if (limits != NULL) { + if (py2rlimit(limits, &new_limit) < 0) { return NULL; } retval = prlimit(pid, resource, &new_limit, &old_limit); diff --git a/Modules/timemodule.c b/Modules/timemodule.c index db0ab58..ebd44ad 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -398,7 +398,7 @@ time_localtime(PyObject *self, PyObject *args) struct tm local = buf; char zone[100]; int gmtoff; - strftime(zone, sizeof(buf), "%Z", &buf); + strftime(zone, sizeof(zone), "%Z", &buf); gmtoff = timegm(&buf) - when; return tmtotuple(&local, zone, gmtoff); } diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index c1a9be9..5041ac8 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -31,7 +31,7 @@ static XxoObject * newXxoObject(PyObject *arg) { XxoObject *self; - self = PyObject_New(XxoObject, (PyTypeObject*)Xxo_Type); + self = PyObject_GC_New(XxoObject, (PyTypeObject*)Xxo_Type); if (self == NULL) return NULL; self->x_attr = NULL; diff --git a/Modules/zlib/ChangeLog b/Modules/zlib/ChangeLog index f22aaba..30199a6 100644 --- a/Modules/zlib/ChangeLog +++ b/Modules/zlib/ChangeLog @@ -1,10 +1,53 @@ ChangeLog file for zlib +Changes in 1.2.11 (15 Jan 2017) +- Fix deflate stored bug when pulling last block from window +- Permit immediate deflateParams changes before any deflate input + +Changes in 1.2.10 (2 Jan 2017) +- Avoid warnings on snprintf() return value +- Fix bug in deflate_stored() for zero-length input +- Fix bug in gzwrite.c that produced corrupt gzip files +- Remove files to be installed before copying them in Makefile.in +- Add warnings when compiling with assembler code + +Changes in 1.2.9 (31 Dec 2016) +- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] +- Improve contrib/blast to return unused bytes +- Assure that gzoffset() is correct when appending +- Improve compress() and uncompress() to support large lengths +- Fix bug in test/example.c where error code not saved +- Remedy Coverity warning [Randers-Pehrson] +- Improve speed of gzprintf() in transparent mode +- Fix inflateInit2() bug when windowBits is 16 or 32 +- Change DEBUG macro to ZLIB_DEBUG +- Avoid uninitialized access by gzclose_w() +- Allow building zlib outside of the source directory +- Fix bug that accepted invalid zlib header when windowBits is zero +- Fix gzseek() problem on MinGW due to buggy _lseeki64 there +- Loop on write() calls in gzwrite.c in case of non-blocking I/O +- Add --warn (-w) option to ./configure for more compiler warnings +- Reject a window size of 256 bytes if not using the zlib wrapper +- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE +- Add --debug (-d) option to ./configure to define ZLIB_DEBUG +- Fix bugs in creating a very large gzip header +- Add uncompress2() function, which returns the input size used +- Assure that deflateParams() will not switch functions mid-block +- Dramatically speed up deflation for level 0 (storing) +- Add gzfread(), duplicating the interface of fread() +- Add gzfwrite(), duplicating the interface of fwrite() +- Add deflateGetDictionary() function +- Use snprintf() for later versions of Microsoft C +- Fix *Init macros to use z_ prefix when requested +- Replace as400 with os400 for OS/400 support [Monnerat] +- Add crc32_z() and adler32_z() functions with size_t lengths +- Update Visual Studio project files [AraHaan] + Changes in 1.2.8 (28 Apr 2013) - Update contrib/minizip/iowin32.c for Windows RT [Vollant] - Do not force Z_CONST for C++ -- Clean up contrib/vstudio [Ro§] +- Clean up contrib/vstudio [Roß] - Correct spelling error in zlib.h - Fix mixed line endings in contrib/vstudio @@ -34,7 +77,7 @@ Changes in 1.2.7.1 (24 Mar 2013) - Clean up the usage of z_const and respect const usage within zlib - Clean up examples/gzlog.[ch] comparisons of different types - Avoid shift equal to bits in type (caused endless loop) -- Fix unintialized value bug in gzputc() introduced by const patches +- Fix uninitialized value bug in gzputc() introduced by const patches - Fix memory allocation error in examples/zran.c [Nor] - Fix bug where gzopen(), gzclose() would write an empty file - Fix bug in gzclose() when gzwrite() runs out of memory @@ -194,7 +237,7 @@ Changes in 1.2.5.2 (17 Dec 2011) - Add a transparent write mode to gzopen() when 'T' is in the mode - Update python link in zlib man page - Get inffixed.h and MAKEFIXED result to match -- Add a ./config --solo option to make zlib subset with no libary use +- Add a ./config --solo option to make zlib subset with no library use - Add undocumented inflateResetKeep() function for CAB file decoding - Add --cover option to ./configure for gcc coverage testing - Add #define ZLIB_CONST option to use const in the z_stream interface @@ -564,7 +607,7 @@ Changes in 1.2.3.1 (16 August 2006) - Update make_vms.com [Zinser] - Use -fPIC for shared build in configure [Teredesai, Nicholson] - Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] -- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] - Add some FAQ entries about the contrib directory - Update the MVS question in the FAQ - Avoid extraneous reads after EOF in gzio.c [Brown] @@ -1178,7 +1221,7 @@ Changes in 1.0.6 (19 Jan 1998) 386 asm code replacing longest_match(). contrib/iostream/ by Kevin Ruland A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge Løvset + contrib/iostream2/ by Tyge Løvset Another C++ I/O streams interface contrib/untgz/ by "Pedro A. Aranda Guti\irrez" A very simple tar.gz file extractor using zlib @@ -1267,7 +1310,7 @@ Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] - fix array overlay in deflate.c which sometimes caused bad compressed data - fix inflate bug with empty stored block - fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generated bad compressed data. +- fix deflateParams() which could generate bad compressed data. - Bytef is define'd instead of typedef'ed (work around Borland bug) - added an INDEX file - new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), diff --git a/Modules/zlib/Makefile.in b/Modules/zlib/Makefile.in index c61aa30..1852192 100644 --- a/Modules/zlib/Makefile.in +++ b/Modules/zlib/Makefile.in @@ -1,5 +1,5 @@ # Makefile for zlib -# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler # For conditions of distribution and use, see copyright notice in zlib.h # To compile and test, type: @@ -20,7 +20,7 @@ CC=cc CFLAGS=-O #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DDEBUG +#CFLAGS=-g -DZLIB_DEBUG #CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ # -Wstrict-prototypes -Wmissing-prototypes @@ -32,7 +32,7 @@ CPP=$(CC) -E STATICLIB=libz.a SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.8 +SHAREDLIBV=libz.so.1.2.10 SHAREDLIBM=libz.so.1 LIBS=$(STATICLIB) $(SHAREDLIBV) @@ -53,6 +53,9 @@ includedir = ${prefix}/include mandir = ${prefix}/share/man man3dir = ${mandir}/man3 pkgconfigdir = ${libdir}/pkgconfig +SRCDIR= +ZINC= +ZINCOUT=-I. OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o @@ -113,8 +116,8 @@ test64: all64 fi; \ rm -f $$TMP64 -infcover.o: test/infcover.c zlib.h zconf.h - $(CC) $(CFLAGS) -I. -c -o $@ test/infcover.c +infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c infcover: infcover.o libz.a $(CC) $(CFLAGS) -o $@ infcover.o libz.a @@ -140,24 +143,140 @@ match.lo: match.S mv _match.o match.lo rm -f _match.s -example.o: test/example.c zlib.h zconf.h - $(CC) $(CFLAGS) -I. -c -o $@ test/example.c +example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c -minigzip.o: test/minigzip.c zlib.h zconf.h - $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c +minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c -example64.o: test/example.c zlib.h zconf.h - $(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/example.c +example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c -minigzip64.o: test/minigzip.c zlib.h zconf.h - $(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/minigzip.c +minigzip64.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/minigzip.c -.SUFFIXES: .lo -.c.lo: +adler32.o: $(SRCDIR)adler32.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)adler32.c + +crc32.o: $(SRCDIR)crc32.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c + +deflate.o: $(SRCDIR)deflate.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c + +infback.o: $(SRCDIR)infback.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c + +inffast.o: $(SRCDIR)inffast.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inffast.c + +inflate.o: $(SRCDIR)inflate.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inflate.c + +inftrees.o: $(SRCDIR)inftrees.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inftrees.c + +trees.o: $(SRCDIR)trees.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)trees.c + +zutil.o: $(SRCDIR)zutil.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)zutil.c + +compress.o: $(SRCDIR)compress.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)compress.c + +uncompr.o: $(SRCDIR)uncompr.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)uncompr.c + +gzclose.o: $(SRCDIR)gzclose.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzclose.c + +gzlib.o: $(SRCDIR)gzlib.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzlib.c + +gzread.o: $(SRCDIR)gzread.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzread.c + +gzwrite.o: $(SRCDIR)gzwrite.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzwrite.c + + +adler32.lo: $(SRCDIR)adler32.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/adler32.o $(SRCDIR)adler32.c + -@mv objs/adler32.o $@ + +crc32.lo: $(SRCDIR)crc32.c -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $< - -@mv objs/$*.o $@ + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c + -@mv objs/crc32.o $@ + +deflate.lo: $(SRCDIR)deflate.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c + -@mv objs/deflate.o $@ + +infback.lo: $(SRCDIR)infback.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c + -@mv objs/infback.o $@ + +inffast.lo: $(SRCDIR)inffast.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inffast.o $(SRCDIR)inffast.c + -@mv objs/inffast.o $@ + +inflate.lo: $(SRCDIR)inflate.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inflate.o $(SRCDIR)inflate.c + -@mv objs/inflate.o $@ + +inftrees.lo: $(SRCDIR)inftrees.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inftrees.o $(SRCDIR)inftrees.c + -@mv objs/inftrees.o $@ + +trees.lo: $(SRCDIR)trees.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/trees.o $(SRCDIR)trees.c + -@mv objs/trees.o $@ + +zutil.lo: $(SRCDIR)zutil.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/zutil.o $(SRCDIR)zutil.c + -@mv objs/zutil.o $@ + +compress.lo: $(SRCDIR)compress.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/compress.o $(SRCDIR)compress.c + -@mv objs/compress.o $@ + +uncompr.lo: $(SRCDIR)uncompr.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/uncompr.o $(SRCDIR)uncompr.c + -@mv objs/uncompr.o $@ + +gzclose.lo: $(SRCDIR)gzclose.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzclose.o $(SRCDIR)gzclose.c + -@mv objs/gzclose.o $@ + +gzlib.lo: $(SRCDIR)gzlib.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzlib.o $(SRCDIR)gzlib.c + -@mv objs/gzlib.o $@ + +gzread.lo: $(SRCDIR)gzread.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzread.o $(SRCDIR)gzread.c + -@mv objs/gzread.o $@ + +gzwrite.lo: $(SRCDIR)gzwrite.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzwrite.o $(SRCDIR)gzwrite.c + -@mv objs/gzwrite.o $@ + placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) @@ -190,10 +309,12 @@ install-libs: $(LIBS) -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + rm -f $(DESTDIR)$(libdir)/$(STATICLIB) cp $(STATICLIB) $(DESTDIR)$(libdir) chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1 -@if test -n "$(SHAREDLIBV)"; then \ + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \ echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \ chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ @@ -203,8 +324,10 @@ install-libs: $(LIBS) ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ ($(LDCONFIG) || true) >/dev/null 2>&1; \ fi - cp zlib.3 $(DESTDIR)$(man3dir) + rm -f $(DESTDIR)$(man3dir)/zlib.3 + cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir) chmod 644 $(DESTDIR)$(man3dir)/zlib.3 + rm -f $(DESTDIR)$(pkgconfigdir)/zlib.pc cp zlib.pc $(DESTDIR)$(pkgconfigdir) chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc # The ranlib in install is needed on NeXTSTEP which checks file times @@ -212,7 +335,8 @@ install-libs: $(LIBS) install: install-libs -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi - cp zlib.h zconf.h $(DESTDIR)$(includedir) + rm -f $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h + cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir) chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h uninstall: @@ -226,18 +350,18 @@ uninstall: docs: zlib.3.pdf -zlib.3.pdf: zlib.3 - groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf +zlib.3.pdf: $(SRCDIR)zlib.3 + groff -mandoc -f H -T ps $(SRCDIR)zlib.3 | ps2pdf - $@ -zconf.h.cmakein: zconf.h.in +zconf.h.cmakein: $(SRCDIR)zconf.h.in -@ TEMPFILE=zconfh_$$; \ echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\ - sed -f $$TEMPFILE zconf.h.in > zconf.h.cmakein &&\ - touch -r zconf.h.in zconf.h.cmakein &&\ + sed -f $$TEMPFILE $(SRCDIR)zconf.h.in > $@ &&\ + touch -r $(SRCDIR)zconf.h.in $@ &&\ rm $$TEMPFILE -zconf: zconf.h.in - cp -p zconf.h.in zconf.h +zconf: $(SRCDIR)zconf.h.in + cp -p $(SRCDIR)zconf.h.in zconf.h mostlyclean: clean clean: @@ -255,34 +379,32 @@ maintainer-clean: distclean distclean: clean zconf zconf.h.cmakein docs rm -f Makefile zlib.pc configure.log -@rm -f .DS_Store - -@printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile - -@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile - -@touch -r Makefile.in Makefile + @if [ -f Makefile.in ]; then \ + printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ + printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \ + touch -r $(SRCDIR)Makefile.in Makefile ; fi + @if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi + @if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi tags: - etags *.[ch] - -depend: - makedepend -- $(CFLAGS) -- *.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o zutil.o: zutil.h zlib.h zconf.h -gzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h -compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h -crc32.o: zutil.h zlib.h zconf.h crc32.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -infback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h - -adler32.lo zutil.lo: zutil.h zlib.h zconf.h -gzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h -compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h -crc32.lo: zutil.h zlib.h zconf.h crc32.h -deflate.lo: deflate.h zutil.h zlib.h zconf.h -infback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h -inffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.lo: zutil.h zlib.h zconf.h inftrees.h -trees.lo: deflate.h zutil.h zlib.h zconf.h trees.h + etags $(SRCDIR)*.[ch] + +adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h +gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h +compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h +crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h +deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h +infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h +inffast.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h +inftrees.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h +trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h + +adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h +gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h +compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h +crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h +deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h +infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h +inffast.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h +inftrees.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h +trees.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h diff --git a/Modules/zlib/README b/Modules/zlib/README index 5ca9d12..51106de 100644 --- a/Modules/zlib/README +++ b/Modules/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.8 is a general purpose data compression library. All the code is +zlib 1.2.11 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -31,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.8 are documented in the file ChangeLog. +The changes made in version 1.2.11 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -84,7 +84,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2013 Jean-loup Gailly and Mark Adler + (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Modules/zlib/adler32.c b/Modules/zlib/adler32.c index a868f07..d0be438 100644 --- a/Modules/zlib/adler32.c +++ b/Modules/zlib/adler32.c @@ -1,5 +1,5 @@ /* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011 Mark Adler + * Copyright (C) 1995-2011, 2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -7,11 +7,9 @@ #include "zutil.h" -#define local static - local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); -#define BASE 65521 /* largest prime smaller than 65536 */ +#define BASE 65521U /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ @@ -62,10 +60,10 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); #endif /* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) +uLong ZEXPORT adler32_z(adler, buf, len) uLong adler; const Bytef *buf; - uInt len; + z_size_t len; { unsigned long sum2; unsigned n; @@ -133,6 +131,15 @@ uLong ZEXPORT adler32(adler, buf, len) } /* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + return adler32_z(adler, buf, len); +} + +/* ========================================================================= */ local uLong adler32_combine_(adler1, adler2, len2) uLong adler1; uLong adler2; @@ -156,7 +163,7 @@ local uLong adler32_combine_(adler1, adler2, len2) sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; if (sum1 >= BASE) sum1 -= BASE; if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); if (sum2 >= BASE) sum2 -= BASE; return sum1 | (sum2 << 16); } diff --git a/Modules/zlib/compress.c b/Modules/zlib/compress.c index 6e97626..e2db404 100644 --- a/Modules/zlib/compress.c +++ b/Modules/zlib/compress.c @@ -1,5 +1,5 @@ /* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -28,16 +28,11 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) { z_stream stream; int err; + const uInt max = (uInt)-1; + uLong left; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + left = *destLen; + *destLen = 0; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; @@ -46,15 +41,26 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) err = deflateInit(&stream, level); if (err != Z_OK) return err; - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; + stream.next_out = dest; + stream.avail_out = 0; + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; + sourceLen -= stream.avail_in; + } + err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); - err = deflateEnd(&stream); - return err; + *destLen = stream.total_out; + deflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : err; } /* =========================================================================== diff --git a/Modules/zlib/configure b/Modules/zlib/configure index b77a8a8..e974d1f 100755 --- a/Modules/zlib/configure +++ b/Modules/zlib/configure @@ -18,6 +18,18 @@ echo -------------------- >> configure.log echo $0 $* >> configure.log date >> configure.log +# get source directory +SRCDIR=`dirname $0` +if test $SRCDIR = "."; then + ZINC="" + ZINCOUT="-I." + SRCDIR="" +else + ZINC='-include zconf.h' + ZINCOUT='-I. -I$(SRCDIR)' + SRCDIR="$SRCDIR/" +fi + # set command prefix for cross-compilation if [ -n "${CHOST}" ]; then uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`" @@ -28,10 +40,10 @@ fi STATICLIB=libz.a # extract zlib version numbers from zlib.h -VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` -VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h` -VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h` -VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h` +VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}zlib.h` +VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < ${SRCDIR}zlib.h` +VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h` +VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h` # establish commands for library building if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then @@ -73,6 +85,8 @@ zprefix=0 zconst=0 build64=0 gcc=0 +warn=0 +debug=0 old_cc="$CC" old_cflags="$CFLAGS" OBJC='$(OBJZ) $(OBJG)' @@ -121,6 +135,8 @@ case "$1" in --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; -c* | --const) zconst=1; shift ;; + -w* | --warn) warn=1; shift ;; + -d* | --debug) debug=1; shift ;; *) echo "unknown option: $1" | tee -a configure.log echo "$0 --help for help" | tee -a configure.log @@ -159,34 +175,42 @@ case "$cc" in esac case `$cc -v 2>&1` in *gcc*) gcc=1 ;; + *clang*) gcc=1 ;; esac show $cc -c $test.c if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then echo ... using gcc >> configure.log CC="$cc" - CFLAGS="${CFLAGS--O3} ${ARCHS}" + CFLAGS="${CFLAGS--O3}" SFLAGS="${CFLAGS--O3} -fPIC" - LDFLAGS="${LDFLAGS} ${ARCHS}" + if test "$ARCHS"; then + CFLAGS="${CFLAGS} ${ARCHS}" + LDFLAGS="${LDFLAGS} ${ARCHS}" + fi if test $build64 -eq 1; then CFLAGS="${CFLAGS} -m64" SFLAGS="${SFLAGS} -m64" fi - if test "${ZLIBGCCWARN}" = "YES"; then + if test "$warn" -eq 1; then if test "$zconst" -eq 1; then CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST" else CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" fi fi + if test $debug -eq 1; then + CFLAGS="${CFLAGS} -DZLIB_DEBUG" + SFLAGS="${SFLAGS} -DZLIB_DEBUG" + fi if test -z "$uname"; then uname=`(uname -s || echo unknown) 2>/dev/null` fi case "$uname" in Linux* | linux* | GNU | GNU/* | solaris*) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;; + LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} ;; *BSD | *bsd* | DragonFly) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} + LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} LDCONFIG="ldconfig -m" ;; CYGWIN* | Cygwin* | cygwin* | OS/2*) EXE='.exe' ;; @@ -287,6 +311,9 @@ else esac fi fi + if test -n "$ZINC"; then + ZINC='-I- -I. -I$(SRCDIR)' + fi ;; SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} CFLAGS=${CFLAGS-"-O2"} @@ -337,16 +364,16 @@ if ($CC -c $CFLAGS $test.c) 2>/dev/null; then } echo - using any output from compiler to indicate an error >> configure.log else -try() -{ - show $* - ( $* ) >> configure.log 2>&1 - ret=$? - if test $ret -ne 0; then - echo "(exit code "$ret")" >> configure.log - fi - return $ret -} + try() + { + show $* + ( $* ) >> configure.log 2>&1 + ret=$? + if test $ret -ne 0; then + echo "(exit code "$ret")" >> configure.log + fi + return $ret + } fi tryboth() @@ -422,6 +449,65 @@ esac echo >> configure.log +# check for size_t +cat > $test.c < +#include +size_t dummy = 0; +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Checking for size_t... Yes." | tee -a configure.log + need_sizet=0 +else + echo "Checking for size_t... No." | tee -a configure.log + need_sizet=1 +fi + +echo >> configure.log + +# find the size_t integer type, if needed +if test $need_sizet -eq 1; then + cat > $test.c < $test.c < +int main(void) { + if (sizeof(void *) <= sizeof(int)) puts("int"); + else if (sizeof(void *) <= sizeof(long)) puts("long"); + else puts("z_longlong"); + return 0; +} +EOF + else + echo "Checking for long long... No." | tee -a configure.log + cat > $test.c < +int main(void) { + if (sizeof(void *) <= sizeof(int)) puts("int"); + else puts("long"); + return 0; +} +EOF + fi + if try $CC $CFLAGS -o $test $test.c; then + sizet=`./$test` + echo "Checking for a pointer-size integer type..." $sizet"." | tee -a configure.log + else + echo "Failed to find a pointer-size integer type." | tee -a configure.log + leave 1 + fi +fi + +if test $need_sizet -eq 1; then + CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}" + SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}" +fi + +echo >> configure.log + # check for large file support, and if none, check for fseeko() cat > $test.c < @@ -470,7 +556,7 @@ else fi # copy clean zconf.h for subsequent edits -cp -p zconf.h.in zconf.h +cp -p ${SRCDIR}zconf.h.in zconf.h echo >> configure.log @@ -764,6 +850,7 @@ echo STATICLIB = $STATICLIB >> configure.log echo TEST = $TEST >> configure.log echo VER = $VER >> configure.log echo Z_U4 = $Z_U4 >> configure.log +echo SRCDIR = $SRCDIR >> configure.log echo exec_prefix = $exec_prefix >> configure.log echo includedir = $includedir >> configure.log echo libdir = $libdir >> configure.log @@ -773,7 +860,7 @@ echo sharedlibdir = $sharedlibdir >> configure.log echo uname = $uname >> configure.log # udpate Makefile with the configure results -sed < Makefile.in " +sed < ${SRCDIR}Makefile.in " /^CC *=/s#=.*#=$CC# /^CFLAGS *=/s#=.*#=$CFLAGS# /^SFLAGS *=/s#=.*#=$SFLAGS# @@ -790,6 +877,9 @@ sed < Makefile.in " /^LDCONFIG *=/s#=.*#=$LDCONFIG# /^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# /^EXE *=/s#=.*#=$EXE# +/^SRCDIR *=/s#=.*#=$SRCDIR# +/^ZINC *=/s#=.*#=$ZINC# +/^ZINCOUT *=/s#=.*#=$ZINCOUT# /^prefix *=/s#=.*#=$prefix# /^exec_prefix *=/s#=.*#=$exec_prefix# /^libdir *=/s#=.*#=$libdir# @@ -803,7 +893,7 @@ sed < Makefile.in " " > Makefile # create zlib.pc with the configure results -sed < zlib.pc.in " +sed < ${SRCDIR}zlib.pc.in " /^CC *=/s#=.*#=$CC# /^CFLAGS *=/s#=.*#=$CFLAGS# /^CPP *=/s#=.*#=$CPP# diff --git a/Modules/zlib/crc32.c b/Modules/zlib/crc32.c index 979a719..9580440 100644 --- a/Modules/zlib/crc32.c +++ b/Modules/zlib/crc32.c @@ -1,5 +1,5 @@ /* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster @@ -30,17 +30,15 @@ #include "zutil.h" /* for STDC and FAR definitions */ -#define local static - /* Definitions for doing the crc four data bytes at a time. */ #if !defined(NOBYFOUR) && defined(Z_U4) # define BYFOUR #endif #ifdef BYFOUR local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); + const unsigned char FAR *, z_size_t)); local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); + const unsigned char FAR *, z_size_t)); # define TBLS 8 #else # define TBLS 1 @@ -201,10 +199,10 @@ const z_crc_t FAR * ZEXPORT get_crc_table() #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) +unsigned long ZEXPORT crc32_z(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; - uInt len; + z_size_t len; { if (buf == Z_NULL) return 0UL; @@ -235,8 +233,29 @@ unsigned long ZEXPORT crc32(crc, buf, len) return crc ^ 0xffffffffUL; } +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + return crc32_z(crc, buf, len); +} + #ifdef BYFOUR +/* + This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit + integer pointer type. This violates the strict aliasing rule, where a + compiler can assume, for optimization purposes, that two pointers to + fundamentally different types won't ever point to the same memory. This can + manifest as a problem only if one of the pointers is written to. This code + only reads from those pointers. So long as this code remains isolated in + this compilation unit, there won't be a problem. For this reason, this code + should not be copied and pasted into a compilation unit in which other code + writes to the buffer that is passed to these routines. + */ + /* ========================================================================= */ #define DOLIT4 c ^= *buf4++; \ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ @@ -247,7 +266,7 @@ unsigned long ZEXPORT crc32(crc, buf, len) local unsigned long crc32_little(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; - unsigned len; + z_size_t len; { register z_crc_t c; register const z_crc_t FAR *buf4; @@ -278,7 +297,7 @@ local unsigned long crc32_little(crc, buf, len) } /* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ +#define DOBIG4 c ^= *buf4++; \ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 @@ -287,7 +306,7 @@ local unsigned long crc32_little(crc, buf, len) local unsigned long crc32_big(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; - unsigned len; + z_size_t len; { register z_crc_t c; register const z_crc_t FAR *buf4; @@ -300,7 +319,6 @@ local unsigned long crc32_big(crc, buf, len) } buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - buf4--; while (len >= 32) { DOBIG32; len -= 32; @@ -309,7 +327,6 @@ local unsigned long crc32_big(crc, buf, len) DOBIG4; len -= 4; } - buf4++; buf = (const unsigned char FAR *)buf4; if (len) do { diff --git a/Modules/zlib/deflate.c b/Modules/zlib/deflate.c index 6969577..1ec7614 100644 --- a/Modules/zlib/deflate.c +++ b/Modules/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -73,6 +73,8 @@ typedef enum { typedef block_state (*compress_func) OF((deflate_state *s, int flush)); /* Compression function. Returns the block state after the call. */ +local int deflateStateCheck OF((z_streamp strm)); +local void slide_hash OF((deflate_state *s)); local void fill_window OF((deflate_state *s)); local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush)); @@ -84,15 +86,16 @@ local block_state deflate_huff OF((deflate_state *s, int flush)); local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifdef ASMV +# pragma message("Assembler code may have bugs -- use at your own risk") void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif -#ifdef DEBUG +#ifdef ZLIB_DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, int length)); #endif @@ -148,21 +151,14 @@ local const config configuration_table[10] = { * meaning. */ -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - /* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) /* =========================================================================== * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. + * IN assertion: all calls to UPDATE_HASH are made with consecutive input + * characters, so that a running hash key can be computed from the previous + * key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) @@ -173,9 +169,9 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ * the previous length of the hash chain. * If this file is compiled with -DFASTEST, the compression level is forced * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). + * IN assertion: all calls to INSERT_STRING are made with consecutive input + * characters and the first MIN_MATCH bytes of str are valid (except for + * the last MIN_MATCH-1 bytes of the input file). */ #ifdef FASTEST #define INSERT_STRING(s, str, match_head) \ @@ -197,6 +193,37 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ s->head[s->hash_size-1] = NIL; \ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +local void slide_hash(s) + deflate_state *s; +{ + unsigned n, m; + Posf *p; + uInt wsize = s->w_size; + + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + } while (--n); + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif +} + /* ========================================================================= */ int ZEXPORT deflateInit_(strm, level, version, stream_size) z_streamp strm; @@ -270,7 +297,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, #endif if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { + strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ @@ -278,14 +305,15 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ s->wrap = wrap; s->gzhead = Z_NULL; - s->w_bits = windowBits; + s->w_bits = (uInt)windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; - s->hash_bits = memLevel + 7; + s->hash_bits = (uInt)memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); @@ -319,6 +347,31 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, return deflateReset(strm); } +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +local int deflateStateCheck (strm) + z_streamp strm; +{ + deflate_state *s; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && +#endif + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + /* ========================================================================= */ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) z_streamp strm; @@ -331,7 +384,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) unsigned avail; z_const unsigned char *next; - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + if (deflateStateCheck(strm) || dictionary == Z_NULL) return Z_STREAM_ERROR; s = strm->state; wrap = s->wrap; @@ -389,13 +442,34 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) } /* ========================================================================= */ +int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) + z_streamp strm; + Bytef *dictionary; + uInt *dictLength; +{ + deflate_state *s; + uInt len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != Z_NULL && len) + zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != Z_NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ int ZEXPORT deflateResetKeep (strm) z_streamp strm; { deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + if (deflateStateCheck(strm)) { return Z_STREAM_ERROR; } @@ -410,7 +484,11 @@ int ZEXPORT deflateResetKeep (strm) if (s->wrap < 0) { s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + s->wrap ? INIT_STATE : BUSY_STATE; strm->adler = #ifdef GZIP s->wrap == 2 ? crc32(0L, Z_NULL, 0) : @@ -440,8 +518,8 @@ int ZEXPORT deflateSetHeader (strm, head) z_streamp strm; gz_headerp head; { - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; strm->state->gzhead = head; return Z_OK; } @@ -452,7 +530,7 @@ int ZEXPORT deflatePending (strm, pending, bits) int *bits; z_streamp strm; { - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; if (pending != Z_NULL) *pending = strm->state->pending; if (bits != Z_NULL) @@ -469,7 +547,7 @@ int ZEXPORT deflatePrime (strm, bits, value) deflate_state *s; int put; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; @@ -494,9 +572,8 @@ int ZEXPORT deflateParams(strm, level, strategy) { deflate_state *s; compress_func func; - int err = Z_OK; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; #ifdef FASTEST @@ -510,13 +587,22 @@ int ZEXPORT deflateParams(strm, level, strategy) func = configuration_table[s->level].func; if ((strategy != s->strategy || func != configuration_table[level].func) && - strm->total_in != 0) { + s->high_water) { /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - if (err == Z_BUF_ERROR && s->pending == 0) - err = Z_OK; + int err = deflate(strm, Z_BLOCK); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_out == 0) + return Z_BUF_ERROR; } if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) + slide_hash(s); + else + CLEAR_HASH(s); + s->matches = 0; + } s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; @@ -524,7 +610,7 @@ int ZEXPORT deflateParams(strm, level, strategy) s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; - return err; + return Z_OK; } /* ========================================================================= */ @@ -537,12 +623,12 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) { deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; + s->good_match = (uInt)good_length; + s->max_lazy_match = (uInt)max_lazy; s->nice_match = nice_length; - s->max_chain_length = max_chain; + s->max_chain_length = (uInt)max_chain; return Z_OK; } @@ -569,14 +655,13 @@ uLong ZEXPORT deflateBound(strm, sourceLen) { deflate_state *s; uLong complen, wraplen; - Bytef *str; /* conservative upper bound for compressed data */ complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) + if (deflateStateCheck(strm)) return complen + 6; /* compute wrapper length */ @@ -588,9 +673,11 @@ uLong ZEXPORT deflateBound(strm, sourceLen) case 1: /* zlib wrapper */ wraplen = 6 + (s->strstart ? 4 : 0); break; +#ifdef GZIP case 2: /* gzip wrapper */ wraplen = 18; if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + Bytef *str; if (s->gzhead->extra != Z_NULL) wraplen += 2 + s->gzhead->extra_len; str = s->gzhead->name; @@ -607,6 +694,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) wraplen += 2; } break; +#endif default: /* for compiler happiness */ wraplen = 6; } @@ -634,10 +722,10 @@ local void putShortMSB (s, b) } /* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). */ local void flush_pending(strm) z_streamp strm; @@ -654,13 +742,23 @@ local void flush_pending(strm) strm->next_out += len; s->pending_out += len; strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; + strm->avail_out -= len; + s->pending -= len; if (s->pending == 0) { s->pending_out = s->pending_buf; } } +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ + s->pending - (beg)); \ + } while (0) + /* ========================================================================= */ int ZEXPORT deflate (strm, flush) z_streamp strm; @@ -669,230 +767,229 @@ int ZEXPORT deflate (strm, flush) int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_BLOCK || flush < 0) { + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || + (strm->avail_in != 0 && strm->next_in == Z_NULL) || (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + /* Write the header */ if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } + /* zlib header */ + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + putShortMSB(s, header); + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); s->status = BUSY_STATE; - putShortMSB(s, header); - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); } - strm->adler = adler32(0L, Z_NULL, 0); + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; } } -#ifdef GZIP if (s->status == EXTRA_STATE) { if (s->gzhead->extra != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; + ulg beg = s->pending; /* start of bytes to update crc */ + uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + while (s->pending + left > s->pending_buf_size) { + uInt copy = s->pending_buf_size - s->pending; + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; + beg = 0; + left -= copy; } + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; } - else - s->status = NAME_STATE; + s->status = NAME_STATE; } if (s->status == NAME_STATE) { if (s->gzhead->name != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ + ulg beg = s->pending; /* start of bytes to update crc */ int val; - do { if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); + HCRC_UPDATE(beg); flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; } + beg = 0; } val = s->gzhead->name[s->gzindex++]; put_byte(s, val); } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } + HCRC_UPDATE(beg); + s->gzindex = 0; } - else - s->status = COMMENT_STATE; + s->status = COMMENT_STATE; } if (s->status == COMMENT_STATE) { if (s->gzhead->comment != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ + ulg beg = s->pending; /* start of bytes to update crc */ int val; - do { if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); + HCRC_UPDATE(beg); flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; } + beg = 0; } val = s->gzhead->comment[s->gzindex++]; put_byte(s, val); } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; + HCRC_UPDATE(beg); } - else - s->status = HCRC_STATE; + s->status = HCRC_STATE; } if (s->status == HCRC_STATE) { if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) + if (s->pending + 2 > s->pending_buf_size) { flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } } + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); } - else - s->status = BUSY_STATE; - } -#endif + s->status = BUSY_STATE; - /* Flush as much pending output as possible */ - if (s->pending != 0) { + /* Compression must start with an empty pending buffer */ flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ + if (s->pending != 0) { s->last_flush = -1; return Z_OK; } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); } +#endif /* Start a new block or continue the current one. */ @@ -900,9 +997,10 @@ int ZEXPORT deflate (strm, flush) (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush)); + bstate = s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; @@ -944,7 +1042,6 @@ int ZEXPORT deflate (strm, flush) } } } - Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->wrap <= 0) return Z_STREAM_END; @@ -981,18 +1078,9 @@ int ZEXPORT deflateEnd (strm) { int status; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, strm->state->pending_buf); @@ -1023,7 +1111,7 @@ int ZEXPORT deflateCopy (dest, source) ushf *overlay; - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + if (deflateStateCheck(source) || dest == Z_NULL) { return Z_STREAM_ERROR; } @@ -1073,7 +1161,7 @@ int ZEXPORT deflateCopy (dest, source) * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ -local int read_buf(strm, buf, size) +local unsigned read_buf(strm, buf, size) z_streamp strm; Bytef *buf; unsigned size; @@ -1097,7 +1185,7 @@ local int read_buf(strm, buf, size) strm->next_in += len; strm->total_in += len; - return (int)len; + return len; } /* =========================================================================== @@ -1151,9 +1239,9 @@ local uInt longest_match(s, cur_match) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ + register Bytef *match; /* matched string */ register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ + int best_len = (int)s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; @@ -1188,7 +1276,7 @@ local uInt longest_match(s, cur_match) /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); @@ -1349,7 +1437,11 @@ local uInt longest_match(s, cur_match) #endif /* FASTEST */ -#ifdef DEBUG +#ifdef ZLIB_DEBUG + +#define EQUAL 0 +/* result of memcmp for equal strings */ + /* =========================================================================== * Check that the match at match_start is indeed a match. */ @@ -1375,7 +1467,7 @@ local void check_match(s, start, match, length) } #else # define check_match(s, start, match, length) -#endif /* DEBUG */ +#endif /* ZLIB_DEBUG */ /* =========================================================================== * Fill the window when the lookahead becomes insufficient. @@ -1390,8 +1482,7 @@ local void check_match(s, start, match, length) local void fill_window(s) deflate_state *s; { - register unsigned n, m; - register Posf *p; + unsigned n; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; @@ -1418,35 +1509,11 @@ local void fill_window(s) */ if (s->strstart >= wsize+MAX_DIST(s)) { - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif + slide_hash(s); more += wsize; } if (s->strm->avail_in == 0) break; @@ -1552,70 +1619,199 @@ local void fill_window(s) if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ } +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunites to have a single copy from next_in to next_out. */ local block_state deflate_stored(s, flush) deflate_state *s; int flush; { - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = s->strstart - s->block_start; /* bytes left in window */ + if (len > (ulg)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + if (len > have) + len = have; /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || + flush == Z_NO_FLUSH || + len != left + s->strm->avail_in)) + break; - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending_buf[s->pending - 4] = len; + s->pending_buf[s->pending - 3] = len >> 8; + s->pending_buf[s->pending - 2] = ~len; + s->pending_buf[s->pending - 1] = ~len >> 8; + + /* Write the stored block header bytes. */ + flush_pending(s->strm); + +#ifdef ZLIB_DEBUG + /* Update debugging counts for the data about to be copied. */ + s->compressed_len += len << 3; + s->bits_sent += len << 3; +#endif - if (s->lookahead == 0) break; /* flush the current block */ + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + if (left > len) + left = len; + zmemcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += left; + len -= left; } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + read_buf(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; } + else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + } + zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + } + s->block_start = s->strstart; + s->insert += MIN(used, s->w_size - s->insert); } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* If the last block was written to next_out, then done. */ + if (last) return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && + s->strm->avail_in == 0 && (long)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart - 1; + if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { + /* Slide the window down. */ + s->block_start -= s->w_size; + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ } - if ((long)s->strstart > s->block_start) - FLUSH_BLOCK(s, 0); - return block_done; + if (have > s->strm->avail_in) + have = s->strm->avail_in; + if (have) { + read_buf(s->strm, s->window + s->strstart, have); + s->strstart += have; + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = s->strstart - s->block_start; + if (left >= min_block || + ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && + s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && + len == left ? 1 : 0; + _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); + s->block_start += len; + flush_pending(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; } /* =========================================================================== @@ -1892,7 +2088,7 @@ local block_state deflate_rle(s, flush) prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); + s->match_length = MAX_MATCH - (uInt)(strend - scan); if (s->match_length > s->lookahead) s->match_length = s->lookahead; } diff --git a/Modules/zlib/deflate.h b/Modules/zlib/deflate.h index ce0299e..23ecdd3 100644 --- a/Modules/zlib/deflate.h +++ b/Modules/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2012 Jean-loup Gailly + * Copyright (C) 1995-2016 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -51,13 +51,16 @@ #define Buf_size 16 /* size of bit buffer in bi_buf */ -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +#endif +#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ /* Stream status */ @@ -83,7 +86,7 @@ typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; @@ -100,10 +103,10 @@ typedef struct internal_state { Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ + ulg pending; /* nb of bytes in the pending buffer */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ + ulg gzindex; /* where in extra, name, or comment */ Byte method; /* can only be DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ @@ -249,7 +252,7 @@ typedef struct internal_state { uInt matches; /* number of string matches in current block */ uInt insert; /* bytes at end of window left to insert */ -#ifdef DEBUG +#ifdef ZLIB_DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif @@ -275,7 +278,7 @@ typedef struct internal_state { /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} +#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) @@ -309,7 +312,7 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, * used. */ -#ifndef DEBUG +#ifndef ZLIB_DEBUG /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) @@ -328,8 +331,8 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, flush = (s->last_lit == s->lit_bufsize-1); \ } # define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ s->d_buf[s->last_lit] = dist; \ s->l_buf[s->last_lit++] = len; \ dist--; \ diff --git a/Modules/zlib/gzguts.h b/Modules/zlib/gzguts.h index d87659d..990a4d2 100644 --- a/Modules/zlib/gzguts.h +++ b/Modules/zlib/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -25,6 +25,10 @@ # include # include #endif + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif #include #ifdef _WIN32 @@ -35,6 +39,10 @@ # include #endif +#if defined(_WIN32) || defined(__CYGWIN__) +# define WIDECHAR +#endif + #ifdef WINAPI_FAMILY # define open _open # define read _read @@ -95,18 +103,19 @@ # endif #endif -/* unlike snprintf (which is required in C99, yet still not supported by - Microsoft more than a decade later!), _snprintf does not guarantee null - termination of the result -- however this is only used in gzlib.c where +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c where the result is assured to fit in the space provided */ -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER < 1900 # define snprintf _snprintf #endif #ifndef local # define local static #endif -/* compile with -Dlocal if your debugger can't find static symbols */ +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ /* gz* functions always use library allocation functions */ #ifndef STDC @@ -170,7 +179,7 @@ typedef struct { char *path; /* path or fd for error messages */ unsigned size; /* buffer size, zero if not allocated yet */ unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer */ + unsigned char *in; /* input buffer (double-sized when writing) */ unsigned char *out; /* output buffer (double-sized when reading) */ int direct; /* 0 if processing gzip, 1 if transparent */ /* just for reading */ diff --git a/Modules/zlib/gzlib.c b/Modules/zlib/gzlib.c index fae202e..4105e6a 100644 --- a/Modules/zlib/gzlib.c +++ b/Modules/zlib/gzlib.c @@ -1,11 +1,11 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler + * Copyright (C) 2004-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "gzguts.h" -#if defined(_WIN32) && !defined(__BORLANDC__) +#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) # define LSEEK _lseeki64 #else #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 @@ -94,7 +94,7 @@ local gzFile gz_open(path, fd, mode) const char *mode; { gz_statep state; - size_t len; + z_size_t len; int oflag; #ifdef O_CLOEXEC int cloexec = 0; @@ -188,10 +188,10 @@ local gzFile gz_open(path, fd, mode) } /* save the path name for error messages */ -#ifdef _WIN32 +#ifdef WIDECHAR if (fd == -2) { len = wcstombs(NULL, path, 0); - if (len == (size_t)-1) + if (len == (z_size_t)-1) len = 0; } else @@ -202,7 +202,7 @@ local gzFile gz_open(path, fd, mode) free(state); return NULL; } -#ifdef _WIN32 +#ifdef WIDECHAR if (fd == -2) if (len) wcstombs(state->path, path, len + 1); @@ -211,7 +211,7 @@ local gzFile gz_open(path, fd, mode) else #endif #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->path, len + 1, "%s", (const char *)path); + (void)snprintf(state->path, len + 1, "%s", (const char *)path); #else strcpy(state->path, path); #endif @@ -239,7 +239,7 @@ local gzFile gz_open(path, fd, mode) /* open the file with the appropriate flags (or just use fd) */ state->fd = fd > -1 ? fd : ( -#ifdef _WIN32 +#ifdef WIDECHAR fd == -2 ? _wopen(path, oflag, 0666) : #endif open((const char *)path, oflag, 0666)); @@ -248,8 +248,10 @@ local gzFile gz_open(path, fd, mode) free(state); return NULL; } - if (state->mode == GZ_APPEND) + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ state->mode = GZ_WRITE; /* simplify later checks */ + } /* save the current position for rewinding (only if reading) */ if (state->mode == GZ_READ) { @@ -291,7 +293,7 @@ gzFile ZEXPORT gzdopen(fd, mode) if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) return NULL; #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); #else sprintf(path, "", fd); /* for debugging */ #endif @@ -301,7 +303,7 @@ gzFile ZEXPORT gzdopen(fd, mode) } /* -- see zlib.h -- */ -#ifdef _WIN32 +#ifdef WIDECHAR gzFile ZEXPORT gzopen_w(path, mode) const wchar_t *path; const char *mode; @@ -329,6 +331,8 @@ int ZEXPORT gzbuffer(file, size) return -1; /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ if (size < 2) size = 2; /* need two bytes to check magic header */ state->want = size; @@ -604,14 +608,13 @@ void ZLIB_INTERNAL gz_error(state, err, msg) return; } #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); #else strcpy(state->msg, state->path); strcat(state->msg, ": "); strcat(state->msg, msg); #endif - return; } #ifndef INT_MAX diff --git a/Modules/zlib/gzread.c b/Modules/zlib/gzread.c index bf4538e..956b91e 100644 --- a/Modules/zlib/gzread.c +++ b/Modules/zlib/gzread.c @@ -1,5 +1,5 @@ /* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -12,6 +12,7 @@ local int gz_look OF((gz_statep)); local int gz_decomp OF((gz_statep)); local int gz_fetch OF((gz_statep)); local int gz_skip OF((gz_statep, z_off64_t)); +local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from state->fd, and update state->eof, state->err, and state->msg as appropriate. @@ -24,13 +25,17 @@ local int gz_load(state, buf, len, have) unsigned *have; { int ret; + unsigned get, max = ((unsigned)-1 >> 2) + 1; *have = 0; do { - ret = read(state->fd, buf + *have, len - *have); + get = len - *have; + if (get > max) + get = max; + ret = read(state->fd, buf + *have, get); if (ret <= 0) break; - *have += ret; + *have += (unsigned)ret; } while (*have < len); if (ret < 0) { gz_error(state, Z_ERRNO, zstrerror()); @@ -94,10 +99,8 @@ local int gz_look(state) state->in = (unsigned char *)malloc(state->want); state->out = (unsigned char *)malloc(state->want << 1); if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); + free(state->out); + free(state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } @@ -284,33 +287,17 @@ local int gz_skip(state, len) return 0; } -/* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +local z_size_t gz_read(state, buf, len) + gz_statep state; voidp buf; - unsigned len; + z_size_t len; { - unsigned got, n; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return -1; - } + z_size_t got; + unsigned n; /* if len is zero, avoid unnecessary operations */ if (len == 0) @@ -320,32 +307,38 @@ int ZEXPORT gzread(file, buf, len) if (state->seek) { state->seek = 0; if (gz_skip(state, state->skip) == -1) - return -1; + return 0; } /* get len bytes to buf, or less than len if at the end */ got = 0; do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = -1; + if (n > len) + n = len; + /* first just try copying data from the output buffer */ if (state->x.have) { - n = state->x.have > len ? len : state->x.have; + if (state->x.have < n) + n = state->x.have; memcpy(buf, state->x.next, n); state->x.next += n; state->x.have -= n; } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) { + else if (state->eof && state->strm.avail_in == 0) { state->past = 1; /* tried to read past end */ break; } /* need output data -- for small len or new stream load up our output buffer */ - else if (state->how == LOOK || len < (state->size << 1)) { + else if (state->how == LOOK || n < (state->size << 1)) { /* get more output, looking for header if required */ if (gz_fetch(state) == -1) - return -1; + return 0; continue; /* no progress yet -- go back to copy above */ /* the copy above assures that we will leave with space in the output buffer, allowing at least one gzungetc() to succeed */ @@ -353,16 +346,16 @@ int ZEXPORT gzread(file, buf, len) /* large len -- read directly into user buffer */ else if (state->how == COPY) { /* read directly */ - if (gz_load(state, (unsigned char *)buf, len, &n) == -1) - return -1; + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; } /* large len -- decompress directly into user buffer */ else { /* state->how == GZIP */ - strm->avail_out = len; - strm->next_out = (unsigned char *)buf; + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; if (gz_decomp(state) == -1) - return -1; + return 0; n = state->x.have; state->x.have = 0; } @@ -374,8 +367,75 @@ int ZEXPORT gzread(file, buf, len) state->x.pos += n; } while (len); - /* return number of bytes read into user buffer (will fit in int) */ - return (int)got; + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfread(buf, size, nitems, file) + voidp buf; + z_size_t size; + z_size_t nitems; + gzFile file; +{ + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; } /* -- see zlib.h -- */ @@ -408,8 +468,8 @@ int ZEXPORT gzgetc(file) return *(state->x.next)++; } - /* nothing there -- try gzread() */ - ret = gzread(file, buf, 1); + /* nothing there -- try gz_read() */ + ret = gz_read(state, buf, 1); return ret < 1 ? -1 : buf[0]; } @@ -451,7 +511,7 @@ int ZEXPORT gzungetc(c, file) if (state->x.have == 0) { state->x.have = 1; state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = c; + state->x.next[0] = (unsigned char)c; state->x.pos--; state->past = 0; return c; @@ -473,7 +533,7 @@ int ZEXPORT gzungetc(c, file) } state->x.have++; state->x.next--; - state->x.next[0] = c; + state->x.next[0] = (unsigned char)c; state->x.pos--; state->past = 0; return c; diff --git a/Modules/zlib/gzwrite.c b/Modules/zlib/gzwrite.c index aa767fb..c7b5651 100644 --- a/Modules/zlib/gzwrite.c +++ b/Modules/zlib/gzwrite.c @@ -1,5 +1,5 @@ /* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * Copyright (C) 2004-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,17 +9,19 @@ local int gz_init OF((gz_statep)); local int gz_comp OF((gz_statep, int)); local int gz_zero OF((gz_statep, z_off64_t)); +local z_size_t gz_write OF((gz_statep, voidpc, z_size_t)); /* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on failure or 0 on success. */ + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ local int gz_init(state) gz_statep state; { int ret; z_streamp strm = &(state->strm); - /* allocate input buffer */ - state->in = (unsigned char *)malloc(state->want); + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)malloc(state->want << 1); if (state->in == NULL) { gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; @@ -47,6 +49,7 @@ local int gz_init(state) gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } + strm->next_in = NULL; } /* mark state as initialized */ @@ -62,17 +65,17 @@ local int gz_init(state) } /* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file, otherwise 0. - flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, - then the deflate() state is reset to start a new gzip stream. If gz->direct - is true, then simply write to the output file without compressing, and - ignore flush. */ + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ local int gz_comp(state, flush) gz_statep state; int flush; { - int ret, got; - unsigned have; + int ret, writ; + unsigned have, put, max = ((unsigned)-1 >> 2) + 1; z_streamp strm = &(state->strm); /* allocate memory if this is the first time through */ @@ -81,12 +84,16 @@ local int gz_comp(state, flush) /* write directly if requested */ if (state->direct) { - got = write(state->fd, strm->next_in, strm->avail_in); - if (got < 0 || (unsigned)got != strm->avail_in) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; + while (strm->avail_in) { + put = strm->avail_in > max ? max : strm->avail_in; + writ = write(state->fd, strm->next_in, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in -= (unsigned)writ; + strm->next_in += writ; } - strm->avail_in = 0; return 0; } @@ -97,17 +104,21 @@ local int gz_comp(state, flush) doing Z_FINISH then don't write until we get to Z_STREAM_END */ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { - have = (unsigned)(strm->next_out - state->x.next); - if (have && ((got = write(state->fd, state->x.next, have)) < 0 || - (unsigned)got != have)) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; + while (strm->next_out > state->x.next) { + put = strm->next_out - state->x.next > (int)max ? max : + (unsigned)(strm->next_out - state->x.next); + writ = write(state->fd, state->x.next, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + state->x.next += writ; } if (strm->avail_out == 0) { strm->avail_out = state->size; strm->next_out = state->out; + state->x.next = state->out; } - state->x.next = strm->next_out; } /* compress */ @@ -129,7 +140,8 @@ local int gz_comp(state, flush) return 0; } -/* Compress len zeros to output. Return -1 on error, 0 on success. */ +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ local int gz_zero(state, len) gz_statep state; z_off64_t len; @@ -161,32 +173,14 @@ local int gz_zero(state, len) return 0; } -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; +/* Write len bytes from buf to file. Return the number of bytes written. If + the returned value is less than len, then there was an error. */ +local z_size_t gz_write(state, buf, len) + gz_statep state; voidpc buf; - unsigned len; + z_size_t len; { - unsigned put = len; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } + z_size_t put = len; /* if len is zero, avoid unnecessary operations */ if (len == 0) @@ -209,14 +203,15 @@ int ZEXPORT gzwrite(file, buf, len) do { unsigned have, copy; - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); copy = state->size - have; if (copy > len) copy = len; memcpy(state->in + have, buf, copy); - strm->avail_in += copy; + state->strm.avail_in += copy; state->x.pos += copy; buf = (const char *)buf + copy; len -= copy; @@ -226,19 +221,83 @@ int ZEXPORT gzwrite(file, buf, len) } else { /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) return 0; /* directly compress user buffer to file */ - strm->avail_in = len; - strm->next_in = (z_const Bytef *)buf; - state->x.pos += len; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; + state->strm.next_in = (z_const Bytef *)buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) + voidpc buf; + z_size_t size; + z_size_t nitems; + gzFile file; +{ + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; } - /* input was all buffered or compressed (put will fit in int) */ - return (int)put; + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; } /* -- see zlib.h -- */ @@ -275,7 +334,7 @@ int ZEXPORT gzputc(file, c) strm->next_in = state->in; have = (unsigned)((strm->next_in + strm->avail_in) - state->in); if (have < state->size) { - state->in[have] = c; + state->in[have] = (unsigned char)c; strm->avail_in++; state->x.pos++; return c & 0xff; @@ -283,8 +342,8 @@ int ZEXPORT gzputc(file, c) } /* no room in buffer or not initialized, use gz_write() */ - buf[0] = c; - if (gzwrite(file, buf, 1) != 1) + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) return -1; return c & 0xff; } @@ -295,11 +354,21 @@ int ZEXPORT gzputs(file, str) const char *str; { int ret; - unsigned len; + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; /* write string */ - len = (unsigned)strlen(str); - ret = gzwrite(file, str, len); + len = strlen(str); + ret = gz_write(state, str, len); return ret == 0 && len != 0 ? -1 : ret; } @@ -309,63 +378,73 @@ int ZEXPORT gzputs(file, str) /* -- see zlib.h -- */ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { - int size, len; + int len; + unsigned left; + char *next; gz_statep state; z_streamp strm; /* get internal structure */ if (file == NULL) - return -1; + return Z_STREAM_ERROR; state = (gz_statep)file; strm = &(state->strm); /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; + return Z_STREAM_ERROR; /* make sure we have some buffer space */ if (state->size == 0 && gz_init(state) == -1) - return 0; + return state->err; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) - return 0; + return state->err; } - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; #ifdef NO_vsnprintf # ifdef HAS_vsprintf_void - (void)vsprintf((char *)(state->in), format, va); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; + (void)vsprintf(next, format, va); + for (len = 0; len < state->size; len++) + if (next[len] == 0) break; # else - len = vsprintf((char *)(state->in), format, va); + len = vsprintf(next, format, va); # endif #else # ifdef HAS_vsnprintf_void - (void)vsnprintf((char *)(state->in), size, format, va); - len = strlen((char *)(state->in)); + (void)vsnprintf(next, state->size, format, va); + len = strlen(next); # else - len = vsnprintf((char *)(state->in), size, format, va); + len = vsnprintf(next, state->size, format, va); # endif #endif /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) return 0; - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memcpy(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } return len; } @@ -390,73 +469,82 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; { - int size, len; + unsigned len, left; + char *next; gz_statep state; z_streamp strm; /* get internal structure */ if (file == NULL) - return -1; + return Z_STREAM_ERROR; state = (gz_statep)file; strm = &(state->strm); /* check that can really pass pointer in ints */ if (sizeof(int) != sizeof(void *)) - return 0; + return Z_STREAM_ERROR; /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; + return Z_STREAM_ERROR; /* make sure we have some buffer space */ if (state->size == 0 && gz_init(state) == -1) - return 0; + return state->error; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) - return 0; + return state->error; } - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(strm->next_in + strm->avail_in); + next[state->size - 1] = 0; #ifdef NO_snprintf # ifdef HAS_sprintf_void - sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, + a13, a14, a15, a16, a17, a18, a19, a20); for (len = 0; len < size; len++) - if (state->in[len] == 0) break; + if (next[len] == 0) + break; # else - len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, + a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #else # ifdef HAS_snprintf_void - snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen((char *)(state->in)); + snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(next); # else - len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, - a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, - a19, a20); + len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #endif /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + if (len == 0 || len >= state->size || next[state->size - 1] != 0) return 0; - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; + /* update buffer and position, compress first half if past that */ + strm->avail_in += len; state->x.pos += len; - return len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memcpy(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return (int)len; } #endif @@ -470,7 +558,7 @@ int ZEXPORT gzflush(file, flush) /* get internal structure */ if (file == NULL) - return -1; + return Z_STREAM_ERROR; state = (gz_statep)file; /* check that we're writing and that there's no error */ @@ -485,11 +573,11 @@ int ZEXPORT gzflush(file, flush) if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) - return -1; + return state->err; } /* compress remaining data with requested flush */ - gz_comp(state, flush); + (void)gz_comp(state, flush); return state->err; } @@ -520,13 +608,13 @@ int ZEXPORT gzsetparams(file, level, strategy) if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) - return -1; + return state->err; } /* change compression parameters for subsequent input */ if (state->size) { /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) return state->err; deflateParams(strm, level, strategy); } diff --git a/Modules/zlib/infback.c b/Modules/zlib/infback.c index f3833c2..59679ec 100644 --- a/Modules/zlib/infback.c +++ b/Modules/zlib/infback.c @@ -1,5 +1,5 @@ /* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2011 Mark Adler + * Copyright (C) 1995-2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -61,7 +61,7 @@ int stream_size; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->dmax = 32768U; - state->wbits = windowBits; + state->wbits = (uInt)windowBits; state->wsize = 1U << windowBits; state->window = window; state->wnext = 0; diff --git a/Modules/zlib/inffast.c b/Modules/zlib/inffast.c index bda59ce..0dbd1db 100644 --- a/Modules/zlib/inffast.c +++ b/Modules/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010, 2013 Mark Adler + * Copyright (C) 1995-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -8,26 +8,9 @@ #include "inflate.h" #include "inffast.h" -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") #else -# define OFF 1 -# define PUP(a) *++(a) -#endif /* Decode literal, length, and distance codes and write out the resulting @@ -96,9 +79,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; + in = strm->next_in; last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; + out = strm->next_out; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT @@ -119,9 +102,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ input data or output space */ do { if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; } here = lcode[hold & lmask]; @@ -134,14 +117,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); + *out++ = (unsigned char)(here.val); } else if (op & 16) { /* length base */ len = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; } len += (unsigned)hold & ((1U << op) - 1); @@ -150,9 +133,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; } here = dcode[hold & dmask]; @@ -165,10 +148,10 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ dist = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; + hold += (unsigned long)(*in++) << bits; bits += 8; } } @@ -196,30 +179,30 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR if (len <= op - whave) { do { - PUP(out) = 0; + *out++ = 0; } while (--len); continue; } len -= op - whave; do { - PUP(out) = 0; + *out++ = 0; } while (--op > whave); if (op == 0) { from = out - dist; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--len); continue; } #endif } - from = window - OFF; + from = window; if (wnext == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } @@ -230,14 +213,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ if (op < len) { /* some from end of window */ len -= op; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--op); - from = window - OFF; + from = window; if (wnext < len) { /* some from start of window */ op = wnext; len -= op; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } @@ -248,35 +231,35 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ if (op < len) { /* some from window */ len -= op; do { - PUP(out) = PUP(from); + *out++ = *from++; } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; len -= 3; } if (len) { - PUP(out) = PUP(from); + *out++ = *from++; if (len > 1) - PUP(out) = PUP(from); + *out++ = *from++; } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; len -= 3; } while (len > 2); if (len) { - PUP(out) = PUP(from); + *out++ = *from++; if (len > 1) - PUP(out) = PUP(from); + *out++ = *from++; } } } @@ -313,8 +296,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ hold &= (1U << bits) - 1; /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; + strm->next_in = in; + strm->next_out = out; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); diff --git a/Modules/zlib/inflate.c b/Modules/zlib/inflate.c index 870f89b..ac333e8 100644 --- a/Modules/zlib/inflate.c +++ b/Modules/zlib/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2012 Mark Adler + * Copyright (C) 1995-2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -92,6 +92,7 @@ #endif /* function prototypes */ +local int inflateStateCheck OF((z_streamp strm)); local void fixedtables OF((struct inflate_state FAR *state)); local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, unsigned copy)); @@ -101,12 +102,26 @@ local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, unsigned len)); +local int inflateStateCheck(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + state = (struct inflate_state FAR *)strm->state; + if (state == Z_NULL || state->strm != strm || + state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + int ZEXPORT inflateResetKeep(strm) z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; @@ -131,7 +146,7 @@ z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; state->wsize = 0; state->whave = 0; @@ -147,7 +162,7 @@ int windowBits; struct inflate_state FAR *state; /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* extract wrap request from windowBits parameter */ @@ -156,7 +171,7 @@ int windowBits; windowBits = -windowBits; } else { - wrap = (windowBits >> 4) + 1; + wrap = (windowBits >> 4) + 5; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; @@ -210,7 +225,9 @@ int stream_size; if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; + state->strm = strm; state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { ZFREE(strm, state); @@ -234,17 +251,17 @@ int value; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; state->bits = 0; return Z_OK; } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; + state->hold += (unsigned)value << state->bits; + state->bits += (uInt)bits; return Z_OK; } @@ -625,7 +642,7 @@ int flush; static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + if (inflateStateCheck(strm) || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; @@ -645,6 +662,8 @@ int flush; NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = 15; state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); @@ -672,7 +691,7 @@ int flush; len = BITS(4) + 8; if (state->wbits == 0) state->wbits = len; - else if (len > state->wbits) { + if (len > 15 || len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; @@ -699,14 +718,16 @@ int flush; } if (state->head != Z_NULL) state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); if (state->head != Z_NULL) state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: @@ -715,7 +736,8 @@ int flush; state->head->xflags = (int)(hold & 0xff); state->head->os = (int)(hold >> 8); } - if (state->flags & 0x0200) CRC2(state->check, hold); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; case EXLEN: @@ -724,7 +746,8 @@ int flush; state->length = (unsigned)(hold); if (state->head != Z_NULL) state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); INITBITS(); } else if (state->head != Z_NULL) @@ -742,7 +765,7 @@ int flush; len + copy > state->head->extra_max ? state->head->extra_max - len : copy); } - if (state->flags & 0x0200) + if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -761,9 +784,9 @@ int flush; if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) - state->head->name[state->length++] = len; + state->head->name[state->length++] = (Bytef)len; } while (len && copy < have); - if (state->flags & 0x0200) + if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -782,9 +805,9 @@ int flush; if (state->head != Z_NULL && state->head->comment != Z_NULL && state->length < state->head->comm_max) - state->head->comment[state->length++] = len; + state->head->comment[state->length++] = (Bytef)len; } while (len && copy < have); - if (state->flags & 0x0200) + if ((state->flags & 0x0200) && (state->wrap & 4)) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -796,7 +819,7 @@ int flush; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); - if (hold != (state->check & 0xffff)) { + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; @@ -1177,11 +1200,11 @@ int flush; out -= left; strm->total_out += out; state->total += out; - if (out) + if ((state->wrap & 4) && out) strm->adler = state->check = UPDATE(state->check, put - out, out); out = left; - if (( + if ((state->wrap & 4) && ( #ifdef GUNZIP state->flags ? hold : #endif @@ -1240,10 +1263,10 @@ int flush; strm->total_in += in; strm->total_out += out; state->total += out; - if (state->wrap && out) + if ((state->wrap & 4) && out) strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) @@ -1255,7 +1278,7 @@ int ZEXPORT inflateEnd(strm) z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); @@ -1273,7 +1296,7 @@ uInt *dictLength; struct inflate_state FAR *state; /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* copy dictionary */ @@ -1298,7 +1321,7 @@ uInt dictLength; int ret; /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; @@ -1330,7 +1353,7 @@ gz_headerp head; struct inflate_state FAR *state; /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; @@ -1383,7 +1406,7 @@ z_streamp strm; struct inflate_state FAR *state; /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; @@ -1430,7 +1453,7 @@ z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } @@ -1445,8 +1468,7 @@ z_streamp source; unsigned wsize; /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + if (inflateStateCheck(source) || dest == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; @@ -1467,6 +1489,7 @@ z_streamp source; /* copy state */ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); @@ -1488,25 +1511,51 @@ int subvert; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; - state->sane = !subvert; #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; return Z_OK; #else + (void)subvert; state->sane = 1; return Z_DATA_ERROR; #endif } +int ZEXPORT inflateValidate(strm, check) +z_streamp strm; +int check; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (check) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + long ZEXPORT inflateMark(strm) z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + if (inflateStateCheck(strm)) + return -(1L << 16); state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + + return (long)(((unsigned long)((long)state->back)) << 16) + (state->mode == COPY ? state->length : (state->mode == MATCH ? state->was - state->length : 0)); } + +unsigned long ZEXPORT inflateCodesUsed(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) return (unsigned long)-1; + state = (struct inflate_state FAR *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/Modules/zlib/inflate.h b/Modules/zlib/inflate.h index 95f4986..a46cce6 100644 --- a/Modules/zlib/inflate.h +++ b/Modules/zlib/inflate.h @@ -1,5 +1,5 @@ /* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2009 Mark Adler + * Copyright (C) 1995-2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -18,7 +18,7 @@ /* Possible inflate modes between inflate() calls */ typedef enum { - HEAD, /* i: waiting for magic header */ + HEAD = 16180, /* i: waiting for magic header */ FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ @@ -77,11 +77,14 @@ typedef enum { CHECK -> LENGTH -> DONE */ -/* state maintained between inflate() calls. Approximately 10K bytes. */ +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ struct inflate_state { + z_streamp strm; /* pointer back to this zlib stream */ inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags (0 if zlib) */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ diff --git a/Modules/zlib/inftrees.c b/Modules/zlib/inftrees.c index 44d89cf..2ea08fc 100644 --- a/Modules/zlib/inftrees.c +++ b/Modules/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2013 Mark Adler + * Copyright (C) 1995-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; + " inflate 1.2.11 Copyright 1995-2017 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -54,7 +54,7 @@ unsigned short FAR *work; code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ + unsigned match; /* use base and extra for symbol >= match */ unsigned short count[MAXBITS+1]; /* number of codes of each length */ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, @@ -181,19 +181,17 @@ unsigned short FAR *work; switch (type) { case CODES: base = extra = work; /* dummy value--not used */ - end = 19; + match = 20; break; case LENS: base = lbase; - base -= 257; extra = lext; - extra -= 257; - end = 256; + match = 257; break; - default: /* DISTS */ + default: /* DISTS */ base = dbase; extra = dext; - end = -1; + match = 0; } /* initialize state for loop */ @@ -216,13 +214,13 @@ unsigned short FAR *work; for (;;) { /* create table entry */ here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { + if (work[sym] + 1U < match) { here.op = (unsigned char)0; here.val = work[sym]; } - else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; + else if (work[sym] >= match) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; } else { here.op = (unsigned char)(32 + 64); /* end of block */ diff --git a/Modules/zlib/trees.c b/Modules/zlib/trees.c index 1fd7759..50cf4b4 100644 --- a/Modules/zlib/trees.c +++ b/Modules/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2012 Jean-loup Gailly + * Copyright (C) 1995-2017 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -36,7 +36,7 @@ #include "deflate.h" -#ifdef DEBUG +#ifdef ZLIB_DEBUG # include #endif @@ -122,13 +122,13 @@ struct static_tree_desc_s { int max_length; /* max bit length for the codes */ }; -local static_tree_desc static_l_desc = +local const static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; -local static_tree_desc static_d_desc = +local const static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; -local static_tree_desc static_bl_desc = +local const static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== @@ -152,18 +152,16 @@ local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); #ifdef GEN_TREES_H local void gen_trees_header OF((void)); #endif -#ifndef DEBUG +#ifndef ZLIB_DEBUG # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ -#else /* DEBUG */ +#else /* !ZLIB_DEBUG */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } @@ -182,7 +180,7 @@ local void gen_trees_header OF((void)); * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ -#ifdef DEBUG +#ifdef ZLIB_DEBUG local void send_bits OF((deflate_state *s, int value, int length)); local void send_bits(s, value, length) @@ -208,12 +206,12 @@ local void send_bits(s, value, length) s->bi_valid += length; } } -#else /* !DEBUG */ +#else /* !ZLIB_DEBUG */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ + int val = (int)value;\ s->bi_buf |= (ush)val << s->bi_valid;\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ @@ -223,7 +221,7 @@ local void send_bits(s, value, length) s->bi_valid += len;\ }\ } -#endif /* DEBUG */ +#endif /* ZLIB_DEBUG */ /* the arguments must not have side effects */ @@ -317,7 +315,7 @@ local void tr_static_init() * Genererate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H -# ifndef DEBUG +# ifndef ZLIB_DEBUG # include # endif @@ -394,7 +392,7 @@ void ZLIB_INTERNAL _tr_init(s) s->bi_buf = 0; s->bi_valid = 0; -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len = 0L; s->bits_sent = 0L; #endif @@ -522,12 +520,12 @@ local void gen_bitlen(s, desc) xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + s->opt_len += (ulg)f * (unsigned)(bits + xbits); + if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); } if (overflow == 0) return; - Trace((stderr,"\nbit length overflow\n")); + Tracev((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ @@ -554,9 +552,8 @@ local void gen_bitlen(s, desc) m = s->heap[--h]; if (m > max_code) continue; if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; + Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; tree[m].Len = (ush)bits; } n--; @@ -578,7 +575,7 @@ local void gen_codes (tree, max_code, bl_count) ushf *bl_count; /* number of codes at each bit length */ { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ + unsigned code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ @@ -586,7 +583,8 @@ local void gen_codes (tree, max_code, bl_count) * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = (ush)code; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. @@ -599,7 +597,7 @@ local void gen_codes (tree, max_code, bl_count) int len = tree[n].Len; if (len == 0) continue; /* Now reverse the bits */ - tree[n].Code = bi_reverse(next_code[len]++, len); + tree[n].Code = (ush)bi_reverse(next_code[len]++, len); Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); @@ -821,7 +819,7 @@ local int build_bl_tree(s) if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; + s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); @@ -869,11 +867,17 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) int last; /* one if this is the last block for a file */ { send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ -#ifdef DEBUG + bi_windup(s); /* align on byte boundary */ + put_short(s, (ush)stored_len); + put_short(s, (ush)~stored_len); + zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + s->pending += stored_len; +#ifdef ZLIB_DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; + s->bits_sent += 2*16; + s->bits_sent += stored_len<<3; #endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* =========================================================================== @@ -894,7 +898,7 @@ void ZLIB_INTERNAL _tr_align(s) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif bi_flush(s); @@ -902,7 +906,7 @@ void ZLIB_INTERNAL _tr_align(s) /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. + * trees or store, and write out the encoded block. */ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) deflate_state *s; @@ -974,7 +978,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) send_bits(s, (STATIC_TREES<<1)+last, 3); compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len += 3 + s->static_len; #endif } else { @@ -983,7 +987,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) max_blindex+1); compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len += 3 + s->opt_len; #endif } @@ -995,7 +999,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) if (last) { bi_windup(s); -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } @@ -1090,7 +1094,7 @@ local void compress_block(s, ltree, dtree) send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { - dist -= base_dist[code]; + dist -= (unsigned)base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ @@ -1193,34 +1197,7 @@ local void bi_windup(s) } s->bi_buf = 0; s->bi_valid = 0; -#ifdef DEBUG +#ifdef ZLIB_DEBUG s->bits_sent = (s->bits_sent+7) & ~7; #endif } - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/Modules/zlib/uncompr.c b/Modules/zlib/uncompr.c index 242e949..f03a1a8 100644 --- a/Modules/zlib/uncompr.c +++ b/Modules/zlib/uncompr.c @@ -1,5 +1,5 @@ /* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,51 +9,85 @@ #include "zlib.h" /* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. */ -int ZEXPORT uncompress (dest, destLen, source, sourceLen) +int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; - uLong sourceLen; + uLong *sourceLen; { z_stream stream; int err; + const uInt max = (uInt)-1; + uLong len, left; + Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - stream.next_in = (z_const Bytef *)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } + else { + left = 1; + dest = buf; + } + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; err = inflateInit(&stream); if (err != Z_OK) return err; - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; + stream.next_out = dest; + stream.avail_out = 0; - err = inflateEnd(&stream); - return err; + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (uLong)max ? max : (uInt)len; + len -= stream.avail_in; + } + err = inflate(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + inflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return uncompress2(dest, destLen, source, &sourceLen); } diff --git a/Modules/zlib/zconf.h b/Modules/zlib/zconf.h index 9987a77..5e1d68a 100644 --- a/Modules/zlib/zconf.h +++ b/Modules/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -17,7 +17,7 @@ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ # define Z_PREFIX_SET -/* all linked symbols */ +/* all linked symbols and init macros */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align @@ -29,6 +29,7 @@ # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 @@ -37,10 +38,14 @@ # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 +# define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams @@ -67,6 +72,8 @@ # define gzeof z_gzeof # define gzerror z_gzerror # define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite # define gzgetc z_gzgetc # define gzgetc_ z_gzgetc_ # define gzgets z_gzgets @@ -78,7 +85,6 @@ # define gzopen_w z_gzopen_w # endif # define gzprintf z_gzprintf -# define gzvprintf z_gzvprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread @@ -89,32 +95,39 @@ # define gztell z_gztell # define gztell64 z_gztell64 # define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf # define gzwrite z_gzwrite # endif # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit # define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed # define inflateCopy z_inflateCopy # define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary # define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 # define inflateInit2_ z_inflateInit2_ # define inflateInit_ z_inflateInit_ # define inflateMark z_inflateMark # define inflatePrime z_inflatePrime # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep # define inflateSetDictionary z_inflateSetDictionary -# define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep +# define inflateValidate z_inflateValidate # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table # ifndef Z_SOLO # define uncompress z_uncompress +# define uncompress2 z_uncompress2 # endif # define zError z_zError # ifndef Z_SOLO @@ -224,9 +237,19 @@ # define z_const #endif -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL +#ifdef Z_SOLO + typedef unsigned long z_size_t; +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong #endif /* Maximum value for memLevel in deflateInit2 */ @@ -256,7 +279,7 @@ Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes for small objects. */ diff --git a/Modules/zlib/zconf.h.cmakein b/Modules/zlib/zconf.h.cmakein index 043019c..a7f24cc 100644 --- a/Modules/zlib/zconf.h.cmakein +++ b/Modules/zlib/zconf.h.cmakein @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -19,7 +19,7 @@ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ # define Z_PREFIX_SET -/* all linked symbols */ +/* all linked symbols and init macros */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align @@ -31,6 +31,7 @@ # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 @@ -39,10 +40,14 @@ # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 +# define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams @@ -69,6 +74,8 @@ # define gzeof z_gzeof # define gzerror z_gzerror # define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite # define gzgetc z_gzgetc # define gzgetc_ z_gzgetc_ # define gzgets z_gzgets @@ -80,7 +87,6 @@ # define gzopen_w z_gzopen_w # endif # define gzprintf z_gzprintf -# define gzvprintf z_gzvprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread @@ -91,32 +97,39 @@ # define gztell z_gztell # define gztell64 z_gztell64 # define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf # define gzwrite z_gzwrite # endif # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit # define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed # define inflateCopy z_inflateCopy # define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary # define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 # define inflateInit2_ z_inflateInit2_ # define inflateInit_ z_inflateInit_ # define inflateMark z_inflateMark # define inflatePrime z_inflatePrime # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep # define inflateSetDictionary z_inflateSetDictionary -# define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep +# define inflateValidate z_inflateValidate # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table # ifndef Z_SOLO # define uncompress z_uncompress +# define uncompress2 z_uncompress2 # endif # define zError z_zError # ifndef Z_SOLO @@ -226,9 +239,19 @@ # define z_const #endif -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL +#ifdef Z_SOLO + typedef unsigned long z_size_t; +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong #endif /* Maximum value for memLevel in deflateInit2 */ @@ -258,7 +281,7 @@ Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes for small objects. */ diff --git a/Modules/zlib/zconf.h.in b/Modules/zlib/zconf.h.in index 9987a77..5e1d68a 100644 --- a/Modules/zlib/zconf.h.in +++ b/Modules/zlib/zconf.h.in @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -17,7 +17,7 @@ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ # define Z_PREFIX_SET -/* all linked symbols */ +/* all linked symbols and init macros */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align @@ -29,6 +29,7 @@ # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 @@ -37,10 +38,14 @@ # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 +# define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams @@ -67,6 +72,8 @@ # define gzeof z_gzeof # define gzerror z_gzerror # define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite # define gzgetc z_gzgetc # define gzgetc_ z_gzgetc_ # define gzgets z_gzgets @@ -78,7 +85,6 @@ # define gzopen_w z_gzopen_w # endif # define gzprintf z_gzprintf -# define gzvprintf z_gzvprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread @@ -89,32 +95,39 @@ # define gztell z_gztell # define gztell64 z_gztell64 # define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf # define gzwrite z_gzwrite # endif # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit # define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed # define inflateCopy z_inflateCopy # define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary # define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 # define inflateInit2_ z_inflateInit2_ # define inflateInit_ z_inflateInit_ # define inflateMark z_inflateMark # define inflatePrime z_inflatePrime # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep # define inflateSetDictionary z_inflateSetDictionary -# define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep +# define inflateValidate z_inflateValidate # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table # ifndef Z_SOLO # define uncompress z_uncompress +# define uncompress2 z_uncompress2 # endif # define zError z_zError # ifndef Z_SOLO @@ -224,9 +237,19 @@ # define z_const #endif -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL +#ifdef Z_SOLO + typedef unsigned long z_size_t; +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong #endif /* Maximum value for memLevel in deflateInit2 */ @@ -256,7 +279,7 @@ Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes for small objects. */ diff --git a/Modules/zlib/zlib.3 b/Modules/zlib/zlib.3 index 0160e62..bda4eb0 100644 --- a/Modules/zlib/zlib.3 +++ b/Modules/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "28 Apr 2013" +.TH ZLIB 3 "15 Jan 2017" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -48,32 +48,10 @@ Changes to this version are documented in the file that accompanies the source. .LP .I zlib -is available in Java using the java.util.zip package: -.IP -http://java.sun.com/developer/technicalArticles/Programming/compression/ -.LP -A Perl interface to -.IR zlib , -written by Paul Marquess (pmqs@cpan.org), -is available at CPAN (Comprehensive Perl Archive Network) sites, -including: -.IP -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ -.LP -A Python interface to -.IR zlib , -written by A.M. Kuchling (amk@magnet.com), -is available in Python 1.5 and later versions: -.IP -http://docs.python.org/library/zlib.html -.LP -.I zlib -is built into -.IR tcl: -.IP -http://wiki.tcl.tk/4610 +is built in to many languages and operating systems, including but not limited to +Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. .LP -An experimental package to read and write files in .zip format, +An experimental package to read and write files in the .zip format, written on top of .I zlib by Gilles Vollant (info@winimage.com), @@ -92,7 +70,9 @@ web site can be found at: .IP http://zlib.net/ .LP -The data format used by the zlib library is described by RFC +The data format used by the +.I zlib +library is described by RFC (Request for Comments) 1950 to 1952 in the files: .IP http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) @@ -124,17 +104,35 @@ http://zlib.net/zlib_faq.html before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). -.SH AUTHORS -Version 1.2.8 -Copyright (C) 1995-2013 Jean-loup Gailly (jloup@gzip.org) -and Mark Adler (madler@alumni.caltech.edu). -.LP -This software is provided "as-is," -without any express or implied warranty. -In no event will the authors be held liable for any damages +.SH AUTHORS AND LICENSE +Version 1.2.11 +.LP +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler +.LP +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages arising from the use of this software. -See the distribution directory with respect to requirements -governing redistribution. +.LP +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: +.LP +.nr step 1 1 +.IP \n[step]. 3 +The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +.IP \n+[step]. +Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +.IP \n+[step]. +This notice may not be removed or altered from any source distribution. +.LP +Jean-loup Gailly Mark Adler +.br +jloup@gzip.org madler@alumni.caltech.edu +.LP The deflate format used by .I zlib was defined by Phil Katz. diff --git a/Modules/zlib/zlib.h b/Modules/zlib/zlib.h index 3e0c767..f09cdaf 100644 --- a/Modules/zlib/zlib.h +++ b/Modules/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.8, April 28th, 2013 + version 1.2.11, January 15th, 2017 - Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.8" -#define ZLIB_VERNUM 0x1280 +#define ZLIB_VERSION "1.2.11" +#define ZLIB_VERNUM 0x12b0 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 8 +#define ZLIB_VER_REVISION 11 #define ZLIB_VER_SUBREVISION 0 /* @@ -65,7 +65,8 @@ extern "C" { with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - This library can optionally read and write gzip streams in memory as well. + This library can optionally read and write gzip and raw deflate streams in + memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- @@ -74,7 +75,7 @@ extern "C" { The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash - even in case of corrupted input. + even in the case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); @@ -87,7 +88,7 @@ typedef struct z_stream_s { uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total number of input bytes read so far */ - Bytef *next_out; /* next output byte should be put there */ + Bytef *next_out; /* next output byte will go here */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total number of bytes output so far */ @@ -98,8 +99,9 @@ typedef struct z_stream_s { free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; @@ -142,7 +144,9 @@ typedef gz_header FAR *gz_headerp; zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if @@ -155,7 +159,7 @@ typedef gz_header FAR *gz_headerp; The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly + uncompressed data and may be saved for use by the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ @@ -200,7 +204,7 @@ typedef gz_header FAR *gz_headerp; #define Z_TEXT 1 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ #define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ +/* Possible values of the data_type field for deflate() */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ @@ -258,11 +262,11 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - - Provide more output starting at next_out and update next_out and avail_out + - Generate more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. + should be set only when necessary. Some output may be provided even if + flush is zero. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more @@ -271,7 +275,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more ouput + in that case. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to decide how much data to accumulate before producing output, in order to @@ -292,8 +298,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. This completes the current deflate block and follows it with an empty fixed codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. + in order for the decompressor to finish the block before the empty fixed + codes block. If flush is set to Z_BLOCK, a deflate block is completed and emitted, as for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to @@ -319,34 +325,38 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). Then deflate is guaranteed to - return Z_STREAM_END. If not enough output space is provided, deflate will - not return Z_STREAM_END, and it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. + if next_in or next_out was Z_NULL or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. */ @@ -369,23 +379,21 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. */ @@ -401,17 +409,20 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). - - Provide more output starting at next_out and update next_out and avail_out + - Generate more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be @@ -428,7 +439,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the + To assist in this, on return inflate() always sets strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or @@ -454,7 +465,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all of the uncompressed data for the operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not + saved by the compressor for this purpose.) The use of Z_FINISH is not required to perform an inflation in one step. However it may be used to inform inflate that a faster approach can be used for the single inflate() call. Z_FINISH also informs inflate to not maintain a sliding window if the @@ -476,32 +487,33 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the Adler-32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 + below. At the end of the stream, inflate() checks that its computed Adler-32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() can decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically, if requested when initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. When processing + header is not retained unless inflateGetHeader() is used. When processing gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - producted so far. The CRC-32 is checked against the gzip trailer. + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress was possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. + recovery of the data is to be attempted. */ @@ -511,9 +523,8 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); This function discards any unprocessed input and does not flush any pending output. - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. */ @@ -544,16 +555,29 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. + with no zlib header or trailer, and will not compute a check value. windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is @@ -614,12 +638,12 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, addition, the current implementation of deflate will use at most the window size minus 262 bytes of the provided dictionary. - Upon return of this function, strm->adler is set to the adler32 value + Upon return of this function, strm->adler is set to the Adler-32 value of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value + which dictionary has been used by the compressor. (The Adler-32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. + Adler-32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is @@ -628,6 +652,28 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, not perform any compression: this will be done by deflate(). */ +ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* @@ -648,10 +694,10 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). @@ -662,20 +708,36 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int strategy)); /* Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be + interpretation of level and strategy is as in deflateInit2(). This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. + If the compression approach (which is a function of the level) or the + strategy is changed, and if any input has been consumed in a previous + deflate() call, then the input available so far is compressed with the old + level and strategy using deflate(strm, Z_BLOCK). There are three approaches + for the compression levels 0, 1..3, and 4..9 respectively. The new level + and strategy will take effect at the next call of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. */ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, @@ -793,7 +855,7 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to + recommended that a check value such as an Adler-32 or a CRC-32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. @@ -802,7 +864,10 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will not automatically decode concatenated gzip streams. + inflate() will return Z_STREAM_END at the end of the gzip stream. The state + would need to be reset to continue decoding a subsequent gzip stream. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the @@ -823,7 +888,7 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. + can be determined from the Adler-32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called at any time to set the dictionary. If the provided dictionary is smaller than the @@ -834,7 +899,7 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not + expected one (incorrect Adler-32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ @@ -892,7 +957,7 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The + but does not free and reallocate the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source @@ -904,7 +969,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL), or if @@ -956,7 +1023,7 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); location in the input stream can be determined from avail_in and data_type as noted in the description for the Z_BLOCK flush parameter for inflate. - inflateMark returns the value noted above or -1 << 16 if the provided + inflateMark returns the value noted above, or -65536 if the provided source stream state was inconsistent. */ @@ -1048,9 +1115,9 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those @@ -1059,12 +1126,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in(). @@ -1092,7 +1159,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() + assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK. */ @@ -1114,7 +1181,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); 7.6: size of z_off_t Compiler, assembler, and debug options: - 8: DEBUG + 8: ZLIB_DEBUG 9: ASMV or ASMINF -- use ASM code 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 11: 0 (reserved) @@ -1164,7 +1231,8 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output @@ -1180,7 +1248,7 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. + compressed data. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, @@ -1203,7 +1271,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. + is the actual size of the uncompressed data. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output @@ -1212,6 +1280,14 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ +ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen)); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + /* gzip file access functions */ /* @@ -1290,10 +1366,9 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); default buffer size is 8192 bytes. This function must be called after gzopen() or gzdopen(), and before any other calls that read or write the file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). + write. Three times that size in buffer space is allocated. A larger buffer + size of, for example, 64K or 128K bytes will noticeably increase the speed + of decompression (reading). The new buffer size also affects the maximum length for gzprintf(). @@ -1304,10 +1379,12 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. + of deflateInit2 for the meaning of these parameters. Previously provided + data is flushed before the parameter change. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. */ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); @@ -1335,7 +1412,35 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); case. gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, + gzFile file)); +/* + Read up to nitems items of size size from file to buf, otherwise operating + as gzread() does. This duplicates the interface of stdio's fread(), with + size_t request and return types. If the library defines size_t, then + z_size_t is identical to size_t. If not, then z_size_t is an unsigned + integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a z_size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevetheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, reseting and retrying on end-of-file, when size is not 1. */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, @@ -1346,19 +1451,33 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, error. */ +ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, + z_size_t nitems, gzFile file)); +/* + gzfwrite() writes nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. If + the library defines size_t, then z_size_t is identical to size_t. If not, + then z_size_t is an unsigned integer type that can contain a pointer. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a z_size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); /* Converts, formats, and writes the arguments to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); @@ -1418,7 +1537,7 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); If the flush parameter is Z_FINISH, the remaining data is written and the gzip stream is completed in the output. If gzwrite() is called again, a new gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. + concatenated gzip streams. gzflush should be called only when strictly necessary because it will degrade compression if called too often. @@ -1572,7 +1691,7 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); return the updated checksum. If buf is Z_NULL, this function returns the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed much faster. Usage example: @@ -1585,6 +1704,12 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ +ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, + z_size_t len)); +/* + Same as adler32(), but with a size_t length. +*/ + /* ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); @@ -1614,6 +1739,12 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ +ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, + z_size_t len)); +/* + Same as crc32(), but with a size_t length. +*/ + /* ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); @@ -1644,19 +1775,35 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) +#ifdef Z_PREFIX_SET +# define z_deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define z_inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#else +# define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#endif #ifndef Z_SOLO @@ -1676,10 +1823,10 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) #else # define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) #endif /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or @@ -1737,19 +1884,16 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ #endif /* !Z_SOLO */ -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; -#endif - /* undocumented functions */ ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if defined(_WIN32) && !defined(Z_SOLO) +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, const char *mode)); #endif diff --git a/Modules/zlib/zlib.map b/Modules/zlib/zlib.map index 55c6647..40fa9db 100644 --- a/Modules/zlib/zlib.map +++ b/Modules/zlib/zlib.map @@ -1,83 +1,94 @@ -ZLIB_1.2.0 { - global: - compressBound; - deflateBound; - inflateBack; - inflateBackEnd; - inflateBackInit_; - inflateCopy; - local: - deflate_copyright; - inflate_copyright; - inflate_fast; - inflate_table; - zcalloc; - zcfree; - z_errmsg; - gz_error; - gz_intmax; - _*; -}; - -ZLIB_1.2.0.2 { - gzclearerr; - gzungetc; - zlibCompileFlags; -} ZLIB_1.2.0; - -ZLIB_1.2.0.8 { - deflatePrime; -} ZLIB_1.2.0.2; - -ZLIB_1.2.2 { - adler32_combine; - crc32_combine; - deflateSetHeader; - inflateGetHeader; -} ZLIB_1.2.0.8; - -ZLIB_1.2.2.3 { - deflateTune; - gzdirect; -} ZLIB_1.2.2; - -ZLIB_1.2.2.4 { - inflatePrime; -} ZLIB_1.2.2.3; - -ZLIB_1.2.3.3 { - adler32_combine64; - crc32_combine64; - gzopen64; - gzseek64; - gztell64; - inflateUndermine; -} ZLIB_1.2.2.4; - -ZLIB_1.2.3.4 { - inflateReset2; - inflateMark; -} ZLIB_1.2.3.3; - -ZLIB_1.2.3.5 { - gzbuffer; - gzoffset; - gzoffset64; - gzclose_r; - gzclose_w; -} ZLIB_1.2.3.4; - -ZLIB_1.2.5.1 { - deflatePending; -} ZLIB_1.2.3.5; - -ZLIB_1.2.5.2 { - deflateResetKeep; - gzgetc_; - inflateResetKeep; -} ZLIB_1.2.5.1; - -ZLIB_1.2.7.1 { - inflateGetDictionary; - gzvprintf; -} ZLIB_1.2.5.2; +ZLIB_1.2.0 { + global: + compressBound; + deflateBound; + inflateBack; + inflateBackEnd; + inflateBackInit_; + inflateCopy; + local: + deflate_copyright; + inflate_copyright; + inflate_fast; + inflate_table; + zcalloc; + zcfree; + z_errmsg; + gz_error; + gz_intmax; + _*; +}; + +ZLIB_1.2.0.2 { + gzclearerr; + gzungetc; + zlibCompileFlags; +} ZLIB_1.2.0; + +ZLIB_1.2.0.8 { + deflatePrime; +} ZLIB_1.2.0.2; + +ZLIB_1.2.2 { + adler32_combine; + crc32_combine; + deflateSetHeader; + inflateGetHeader; +} ZLIB_1.2.0.8; + +ZLIB_1.2.2.3 { + deflateTune; + gzdirect; +} ZLIB_1.2.2; + +ZLIB_1.2.2.4 { + inflatePrime; +} ZLIB_1.2.2.3; + +ZLIB_1.2.3.3 { + adler32_combine64; + crc32_combine64; + gzopen64; + gzseek64; + gztell64; + inflateUndermine; +} ZLIB_1.2.2.4; + +ZLIB_1.2.3.4 { + inflateReset2; + inflateMark; +} ZLIB_1.2.3.3; + +ZLIB_1.2.3.5 { + gzbuffer; + gzoffset; + gzoffset64; + gzclose_r; + gzclose_w; +} ZLIB_1.2.3.4; + +ZLIB_1.2.5.1 { + deflatePending; +} ZLIB_1.2.3.5; + +ZLIB_1.2.5.2 { + deflateResetKeep; + gzgetc_; + inflateResetKeep; +} ZLIB_1.2.5.1; + +ZLIB_1.2.7.1 { + inflateGetDictionary; + gzvprintf; +} ZLIB_1.2.5.2; + +ZLIB_1.2.9 { + inflateCodesUsed; + inflateValidate; + uncompress2; + gzfread; + gzfwrite; + deflateGetDictionary; + adler32_z; + crc32_z; +} ZLIB_1.2.7.1; diff --git a/Modules/zlib/zutil.c b/Modules/zlib/zutil.c index 23d2ebe..a76c6b0 100644 --- a/Modules/zlib/zutil.c +++ b/Modules/zlib/zutil.c @@ -1,5 +1,5 @@ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. + * Copyright (C) 1995-2017 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -10,21 +10,18 @@ # include "gzguts.h" #endif -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - z_const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; const char * ZEXPORT zlibVersion() @@ -61,7 +58,7 @@ uLong ZEXPORT zlibCompileFlags() case 8: flags += 2 << 6; break; default: flags += 3 << 6; } -#ifdef DEBUG +#ifdef ZLIB_DEBUG flags += 1 << 8; #endif #if defined(ASMV) || defined(ASMINF) @@ -115,8 +112,8 @@ uLong ZEXPORT zlibCompileFlags() return flags; } -#ifdef DEBUG - +#ifdef ZLIB_DEBUG +#include # ifndef verbose # define verbose 0 # endif @@ -219,9 +216,11 @@ local ptr_table table[MAX_PTR]; voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) { - voidpf buf = opaque; /* just to make some compilers happy */ + voidpf buf; ulg bsize = (ulg)items*size; + (void)opaque; + /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ @@ -244,6 +243,9 @@ voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) { int n; + + (void)opaque; + if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; @@ -259,7 +261,6 @@ void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) next_ptr--; return; } - ptr = opaque; /* just to make some compilers happy */ Assert(0, "zcfree: ptr not found"); } @@ -278,13 +279,13 @@ void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) { - if (opaque) opaque = 0; /* to make compiler happy */ + (void)opaque; return _halloc((long)items, size); } void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) { - if (opaque) opaque = 0; /* to make compiler happy */ + (void)opaque; _hfree(ptr); } @@ -306,7 +307,7 @@ voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) unsigned items; unsigned size; { - if (opaque) items += size - size; /* make compiler happy */ + (void)opaque; return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } @@ -315,8 +316,8 @@ void ZLIB_INTERNAL zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { + (void)opaque; free(ptr); - if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ diff --git a/Modules/zlib/zutil.h b/Modules/zlib/zutil.h index 24ab06b..b079ea6 100644 --- a/Modules/zlib/zutil.h +++ b/Modules/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -36,7 +36,9 @@ #ifndef local # define local static #endif -/* compile with -Dlocal if your debugger can't find static symbols */ +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ typedef unsigned char uch; typedef uch FAR uchf; @@ -98,28 +100,38 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif #ifdef AMIGA -# define OS_CODE 0x01 +# define OS_CODE 1 #endif #if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 +# define OS_CODE 2 # define F_OPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + #if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 +# define OS_CODE 5 #endif #ifdef OS2 -# define OS_CODE 0x06 +# define OS_CODE 6 # if defined(M_I86) && !defined(Z_SOLO) # include # endif #endif #if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 +# define OS_CODE 7 # ifndef Z_SOLO # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fdopen */ @@ -131,18 +143,24 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#ifdef TOPS20 -# define OS_CODE 0x0a +#ifdef __acorn +# define OS_CODE 13 #endif -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif +#if defined(WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef _BEOS_ +# define OS_CODE 16 +#endif + +#ifdef __TOS_OS400__ +# define OS_CODE 18 #endif -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f +#ifdef __APPLE__ +# define OS_CODE 19 #endif #if defined(_BEOS_) || defined(RISCOS) @@ -177,7 +195,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* common defaults */ #ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ +# define OS_CODE 3 /* assume Unix */ #endif #ifndef F_OPEN @@ -216,7 +234,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif /* Diagnostic functions */ -#ifdef DEBUG +#ifdef ZLIB_DEBUG # include extern int ZLIB_INTERNAL z_verbose; extern void ZLIB_INTERNAL z_error OF((char *m)); diff --git a/Objects/abstract.c b/Objects/abstract.c index f9afece..d838856 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2325,7 +2325,7 @@ exit: return result; } -/* Positional arguments are obj followed args. */ +/* Positional arguments are obj followed by args. */ PyObject * _PyObject_Call_Prepend(PyObject *func, PyObject *obj, PyObject *args, PyObject *kwargs) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c6d0707..a8d6980 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -798,18 +798,22 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) if (PyIndex_Check(arg)) { count = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (count == -1 && PyErr_Occurred()) { - return -1; - } - if (count < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return -1; + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + return -1; + PyErr_Clear(); /* fall through */ } - if (count > 0) { - if (PyByteArray_Resize((PyObject *)self, count)) + else { + if (count < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); return -1; - memset(PyByteArray_AS_STRING(self), 0, count); + } + if (count > 0) { + if (PyByteArray_Resize((PyObject *)self, count)) + return -1; + memset(PyByteArray_AS_STRING(self), 0, count); + } + return 0; } - return 0; } /* Use the buffer API */ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 779fe29..5d48440 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -974,7 +974,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, /* Write the numeric prefix for "x", "X" and "o" formats if the alternate form is used. For example, write "0x" for the "%#x" format. */ - if ((flags & F_ALT) && (c == 'x' || c == 'X')) { + if ((flags & F_ALT) && (c == 'o' || c == 'x' || c == 'X')) { assert(pbuf[0] == '0'); assert(pbuf[1] == c); if (fill != ' ') { @@ -999,8 +999,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, if (fill == ' ') { if (sign) *res++ = sign; - if ((flags & F_ALT) && - (c == 'x' || c == 'X')) { + if ((flags & F_ALT) && (c == 'o' || c == 'x' || c == 'X')) { assert(pbuf[0] == '0'); assert(pbuf[1] == c); *res++ = *pbuf++; @@ -2594,16 +2593,20 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyIndex_Check(x)) { size = PyNumber_AsSsize_t(x, PyExc_OverflowError); if (size == -1 && PyErr_Occurred()) { - return NULL; + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); /* fall through */ } - if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return NULL; + else { + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + new = _PyBytes_FromSize(size, 1); + if (new == NULL) + return NULL; + return new; } - new = _PyBytes_FromSize(size, 1); - if (new == NULL) - return NULL; - return new; } return PyBytes_FromObject(x); diff --git a/Objects/codeobject.c b/Objects/codeobject.c index f7f91a8..df8b953 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -545,7 +545,7 @@ _PyCode_ConstantKey(PyObject *op) PyTuple_SET_ITEM(tuple, i, item_key); } - key = PyTuple_Pack(3, Py_TYPE(op), op, tuple); + key = PyTuple_Pack(2, tuple, op); Py_DECREF(tuple); } else if (PyFrozenSet_CheckExact(op)) { @@ -579,7 +579,7 @@ _PyCode_ConstantKey(PyObject *op) if (set == NULL) return NULL; - key = PyTuple_Pack(3, Py_TYPE(op), op, set); + key = PyTuple_Pack(2, set, op); Py_DECREF(set); return key; } @@ -590,7 +590,7 @@ _PyCode_ConstantKey(PyObject *op) if (obj_id == NULL) return NULL; - key = PyTuple_Pack(3, Py_TYPE(op), op, obj_id); + key = PyTuple_Pack(2, obj_id, op); Py_DECREF(obj_id); } return key; @@ -856,16 +856,15 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra; if (co_extra == NULL) { - o->co_extra = (_PyCodeObjectExtra*) PyMem_Malloc( - sizeof(_PyCodeObjectExtra)); - if (o->co_extra == NULL) { + co_extra = PyMem_Malloc(sizeof(_PyCodeObjectExtra)); + if (co_extra == NULL) { return -1; } - co_extra = (_PyCodeObjectExtra *) o->co_extra; co_extra->ce_extras = PyMem_Malloc( tstate->co_extra_user_count * sizeof(void*)); if (co_extra->ce_extras == NULL) { + PyMem_Free(co_extra); return -1; } @@ -874,20 +873,25 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) { co_extra->ce_extras[i] = NULL; } + + o->co_extra = co_extra; } else if (co_extra->ce_size <= index) { - co_extra->ce_extras = PyMem_Realloc( + void** ce_extras = PyMem_Realloc( co_extra->ce_extras, tstate->co_extra_user_count * sizeof(void*)); - if (co_extra->ce_extras == NULL) { + if (ce_extras == NULL) { return -1; } - co_extra->ce_size = tstate->co_extra_user_count; - - for (Py_ssize_t i = co_extra->ce_size; i < co_extra->ce_size; i++) { - co_extra->ce_extras[i] = NULL; + for (Py_ssize_t i = co_extra->ce_size; + i < tstate->co_extra_user_count; + i++) { + ce_extras[i] = NULL; } + + co_extra->ce_extras = ce_extras; + co_extra->ce_size = tstate->co_extra_user_count; } co_extra->ce_extras[index] = extra; diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 31e1278..cfaba68 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -1025,11 +1025,11 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } cr.real = PyFloat_AsDouble(tmp); - cr.imag = 0.0; /* Shut up compiler warning */ + cr.imag = 0.0; Py_DECREF(tmp); } if (i == NULL) { - ci.real = 0.0; + ci.real = cr.imag; } else if (PyComplex_Check(i)) { ci = ((PyComplexObject*)i)->cval; @@ -1051,7 +1051,7 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (ci_is_complex) { cr.real -= ci.imag; } - if (cr_is_complex) { + if (cr_is_complex && i != NULL) { ci.real += cr.imag; } return complex_subtype_from_doubles(type, cr.real, ci.real); diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 20b6f2f..a0c1977 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -388,7 +388,7 @@ dk_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) * This can be used to reserve enough size to insert n entries without * resizing. */ -#define ESTIMATE_SIZE(n) (((n)*3) >> 1) +#define ESTIMATE_SIZE(n) (((n)*3+1) >> 1) /* Alternative fraction that is otherwise close enough to 2n/3 to make * little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10. @@ -676,7 +676,8 @@ Christian Tismer. lookdict() is general-purpose, and may return DKIX_ERROR if (and only if) a comparison raises an exception. lookdict_unicode() below is specialized to string keys, comparison of which can -never raise an exception; that function can never return DKIX_ERROR. +never raise an exception; that function can never return DKIX_ERROR when key +is string. Otherwise, it falls back to lookdict(). lookdict_unicode_nodummy is further specialized for string keys that cannot be the value. For both, when the key isn't found a DKIX_EMPTY is returned. hashpos returns @@ -1359,12 +1360,26 @@ make_keys_shared(PyObject *op) PyObject * _PyDict_NewPresized(Py_ssize_t minused) { + const Py_ssize_t max_presize = 128 * 1024; Py_ssize_t newsize; PyDictKeysObject *new_keys; - for (newsize = PyDict_MINSIZE; - newsize <= minused && newsize > 0; - newsize <<= 1) - ; + + /* There are no strict guarantee that returned dict can contain minused + * items without resize. So we create medium size dict instead of very + * large dict or MemoryError. + */ + if (minused > USABLE_FRACTION(max_presize)) { + newsize = max_presize; + } + else { + Py_ssize_t minsize = ESTIMATE_SIZE(minused); + newsize = PyDict_MINSIZE; + while (newsize < minsize) { + newsize <<= 1; + } + } + assert(IS_POWER_OF_2(newsize)); + new_keys = new_keys_object(newsize); if (new_keys == NULL) return NULL; @@ -1577,11 +1592,34 @@ _PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, return insertdict(mp, key, hash, value); } +static int +delitem_common(PyDictObject *mp, Py_ssize_t hashpos, Py_ssize_t ix, + PyObject **value_addr) +{ + PyObject *old_key, *old_value; + PyDictKeyEntry *ep; + + old_value = *value_addr; + assert(old_value != NULL); + *value_addr = NULL; + mp->ma_used--; + mp->ma_version_tag = DICT_NEXT_VERSION(); + ep = &DK_ENTRIES(mp->ma_keys)[ix]; + dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); + ENSURE_ALLOWS_DELETIONS(mp); + old_key = ep->me_key; + ep->me_key = NULL; + Py_DECREF(old_key); + Py_DECREF(old_value); + + assert(_PyDict_CheckConsistency(mp)); + return 0; +} + int PyDict_DelItem(PyObject *op, PyObject *key) { Py_hash_t hash; - assert(key); if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -1598,8 +1636,6 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) { Py_ssize_t hashpos, ix; PyDictObject *mp; - PyDictKeyEntry *ep; - PyObject *old_key, *old_value; PyObject **value_addr; if (!PyDict_Check(op)) { @@ -1626,24 +1662,60 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); assert(ix >= 0); } + return delitem_common(mp, hashpos, ix, value_addr); +} - old_value = *value_addr; - assert(old_value != NULL); - *value_addr = NULL; - mp->ma_used--; - mp->ma_version_tag = DICT_NEXT_VERSION(); - ep = &DK_ENTRIES(mp->ma_keys)[ix]; - dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); - ENSURE_ALLOWS_DELETIONS(mp); - old_key = ep->me_key; - ep->me_key = NULL; - Py_DECREF(old_key); - Py_DECREF(old_value); +/* This function promises that the predicate -> deletion sequence is atomic + * (i.e. protected by the GIL), assuming the predicate itself doesn't + * release the GIL. + */ +int +_PyDict_DelItemIf(PyObject *op, PyObject *key, + int (*predicate)(PyObject *value)) +{ + Py_ssize_t hashpos, ix; + PyDictObject *mp; + Py_hash_t hash; + PyObject **value_addr; + int res; - assert(_PyDict_CheckConsistency(mp)); - return 0; + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + assert(key); + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + mp = (PyDictObject *)op; + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); + if (ix == DKIX_ERROR) + return -1; + if (ix == DKIX_EMPTY || *value_addr == NULL) { + _PyErr_SetKeyError(key); + return -1; + } + assert(dk_get_index(mp->ma_keys, hashpos) == ix); + + // Split table doesn't allow deletion. Combine it. + if (_PyDict_HasSplitTable(mp)) { + if (dictresize(mp, DK_SIZE(mp->ma_keys))) { + return -1; + } + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); + assert(ix >= 0); + } + + res = predicate(*value_addr); + if (res == -1) + return -1; + if (res > 0) + return delitem_common(mp, hashpos, ix, value_addr); + else + return 0; } + void PyDict_Clear(PyObject *op) { @@ -1758,9 +1830,8 @@ PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) /* Internal version of dict.pop(). */ PyObject * -_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) +_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt) { - Py_hash_t hash; Py_ssize_t ix, hashpos; PyObject *old_value, *old_key; PyDictKeyEntry *ep; @@ -1778,12 +1849,6 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) _PyErr_SetKeyError(key); return NULL; } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { - hash = PyObject_Hash(key); - if (hash == -1) - return NULL; - } ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); if (ix == DKIX_ERROR) return NULL; @@ -1821,6 +1886,28 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) return old_value; } +PyObject * +_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) +{ + Py_hash_t hash; + + if (((PyDictObject *)dict)->ma_used == 0) { + if (deflt) { + Py_INCREF(deflt); + return deflt; + } + _PyErr_SetKeyError(key); + return NULL; + } + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + } + return _PyDict_Pop_KnownHash(dict, key, hash, deflt); +} + /* Internal version of dict.from_keys(). It is subclass-friendly. */ PyObject * _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) @@ -4290,15 +4377,19 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, } if (value == NULL) { res = PyDict_DelItem(dict, key); - if (cached != ((PyDictObject *)dict)->ma_keys) { + // Since key sharing dict doesn't allow deletion, PyDict_DelItem() + // always converts dict to combined form. + if ((cached = CACHED_KEYS(tp)) != NULL) { CACHED_KEYS(tp) = NULL; DK_DECREF(cached); } } else { - int was_shared = cached == ((PyDictObject *)dict)->ma_keys; + int was_shared = (cached == ((PyDictObject *)dict)->ma_keys); res = PyDict_SetItem(dict, key, value); - if (was_shared && cached != ((PyDictObject *)dict)->ma_keys) { + if (was_shared && + (cached = CACHED_KEYS(tp)) != NULL && + cached != ((PyDictObject *)dict)->ma_keys) { /* PyDict_SetItem() may call dictresize and convert split table * into combined table. In such case, convert it to split * table again and update type's shared key only when this is diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 428d83c..b1798a2 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -221,7 +221,7 @@ PyTypeObject _PyManagedBuffer_Type = { PyDoc_STRVAR(memory_doc, -"memoryview($module, object)\n--\n\ +"memoryview(object)\n--\n\ \n\ Create a new memoryview object which references the given object."); diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 22b1f1d..f9f1bf3 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -2231,7 +2231,7 @@ odictvalues_new(PyObject *od) /* ---------------------------------------------- - MutableMappping implementations + MutableMapping implementations Mapping: diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 2f32355..6a69021 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -191,15 +191,12 @@ PySlice_GetIndices(PyObject *_r, Py_ssize_t length, } int -PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, - Py_ssize_t *slicelength) +PySlice_Unpack(PyObject *_r, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) { PySliceObject *r = (PySliceObject*)_r; /* this is harder to get right than you might think */ - Py_ssize_t defstart, defstop; - if (r->step == Py_None) { *step = 1; } @@ -219,42 +216,75 @@ PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length, *step = -PY_SSIZE_T_MAX; } - defstart = *step < 0 ? length-1 : 0; - defstop = *step < 0 ? -1 : length; - if (r->start == Py_None) { - *start = defstart; + *start = *step < 0 ? PY_SSIZE_T_MAX-1 : 0;; } else { if (!_PyEval_SliceIndex(r->start, start)) return -1; - if (*start < 0) *start += length; - if (*start < 0) *start = (*step < 0) ? -1 : 0; - if (*start >= length) - *start = (*step < 0) ? length - 1 : length; } if (r->stop == Py_None) { - *stop = defstop; + *stop = *step < 0 ? -PY_SSIZE_T_MAX : PY_SSIZE_T_MAX; } else { if (!_PyEval_SliceIndex(r->stop, stop)) return -1; - if (*stop < 0) *stop += length; - if (*stop < 0) *stop = (*step < 0) ? -1 : 0; - if (*stop >= length) - *stop = (*step < 0) ? length - 1 : length; } - if ((*step < 0 && *stop >= *start) - || (*step > 0 && *start >= *stop)) { - *slicelength = 0; + return 0; +} + +Py_ssize_t +PySlice_AdjustIndices(Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t step) +{ + /* this is harder to get right than you might think */ + + assert(step != 0); + assert(step >= -PY_SSIZE_T_MAX); + + if (*start < 0) { + *start += length; + if (*start < 0) { + *start = (step < 0) ? -1 : 0; + } } - else if (*step < 0) { - *slicelength = (*stop-*start+1)/(*step)+1; + else if (*start >= length) { + *start = (step < 0) ? length - 1 : length; + } + + if (*stop < 0) { + *stop += length; + if (*stop < 0) { + *stop = (step < 0) ? -1 : 0; + } + } + else if (*stop >= length) { + *stop = (step < 0) ? length - 1 : length; + } + + if (step < 0) { + if (*stop < *start) { + return (*start - *stop - 1) / (-step) + 1; + } } else { - *slicelength = (*stop-*start-1)/(*step)+1; + if (*start < *stop) { + return (*stop - *start - 1) / step + 1; + } } + return 0; +} + +#undef PySlice_GetIndicesEx +int +PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, + Py_ssize_t *slicelength) +{ + if (PySlice_Unpack(_r, start, stop, step) < 0) + return -1; + *slicelength = PySlice_AdjustIndices(length, start, stop, *step); return 0; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9c998f7..a5ae454 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5083,10 +5083,10 @@ onError: return NULL; } -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(__ANDROID__) /* Simplified UTF-8 decoder using surrogateescape error handler, - used to decode the command line arguments on Mac OS X. + used to decode the command line arguments on Mac OS X and Android. Return a pointer to a newly allocated wide character string (use PyMem_RawFree() to free the memory), or NULL on memory allocation error. */ @@ -5137,7 +5137,7 @@ _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size) return unicode; } -#endif /* __APPLE__ */ +#endif /* __APPLE__ or __ANDROID__ */ /* Primary internal function which creates utf8 encoded bytes objects. @@ -9988,7 +9988,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject **items, Py_ssize_t seqlen) use_memcpy = 1; #endif for (i = 0; i < seqlen; i++) { - const Py_ssize_t old_sz = sz; + size_t add_sz; item = items[i]; if (!PyUnicode_Check(item)) { PyErr_Format(PyExc_TypeError, @@ -9999,16 +9999,18 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject **items, Py_ssize_t seqlen) } if (PyUnicode_READY(item) == -1) goto onError; - sz += PyUnicode_GET_LENGTH(item); + add_sz = PyUnicode_GET_LENGTH(item); item_maxchar = PyUnicode_MAX_CHAR_VALUE(item); maxchar = Py_MAX(maxchar, item_maxchar); - if (i != 0) - sz += seplen; - if (sz < old_sz || sz > PY_SSIZE_T_MAX) { + if (i != 0) { + add_sz += seplen; + } + if (add_sz > (size_t)(PY_SSIZE_T_MAX - sz)) { PyErr_SetString(PyExc_OverflowError, "join() result is too long for a Python string"); goto onError; } + sz += add_sz; if (use_memcpy && last_obj != NULL) { if (PyUnicode_KIND(last_obj) != PyUnicode_KIND(item)) use_memcpy = 0; @@ -10646,7 +10648,7 @@ replace(PyObject *self, PyObject *str1, u = unicode_empty; goto done; } - if (new_size > (PY_SSIZE_T_MAX >> (rkind-1))) { + if (new_size > (PY_SSIZE_T_MAX / rkind)) { PyErr_SetString(PyExc_OverflowError, "replace string is too long"); goto error; @@ -14324,11 +14326,12 @@ formatchar(PyObject *v) if (iobj == NULL) { goto onError; } - v = iobj; + x = PyLong_AsLong(iobj); Py_DECREF(iobj); } - /* Integer input truncated to a character */ - x = PyLong_AsLong(v); + else { + x = PyLong_AsLong(v); + } if (x == -1 && PyErr_Occurred()) goto onError; diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index ab6b235..9ca386d 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -24,6 +24,8 @@ init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback) { self->hash = -1; self->wr_object = ob; + self->wr_prev = NULL; + self->wr_next = NULL; Py_XINCREF(callback); self->wr_callback = callback; } diff --git a/PC/bdist_wininst/install.c b/PC/bdist_wininst/install.c index fd977f5..17cc30d 100644 --- a/PC/bdist_wininst/install.c +++ b/PC/bdist_wininst/install.c @@ -154,7 +154,7 @@ HANDLE hBitmap; char *bitmap_bytes; static const char *REGISTRY_SUFFIX_6432 = -#ifdef MS_WIN64 +#ifdef _WIN64 ""; #else "-32"; diff --git a/PC/getpathp.c b/PC/getpathp.c index 0b0ae49..1eeebfe 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -560,7 +560,7 @@ read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite) char *p = fgets(line, MAXPATHLEN + 1, sp_file); if (!p) break; - if (*p == '\0' || *p == '#') + if (*p == '\0' || *p == '\r' || *p == '\n' || *p == '#') continue; while (*++p) { if (*p == '\r' || *p == '\n') { diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index c9d1e6c..4797cdc 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -111,7 +111,9 @@ msvcrt_locking_impl(PyObject *module, int fd, int mode, long nbytes) int err; Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH err = _locking(fd, mode, nbytes); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (err != 0) return PyErr_SetFromErrno(PyExc_IOError); @@ -138,7 +140,9 @@ static long msvcrt_setmode_impl(PyObject *module, int fd, int flags) /*[clinic end generated code: output=24a9be5ea07ccb9b input=76e7c01f6b137f75]*/ { + _Py_BEGIN_SUPPRESS_IPH flags = _setmode(fd, flags); + _Py_END_SUPPRESS_IPH if (flags == -1) PyErr_SetFromErrno(PyExc_IOError); @@ -165,7 +169,9 @@ msvcrt_open_osfhandle_impl(PyObject *module, intptr_t handle, int flags) { int fd; + _Py_BEGIN_SUPPRESS_IPH fd = _open_osfhandle(handle, flags); + _Py_END_SUPPRESS_IPH if (fd == -1) PyErr_SetFromErrno(PyExc_IOError); @@ -303,7 +309,9 @@ static PyObject * msvcrt_putch_impl(PyObject *module, char char_value) /*[clinic end generated code: output=92ec9b81012d8f60 input=ec078dd10cb054d6]*/ { + _Py_BEGIN_SUPPRESS_IPH _putch(char_value); + _Py_END_SUPPRESS_IPH Py_RETURN_NONE; } @@ -320,7 +328,9 @@ static PyObject * msvcrt_putwch_impl(PyObject *module, int unicode_char) /*[clinic end generated code: output=a3bd1a8951d28eee input=996ccd0bbcbac4c3]*/ { + _Py_BEGIN_SUPPRESS_IPH _putwch(unicode_char); + _Py_END_SUPPRESS_IPH Py_RETURN_NONE; } @@ -342,7 +352,13 @@ static PyObject * msvcrt_ungetch_impl(PyObject *module, char char_value) /*[clinic end generated code: output=c6942a0efa119000 input=22f07ee9001bbf0f]*/ { - if (_ungetch(char_value) == EOF) + int res; + + _Py_BEGIN_SUPPRESS_IPH + res = _ungetch(char_value); + _Py_END_SUPPRESS_IPH + + if (res == EOF) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; } @@ -360,7 +376,13 @@ static PyObject * msvcrt_ungetwch_impl(PyObject *module, int unicode_char) /*[clinic end generated code: output=e63af05438b8ba3d input=83ec0492be04d564]*/ { - if (_ungetwch(unicode_char) == WEOF) + int res; + + _Py_BEGIN_SUPPRESS_IPH + res = _ungetwch(unicode_char); + _Py_END_SUPPRESS_IPH + + if (res == WEOF) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; } @@ -382,7 +404,13 @@ static long msvcrt_CrtSetReportFile_impl(PyObject *module, int type, int file) /*[clinic end generated code: output=df291c7fe032eb68 input=bb8f721a604fcc45]*/ { - return (long)_CrtSetReportFile(type, (_HFILE)file); + long res; + + _Py_BEGIN_SUPPRESS_IPH + res = (long)_CrtSetReportFile(type, (_HFILE)file); + _Py_END_SUPPRESS_IPH + + return res; } /*[clinic input] @@ -403,7 +431,9 @@ msvcrt_CrtSetReportMode_impl(PyObject *module, int type, int mode) { int res; + _Py_BEGIN_SUPPRESS_IPH res = _CrtSetReportMode(type, mode); + _Py_END_SUPPRESS_IPH if (res == -1) PyErr_SetFromErrno(PyExc_IOError); return res; @@ -424,7 +454,13 @@ static long msvcrt_set_error_mode_impl(PyObject *module, int mode) /*[clinic end generated code: output=ac4a09040d8ac4e3 input=046fca59c0f20872]*/ { - return _set_error_mode(mode); + long res; + + _Py_BEGIN_SUPPRESS_IPH + res = _set_error_mode(mode); + _Py_END_SUPPRESS_IPH + + return res; } #endif /* _DEBUG */ @@ -443,7 +479,10 @@ msvcrt_SetErrorMode_impl(PyObject *module, unsigned int mode) { unsigned int res; + _Py_BEGIN_SUPPRESS_IPH res = SetErrorMode(mode); + _Py_END_SUPPRESS_IPH + return PyLong_FromUnsignedLong(res); } diff --git a/PC/python3.def b/PC/python3.def index e8d2d8c..ff70718 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -68,6 +68,7 @@ EXPORTS PyCodec_IncrementalEncoder=python36.PyCodec_IncrementalEncoder PyCodec_KnownEncoding=python36.PyCodec_KnownEncoding PyCodec_LookupError=python36.PyCodec_LookupError + PyCodec_NameReplaceErrors=python36.PyCodec_NameReplaceErrors PyCodec_Register=python36.PyCodec_Register PyCodec_RegisterError=python36.PyCodec_RegisterError PyCodec_ReplaceErrors=python36.PyCodec_ReplaceErrors @@ -122,6 +123,7 @@ EXPORTS PyErr_Fetch=python36.PyErr_Fetch PyErr_Format=python36.PyErr_Format PyErr_FormatV=python36.PyErr_FormatV + PyErr_GetExcInfo=python36.PyErr_GetExcInfo PyErr_GivenExceptionMatches=python36.PyErr_GivenExceptionMatches PyErr_NewException=python36.PyErr_NewException PyErr_NewExceptionWithDoc=python36.PyErr_NewExceptionWithDoc @@ -131,15 +133,27 @@ EXPORTS PyErr_Print=python36.PyErr_Print PyErr_PrintEx=python36.PyErr_PrintEx PyErr_ProgramText=python36.PyErr_ProgramText + PyErr_ResourceWarning=python36.PyErr_ResourceWarning PyErr_Restore=python36.PyErr_Restore + PyErr_SetExcFromWindowsErr=python36.PyErr_SetExcFromWindowsErr + PyErr_SetExcFromWindowsErrWithFilename=python36.PyErr_SetExcFromWindowsErrWithFilename + PyErr_SetExcFromWindowsErrWithFilenameObject=python36.PyErr_SetExcFromWindowsErrWithFilenameObject + PyErr_SetExcFromWindowsErrWithFilenameObjects=python36.PyErr_SetExcFromWindowsErrWithFilenameObjects + PyErr_SetExcInfo=python36.PyErr_SetExcInfo PyErr_SetFromErrno=python36.PyErr_SetFromErrno PyErr_SetFromErrnoWithFilename=python36.PyErr_SetFromErrnoWithFilename PyErr_SetFromErrnoWithFilenameObject=python36.PyErr_SetFromErrnoWithFilenameObject + PyErr_SetFromErrnoWithFilenameObjects=python36.PyErr_SetFromErrnoWithFilenameObjects + PyErr_SetFromWindowsErr=python36.PyErr_SetFromWindowsErr + PyErr_SetFromWindowsErrWithFilename=python36.PyErr_SetFromWindowsErrWithFilename + PyErr_SetImportError=python36.PyErr_SetImportError + PyErr_SetImportErrorSubclass=python36.PyErr_SetImportErrorSubclass PyErr_SetInterrupt=python36.PyErr_SetInterrupt PyErr_SetNone=python36.PyErr_SetNone PyErr_SetObject=python36.PyErr_SetObject PyErr_SetString=python36.PyErr_SetString PyErr_SyntaxLocation=python36.PyErr_SyntaxLocation + PyErr_SyntaxLocationEx=python36.PyErr_SyntaxLocationEx PyErr_WarnEx=python36.PyErr_WarnEx PyErr_WarnExplicit=python36.PyErr_WarnExplicit PyErr_WarnFormat=python36.PyErr_WarnFormat @@ -171,12 +185,21 @@ EXPORTS PyExc_AssertionError=python36.PyExc_AssertionError DATA PyExc_AttributeError=python36.PyExc_AttributeError DATA PyExc_BaseException=python36.PyExc_BaseException DATA + PyExc_BlockingIOError=python36.PyExc_BlockingIOError DATA + PyExc_BrokenPipeError=python36.PyExc_BrokenPipeError DATA PyExc_BufferError=python36.PyExc_BufferError DATA PyExc_BytesWarning=python36.PyExc_BytesWarning DATA + PyExc_ChildProcessError=python36.PyExc_ChildProcessError DATA + PyExc_ConnectionAbortedError=python36.PyExc_ConnectionAbortedError DATA + PyExc_ConnectionError=python36.PyExc_ConnectionError DATA + PyExc_ConnectionRefusedError=python36.PyExc_ConnectionRefusedError DATA + PyExc_ConnectionResetError=python36.PyExc_ConnectionResetError DATA PyExc_DeprecationWarning=python36.PyExc_DeprecationWarning DATA PyExc_EOFError=python36.PyExc_EOFError DATA PyExc_EnvironmentError=python36.PyExc_EnvironmentError DATA PyExc_Exception=python36.PyExc_Exception DATA + PyExc_FileExistsError=python36.PyExc_FileExistsError DATA + PyExc_FileNotFoundError=python36.PyExc_FileNotFoundError DATA PyExc_FloatingPointError=python36.PyExc_FloatingPointError DATA PyExc_FutureWarning=python36.PyExc_FutureWarning DATA PyExc_GeneratorExit=python36.PyExc_GeneratorExit DATA @@ -185,26 +208,35 @@ EXPORTS PyExc_ImportWarning=python36.PyExc_ImportWarning DATA PyExc_IndentationError=python36.PyExc_IndentationError DATA PyExc_IndexError=python36.PyExc_IndexError DATA + PyExc_InterruptedError=python36.PyExc_InterruptedError DATA + PyExc_IsADirectoryError=python36.PyExc_IsADirectoryError DATA PyExc_KeyError=python36.PyExc_KeyError DATA PyExc_KeyboardInterrupt=python36.PyExc_KeyboardInterrupt DATA PyExc_LookupError=python36.PyExc_LookupError DATA PyExc_MemoryError=python36.PyExc_MemoryError DATA - PyExc_MemoryErrorInst=python36.PyExc_MemoryErrorInst DATA + PyExc_ModuleNotFoundError=python36.PyExc_ModuleNotFoundError DATA PyExc_NameError=python36.PyExc_NameError DATA + PyExc_NotADirectoryError=python36.PyExc_NotADirectoryError DATA PyExc_NotImplementedError=python36.PyExc_NotImplementedError DATA PyExc_OSError=python36.PyExc_OSError DATA PyExc_OverflowError=python36.PyExc_OverflowError DATA PyExc_PendingDeprecationWarning=python36.PyExc_PendingDeprecationWarning DATA + PyExc_PermissionError=python36.PyExc_PermissionError DATA + PyExc_ProcessLookupError=python36.PyExc_ProcessLookupError DATA + PyExc_RecursionError=python36.PyExc_RecursionError DATA PyExc_RecursionErrorInst=python36.PyExc_RecursionErrorInst DATA PyExc_ReferenceError=python36.PyExc_ReferenceError DATA + PyExc_ResourceWarning=python36.PyExc_ResourceWarning DATA PyExc_RuntimeError=python36.PyExc_RuntimeError DATA PyExc_RuntimeWarning=python36.PyExc_RuntimeWarning DATA + PyExc_StopAsyncIteration=python36.PyExc_StopAsyncIteration DATA PyExc_StopIteration=python36.PyExc_StopIteration DATA PyExc_SyntaxError=python36.PyExc_SyntaxError DATA PyExc_SyntaxWarning=python36.PyExc_SyntaxWarning DATA PyExc_SystemError=python36.PyExc_SystemError DATA PyExc_SystemExit=python36.PyExc_SystemExit DATA PyExc_TabError=python36.PyExc_TabError DATA + PyExc_TimeoutError=python36.PyExc_TimeoutError DATA PyExc_TypeError=python36.PyExc_TypeError DATA PyExc_UnboundLocalError=python36.PyExc_UnboundLocalError DATA PyExc_UnicodeDecodeError=python36.PyExc_UnicodeDecodeError DATA @@ -215,6 +247,7 @@ EXPORTS PyExc_UserWarning=python36.PyExc_UserWarning DATA PyExc_ValueError=python36.PyExc_ValueError DATA PyExc_Warning=python36.PyExc_Warning DATA + PyExc_WindowsError=python36.PyExc_WindowsError DATA PyExc_ZeroDivisionError=python36.PyExc_ZeroDivisionError DATA PyException_GetCause=python36.PyException_GetCause PyException_GetContext=python36.PyException_GetContext @@ -242,10 +275,12 @@ EXPORTS PyGILState_Release=python36.PyGILState_Release PyGetSetDescr_Type=python36.PyGetSetDescr_Type DATA PyImport_AddModule=python36.PyImport_AddModule + PyImport_AddModuleObject=python36.PyImport_AddModuleObject PyImport_AppendInittab=python36.PyImport_AppendInittab PyImport_Cleanup=python36.PyImport_Cleanup PyImport_ExecCodeModule=python36.PyImport_ExecCodeModule PyImport_ExecCodeModuleEx=python36.PyImport_ExecCodeModuleEx + PyImport_ExecCodeModuleObject=python36.PyImport_ExecCodeModuleObject PyImport_ExecCodeModuleWithPathnames=python36.PyImport_ExecCodeModuleWithPathnames PyImport_GetImporter=python36.PyImport_GetImporter PyImport_GetMagicNumber=python36.PyImport_GetMagicNumber @@ -253,8 +288,10 @@ EXPORTS PyImport_GetModuleDict=python36.PyImport_GetModuleDict PyImport_Import=python36.PyImport_Import PyImport_ImportFrozenModule=python36.PyImport_ImportFrozenModule + PyImport_ImportFrozenModuleObject=python36.PyImport_ImportFrozenModuleObject PyImport_ImportModule=python36.PyImport_ImportModule PyImport_ImportModuleLevel=python36.PyImport_ImportModuleLevel + PyImport_ImportModuleLevelObject=python36.PyImport_ImportModuleLevelObject PyImport_ImportModuleNoBlock=python36.PyImport_ImportModuleNoBlock PyImport_ReloadModule=python36.PyImport_ReloadModule PyInterpreterState_Clear=python36.PyInterpreterState_Clear @@ -310,28 +347,36 @@ EXPORTS PyMapping_SetItemString=python36.PyMapping_SetItemString PyMapping_Size=python36.PyMapping_Size PyMapping_Values=python36.PyMapping_Values + PyMem_Calloc=python36.PyMem_Calloc PyMem_Free=python36.PyMem_Free PyMem_Malloc=python36.PyMem_Malloc PyMem_Realloc=python36.PyMem_Realloc PyMemberDescr_Type=python36.PyMemberDescr_Type DATA + PyMemoryView_FromMemory=python36.PyMemoryView_FromMemory PyMemoryView_FromObject=python36.PyMemoryView_FromObject PyMemoryView_GetContiguous=python36.PyMemoryView_GetContiguous PyMemoryView_Type=python36.PyMemoryView_Type DATA PyMethodDescr_Type=python36.PyMethodDescr_Type DATA + PyModuleDef_Init=python36.PyModuleDef_Init + PyModuleDef_Type=python36.PyModuleDef_Type DATA + PyModule_AddFunctions=python36.PyModule_AddFunctions PyModule_AddIntConstant=python36.PyModule_AddIntConstant PyModule_AddObject=python36.PyModule_AddObject PyModule_AddStringConstant=python36.PyModule_AddStringConstant PyModule_Create2=python36.PyModule_Create2 + PyModule_ExecDef=python36.PyModule_ExecDef + PyModule_FromDefAndSpec2=python36.PyModule_FromDefAndSpec2 PyModule_GetDef=python36.PyModule_GetDef PyModule_GetDict=python36.PyModule_GetDict PyModule_GetFilename=python36.PyModule_GetFilename PyModule_GetFilenameObject=python36.PyModule_GetFilenameObject PyModule_GetName=python36.PyModule_GetName + PyModule_GetNameObject=python36.PyModule_GetNameObject PyModule_GetState=python36.PyModule_GetState PyModule_New=python36.PyModule_New + PyModule_NewObject=python36.PyModule_NewObject + PyModule_SetDocString=python36.PyModule_SetDocString PyModule_Type=python36.PyModule_Type DATA - PyModuleDef_Init=python36.PyModuleDef_Init - PyModuleDef_Type=python36.PyModuleDef_Type DATA PyNullImporter_Type=python36.PyNullImporter_Type DATA PyNumber_Absolute=python36.PyNumber_Absolute PyNumber_Add=python36.PyNumber_Add @@ -345,6 +390,7 @@ EXPORTS PyNumber_InPlaceAnd=python36.PyNumber_InPlaceAnd PyNumber_InPlaceFloorDivide=python36.PyNumber_InPlaceFloorDivide PyNumber_InPlaceLshift=python36.PyNumber_InPlaceLshift + PyNumber_InPlaceMatrixMultiply=python36.PyNumber_InPlaceMatrixMultiply PyNumber_InPlaceMultiply=python36.PyNumber_InPlaceMultiply PyNumber_InPlaceOr=python36.PyNumber_InPlaceOr PyNumber_InPlacePower=python36.PyNumber_InPlacePower @@ -357,6 +403,7 @@ EXPORTS PyNumber_Invert=python36.PyNumber_Invert PyNumber_Long=python36.PyNumber_Long PyNumber_Lshift=python36.PyNumber_Lshift + PyNumber_MatrixMultiply=python36.PyNumber_MatrixMultiply PyNumber_Multiply=python36.PyNumber_Multiply PyNumber_Negative=python36.PyNumber_Negative PyNumber_Or=python36.PyNumber_Or @@ -368,7 +415,17 @@ EXPORTS PyNumber_ToBase=python36.PyNumber_ToBase PyNumber_TrueDivide=python36.PyNumber_TrueDivide PyNumber_Xor=python36.PyNumber_Xor + PyODictItems_Type=python36.PyODictItems_Type DATA + PyODictIter_Type=python36.PyODictIter_Type DATA + PyODictKeys_Type=python36.PyODictKeys_Type DATA + PyODictValues_Type=python36.PyODictValues_Type DATA + PyODict_DelItem=python36.PyODict_DelItem + PyODict_New=python36.PyODict_New + PyODict_SetItem=python36.PyODict_SetItem + PyODict_Type=python36.PyODict_Type DATA PyOS_AfterFork=python36.PyOS_AfterFork + PyOS_CheckStack=python36.PyOS_CheckStack + PyOS_FSPath=python36.PyOS_FSPath PyOS_InitInterrupts=python36.PyOS_InitInterrupts PyOS_InputHook=python36.PyOS_InputHook DATA PyOS_InterruptOccurred=python36.PyOS_InterruptOccurred @@ -395,6 +452,7 @@ EXPORTS PyObject_CallMethod=python36.PyObject_CallMethod PyObject_CallMethodObjArgs=python36.PyObject_CallMethodObjArgs PyObject_CallObject=python36.PyObject_CallObject + PyObject_Calloc=python36.PyObject_Calloc PyObject_CheckReadBuffer=python36.PyObject_CheckReadBuffer PyObject_ClearWeakRefs=python36.PyObject_ClearWeakRefs PyObject_DelItem=python36.PyObject_DelItem @@ -407,6 +465,7 @@ EXPORTS PyObject_GC_UnTrack=python36.PyObject_GC_UnTrack PyObject_GenericGetAttr=python36.PyObject_GenericGetAttr PyObject_GenericSetAttr=python36.PyObject_GenericSetAttr + PyObject_GenericSetDict=python36.PyObject_GenericSetDict PyObject_GetAttr=python36.PyObject_GetAttr PyObject_GetAttrString=python36.PyObject_GetAttrString PyObject_GetItem=python36.PyObject_GetItem @@ -433,17 +492,10 @@ EXPORTS PyObject_SetItem=python36.PyObject_SetItem PyObject_Size=python36.PyObject_Size PyObject_Str=python36.PyObject_Str - PyObject_Type=python36.PyObject_Type DATA - PyODict_DelItem=python36.PyODict_DelItem - PyODict_New=python36.PyODict_New - PyODict_SetItem=python36.PyODict_SetItem - PyODict_Type=python36.PyODict_Type DATA - PyODictItems_Type=python36.PyODictItems_Type DATA - PyODictIter_Type=python36.PyODictIter_Type DATA - PyODictKeys_Type=python36.PyODictKeys_Type DATA - PyODictValues_Type=python36.PyODictValues_Type DATA + PyObject_Type=python36.PyObject_Type PyParser_SimpleParseFileFlags=python36.PyParser_SimpleParseFileFlags PyParser_SimpleParseStringFlags=python36.PyParser_SimpleParseStringFlags + PyParser_SimpleParseStringFlagsFilename=python36.PyParser_SimpleParseStringFlagsFilename PyProperty_Type=python36.PyProperty_Type DATA PyRangeIter_Type=python36.PyRangeIter_Type DATA PyRange_Type=python36.PyRange_Type DATA @@ -479,13 +531,15 @@ EXPORTS PySet_Pop=python36.PySet_Pop PySet_Size=python36.PySet_Size PySet_Type=python36.PySet_Type DATA + PySlice_AdjustIndices=python36.PySlice_AdjustIndices PySlice_GetIndices=python36.PySlice_GetIndices PySlice_GetIndicesEx=python36.PySlice_GetIndicesEx PySlice_New=python36.PySlice_New PySlice_Type=python36.PySlice_Type DATA + PySlice_Unpack=python36.PySlice_Unpack PySortWrapper_Type=python36.PySortWrapper_Type DATA - PyState_FindModule=python36.PyState_FindModule PyState_AddModule=python36.PyState_AddModule + PyState_FindModule=python36.PyState_FindModule PyState_RemoveModule=python36.PyState_RemoveModule PyStructSequence_GetItem=python36.PyStructSequence_GetItem PyStructSequence_New=python36.PyStructSequence_New @@ -494,9 +548,11 @@ EXPORTS PySuper_Type=python36.PySuper_Type DATA PySys_AddWarnOption=python36.PySys_AddWarnOption PySys_AddWarnOptionUnicode=python36.PySys_AddWarnOptionUnicode + PySys_AddXOption=python36.PySys_AddXOption PySys_FormatStderr=python36.PySys_FormatStderr PySys_FormatStdout=python36.PySys_FormatStdout PySys_GetObject=python36.PySys_GetObject + PySys_GetXOptions=python36.PySys_GetXOptions PySys_HasWarnOptions=python36.PySys_HasWarnOptions PySys_ResetWarnOptions=python36.PySys_ResetWarnOptions PySys_SetArgv=python36.PySys_SetArgv @@ -571,34 +627,51 @@ EXPORTS PyUnicode_AsEncodedString=python36.PyUnicode_AsEncodedString PyUnicode_AsEncodedUnicode=python36.PyUnicode_AsEncodedUnicode PyUnicode_AsLatin1String=python36.PyUnicode_AsLatin1String + PyUnicode_AsMBCSString=python36.PyUnicode_AsMBCSString PyUnicode_AsRawUnicodeEscapeString=python36.PyUnicode_AsRawUnicodeEscapeString + PyUnicode_AsUCS4=python36.PyUnicode_AsUCS4 + PyUnicode_AsUCS4Copy=python36.PyUnicode_AsUCS4Copy PyUnicode_AsUTF16String=python36.PyUnicode_AsUTF16String PyUnicode_AsUTF32String=python36.PyUnicode_AsUTF32String PyUnicode_AsUTF8String=python36.PyUnicode_AsUTF8String PyUnicode_AsUnicodeEscapeString=python36.PyUnicode_AsUnicodeEscapeString PyUnicode_AsWideChar=python36.PyUnicode_AsWideChar - PyUnicode_ClearFreelist=python36.PyUnicode_ClearFreelist + PyUnicode_AsWideCharString=python36.PyUnicode_AsWideCharString + PyUnicode_BuildEncodingMap=python36.PyUnicode_BuildEncodingMap + PyUnicode_ClearFreeList=python36.PyUnicode_ClearFreeList PyUnicode_Compare=python36.PyUnicode_Compare + PyUnicode_CompareWithASCIIString=python36.PyUnicode_CompareWithASCIIString PyUnicode_Concat=python36.PyUnicode_Concat PyUnicode_Contains=python36.PyUnicode_Contains PyUnicode_Count=python36.PyUnicode_Count PyUnicode_Decode=python36.PyUnicode_Decode PyUnicode_DecodeASCII=python36.PyUnicode_DecodeASCII PyUnicode_DecodeCharmap=python36.PyUnicode_DecodeCharmap + PyUnicode_DecodeCodePageStateful=python36.PyUnicode_DecodeCodePageStateful PyUnicode_DecodeFSDefault=python36.PyUnicode_DecodeFSDefault PyUnicode_DecodeFSDefaultAndSize=python36.PyUnicode_DecodeFSDefaultAndSize PyUnicode_DecodeLatin1=python36.PyUnicode_DecodeLatin1 + PyUnicode_DecodeLocale=python36.PyUnicode_DecodeLocale + PyUnicode_DecodeLocaleAndSize=python36.PyUnicode_DecodeLocaleAndSize + PyUnicode_DecodeMBCS=python36.PyUnicode_DecodeMBCS + PyUnicode_DecodeMBCSStateful=python36.PyUnicode_DecodeMBCSStateful PyUnicode_DecodeRawUnicodeEscape=python36.PyUnicode_DecodeRawUnicodeEscape PyUnicode_DecodeUTF16=python36.PyUnicode_DecodeUTF16 PyUnicode_DecodeUTF16Stateful=python36.PyUnicode_DecodeUTF16Stateful PyUnicode_DecodeUTF32=python36.PyUnicode_DecodeUTF32 PyUnicode_DecodeUTF32Stateful=python36.PyUnicode_DecodeUTF32Stateful + PyUnicode_DecodeUTF7=python36.PyUnicode_DecodeUTF7 + PyUnicode_DecodeUTF7Stateful=python36.PyUnicode_DecodeUTF7Stateful PyUnicode_DecodeUTF8=python36.PyUnicode_DecodeUTF8 PyUnicode_DecodeUTF8Stateful=python36.PyUnicode_DecodeUTF8Stateful PyUnicode_DecodeUnicodeEscape=python36.PyUnicode_DecodeUnicodeEscape + PyUnicode_EncodeCodePage=python36.PyUnicode_EncodeCodePage + PyUnicode_EncodeFSDefault=python36.PyUnicode_EncodeFSDefault + PyUnicode_EncodeLocale=python36.PyUnicode_EncodeLocale PyUnicode_FSConverter=python36.PyUnicode_FSConverter PyUnicode_FSDecoder=python36.PyUnicode_FSDecoder PyUnicode_Find=python36.PyUnicode_Find + PyUnicode_FindChar=python36.PyUnicode_FindChar PyUnicode_Format=python36.PyUnicode_Format PyUnicode_FromEncodedObject=python36.PyUnicode_FromEncodedObject PyUnicode_FromFormat=python36.PyUnicode_FromFormat @@ -609,30 +682,28 @@ EXPORTS PyUnicode_FromStringAndSize=python36.PyUnicode_FromStringAndSize PyUnicode_FromWideChar=python36.PyUnicode_FromWideChar PyUnicode_GetDefaultEncoding=python36.PyUnicode_GetDefaultEncoding + PyUnicode_GetLength=python36.PyUnicode_GetLength PyUnicode_GetSize=python36.PyUnicode_GetSize + PyUnicode_InternFromString=python36.PyUnicode_InternFromString + PyUnicode_InternImmortal=python36.PyUnicode_InternImmortal + PyUnicode_InternInPlace=python36.PyUnicode_InternInPlace PyUnicode_IsIdentifier=python36.PyUnicode_IsIdentifier PyUnicode_Join=python36.PyUnicode_Join PyUnicode_Partition=python36.PyUnicode_Partition PyUnicode_RPartition=python36.PyUnicode_RPartition PyUnicode_RSplit=python36.PyUnicode_RSplit + PyUnicode_ReadChar=python36.PyUnicode_ReadChar PyUnicode_Replace=python36.PyUnicode_Replace PyUnicode_Resize=python36.PyUnicode_Resize PyUnicode_RichCompare=python36.PyUnicode_RichCompare - PyUnicode_SetDefaultEncoding=python36.PyUnicode_SetDefaultEncoding PyUnicode_Split=python36.PyUnicode_Split PyUnicode_Splitlines=python36.PyUnicode_Splitlines + PyUnicode_Substring=python36.PyUnicode_Substring PyUnicode_Tailmatch=python36.PyUnicode_Tailmatch PyUnicode_Translate=python36.PyUnicode_Translate - PyUnicode_BuildEncodingMap=python36.PyUnicode_BuildEncodingMap - PyUnicode_CompareWithASCIIString=python36.PyUnicode_CompareWithASCIIString - PyUnicode_DecodeUTF7=python36.PyUnicode_DecodeUTF7 - PyUnicode_DecodeUTF7Stateful=python36.PyUnicode_DecodeUTF7Stateful - PyUnicode_EncodeFSDefault=python36.PyUnicode_EncodeFSDefault - PyUnicode_InternFromString=python36.PyUnicode_InternFromString - PyUnicode_InternImmortal=python36.PyUnicode_InternImmortal - PyUnicode_InternInPlace=python36.PyUnicode_InternInPlace PyUnicode_Type=python36.PyUnicode_Type DATA - PyWeakref_GetObject=python36.PyWeakref_GetObject DATA + PyUnicode_WriteChar=python36.PyUnicode_WriteChar + PyWeakref_GetObject=python36.PyWeakref_GetObject PyWeakref_NewProxy=python36.PyWeakref_NewProxy PyWeakref_NewRef=python36.PyWeakref_NewRef PyWrapperDescr_Type=python36.PyWrapperDescr_Type DATA @@ -643,9 +714,12 @@ EXPORTS Py_BuildValue=python36.Py_BuildValue Py_CompileString=python36.Py_CompileString Py_DecRef=python36.Py_DecRef + Py_DecodeLocale=python36.Py_DecodeLocale + Py_EncodeLocale=python36.Py_EncodeLocale Py_EndInterpreter=python36.Py_EndInterpreter Py_Exit=python36.Py_Exit Py_FatalError=python36.Py_FatalError + Py_FileSystemDefaultEncodeErrors=python36.Py_FileSystemDefaultEncodeErrors DATA Py_FileSystemDefaultEncoding=python36.Py_FileSystemDefaultEncoding DATA Py_Finalize=python36.Py_Finalize Py_FinalizeEx=python36.Py_FinalizeEx @@ -671,11 +745,17 @@ EXPORTS Py_NewInterpreter=python36.Py_NewInterpreter Py_ReprEnter=python36.Py_ReprEnter Py_ReprLeave=python36.Py_ReprLeave + Py_SetPath=python36.Py_SetPath Py_SetProgramName=python36.Py_SetProgramName Py_SetPythonHome=python36.Py_SetPythonHome Py_SetRecursionLimit=python36.Py_SetRecursionLimit Py_SymtableString=python36.Py_SymtableString Py_VaBuildValue=python36.Py_VaBuildValue + _PyArg_ParseTupleAndKeywords_SizeT=python36._PyArg_ParseTupleAndKeywords_SizeT + _PyArg_ParseTuple_SizeT=python36._PyArg_ParseTuple_SizeT + _PyArg_Parse_SizeT=python36._PyArg_Parse_SizeT + _PyArg_VaParseTupleAndKeywords_SizeT=python36._PyArg_VaParseTupleAndKeywords_SizeT + _PyArg_VaParse_SizeT=python36._PyArg_VaParse_SizeT _PyErr_BadInternalCall=python36._PyErr_BadInternalCall _PyObject_CallFunction_SizeT=python36._PyObject_CallFunction_SizeT _PyObject_CallMethod_SizeT=python36._PyObject_CallMethod_SizeT @@ -692,6 +772,8 @@ EXPORTS _PyTrash_delete_nesting=python36._PyTrash_delete_nesting DATA _PyTrash_deposit_object=python36._PyTrash_deposit_object _PyTrash_destroy_chain=python36._PyTrash_destroy_chain + _PyTrash_thread_deposit_object=python36._PyTrash_thread_deposit_object + _PyTrash_thread_destroy_chain=python36._PyTrash_thread_destroy_chain _PyWeakref_CallableProxyType=python36._PyWeakref_CallableProxyType DATA _PyWeakref_ProxyType=python36._PyWeakref_ProxyType DATA _PyWeakref_RefType=python36._PyWeakref_RefType DATA @@ -706,9 +788,3 @@ EXPORTS _Py_SwappedOp=python36._Py_SwappedOp DATA _Py_TrueStruct=python36._Py_TrueStruct DATA _Py_VaBuildValue_SizeT=python36._Py_VaBuildValue_SizeT - _PyArg_Parse_SizeT=python36._PyArg_Parse_SizeT - _PyArg_ParseTuple_SizeT=python36._PyArg_ParseTuple_SizeT - _PyArg_ParseTupleAndKeywords_SizeT=python36._PyArg_ParseTupleAndKeywords_SizeT - _PyArg_VaParse_SizeT=python36._PyArg_VaParse_SizeT - _PyArg_VaParseTupleAndKeywords_SizeT=python36._PyArg_VaParseTupleAndKeywords_SizeT - _Py_BuildValue_SizeT=python36._Py_BuildValue_SizeT diff --git a/PC/winreg.c b/PC/winreg.c index 9524838..5efdc5e 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -719,14 +719,13 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) case REG_SZ: case REG_EXPAND_SZ: { - /* the buffer may or may not have a trailing NULL */ + /* REG_SZ should be a NUL terminated string, but only by + * convention. The buffer may have been saved without a NUL + * or with embedded NULs. To be consistent with reg.exe and + * regedit.exe, consume only up to the first NUL. */ wchar_t *data = (wchar_t *)retDataBuf; - int len = retDataSize / 2; - if (retDataSize && data[len-1] == '\0') - retDataSize -= 2; - if (retDataSize <= 0) - data = L""; - obData = PyUnicode_FromWideChar(data, retDataSize/2); + size_t len = wcsnlen(data, retDataSize / sizeof(wchar_t)); + obData = PyUnicode_FromWideChar(data, len); break; } case REG_MULTI_SZ: diff --git a/PCbuild/_freeze_importlib.vcxproj b/PCbuild/_freeze_importlib.vcxproj index f7714c0..c732663 100644 --- a/PCbuild/_freeze_importlib.vcxproj +++ b/PCbuild/_freeze_importlib.vcxproj @@ -76,31 +76,44 @@ - + + $(IntDir)importlib.g.h + $(PySourcePath)Python\importlib.h + + + $(IntDir)importlib_external.g.h + $(PySourcePath)Python\importlib_external.h + - - + + - <_OldContent Condition="Exists('$(PySourcePath)Python\importlib.h')">$([System.IO.File]::ReadAllText('$(PySourcePath)Python\importlib.h').Replace(` `, ` `)) - <_NewContent Condition="Exists('$(IntDir)importlib.g.h')">$([System.IO.File]::ReadAllText('$(IntDir)importlib.g.h').Replace(` `, ` `)) + <_OldContent Condition="Exists($(OutTargetPath))"> + <_NewContent Condition="Exists($(IntTargetPath))">$([System.IO.File]::ReadAllText($(IntTargetPath)).Replace(` `, ` `)) - + + + - - + + + + + diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 1ad58f8..f7f2858 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -105,8 +105,9 @@ if "%platf%"=="x64" ( ) ) -if not exist "%HG%" where hg > "%TEMP%\hg.loc" 2> nul && set /P HG= < "%TEMP%\hg.loc" & del "%TEMP%\hg.loc" -if not exist "%HG%" echo Cannot find Mercurial on PATH && exit /B 1 +if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" +if exist "%GIT%" set GITProperty=/p:GIT="%GIT%" +if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty= rem Setup the environment call "%dir%env.bat" %vs_platf% >nul @@ -144,8 +145,7 @@ msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ /p:Configuration=%conf% /p:Platform=%platf%^ /p:IncludeExternals=%IncludeExternals%^ /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ - /p:UseTestMarker=%UseTestMarker%^ - /p:HG="%HG%"^ + /p:UseTestMarker=%UseTestMarker% %GITProperty%^ %1 %2 %3 %4 %5 %6 %7 %8 %9 @echo off diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index a5185be..98a755d 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -54,7 +54,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.6 if NOT "%IncludeSSL%"=="false" set libraries=%libraries% nasm-2.11.06 -if NOT "%IncludeSSL%"=="false" set libraries=%libraries% openssl-1.0.2j +if NOT "%IncludeSSL%"=="false" set libraries=%libraries% openssl-1.0.2k set libraries=%libraries% sqlite-3.14.2.0 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tcl-core-8.6.6.0 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tk-8.6.6.0 diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj index e0e6e93..c6b8487 100644 --- a/PCbuild/pcbuild.proj +++ b/PCbuild/pcbuild.proj @@ -28,7 +28,7 @@ Build Clean CleanAll - true + false @@ -48,8 +48,6 @@ - - @@ -68,10 +66,10 @@ false + + - - false - + diff --git a/PCbuild/python.props b/PCbuild/python.props index dde94f7..d6bfd08 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -45,7 +45,7 @@ $(ExternalsDir)sqlite-3.14.2.0\ $(ExternalsDir)bzip2-1.0.6\ $(ExternalsDir)xz-5.2.2\ - $(ExternalsDir)openssl-1.0.2j\ + $(ExternalsDir)openssl-1.0.2k\ $(opensslDir)include32 $(opensslDir)include64 $(ExternalsDir)\nasm-2.11.06\ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 6b23d8e..6ea1848 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -407,24 +407,24 @@ - hg - <_HG>$(HG) - <_HG Condition="$(HG.Contains(` `))">"$(HG)" + git + <_GIT>$(GIT) + <_GIT Condition="$(GIT.Contains(` `))">"$(GIT)" - + - - - + + + - $([System.IO.File]::ReadAllText('$(IntDir)hgbranch.txt').Trim()) - $([System.IO.File]::ReadAllText('$(IntDir)hgversion.txt').Trim()) - $([System.IO.File]::ReadAllText('$(IntDir)hgtag.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)gitbranch.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)gitversion.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)gittag.txt').Trim()) - + - HGVERSION="$(HgVersion)";HGTAG="$(HgTag)";HGBRANCH="$(HgBranch)";%(PreprocessorDefinitions) + GITVERSION="$(GitVersion)";GITTAG="$(GitTag)";GITBRANCH="$(GitBranch)";%(PreprocessorDefinitions) diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index c04ba4e..8924b3f 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -169,7 +169,7 @@ _lzma Homepage: http://tukaani.org/xz/ _ssl - Python wrapper for version 1.0.2j of the OpenSSL secure sockets + Python wrapper for version 1.0.2k of the OpenSSL secure sockets library, which is built by ssl.vcxproj Homepage: http://www.openssl.org/ diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 0fa3aeb..ff65f2a 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -1508,7 +1508,7 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) /* Identifier (most frequent token!) */ nonascii = 0; if (is_potential_identifier_start(c)) { - /* Process b"", r"", u"", br"" and rb"" */ + /* Process the various legal combinations of b"", r"", u"", and f"". */ int saw_b = 0, saw_r = 0, saw_u = 0, saw_f = 0; while (1) { if (!(saw_b || saw_u || saw_f) && (c == 'b' || c == 'B')) diff --git a/Python/ast.c b/Python/ast.c index 82f4529..217ea14 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -4789,6 +4789,7 @@ ExprList_Finish(ExprList *l, PyArena *arena) typedef struct { PyObject *last_str; ExprList expr_list; + int fmode; } FstringParser; #ifdef NDEBUG @@ -4807,6 +4808,7 @@ static void FstringParser_Init(FstringParser *state) { state->last_str = NULL; + state->fmode = 0; ExprList_Init(&state->expr_list); FstringParser_check_invariants(state); } @@ -4869,6 +4871,7 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str, struct compiling *c, const node *n) { FstringParser_check_invariants(state); + state->fmode = 1; /* Parse the f-string. */ while (1) { @@ -4960,7 +4963,8 @@ FstringParser_Finish(FstringParser *state, struct compiling *c, /* If we're just a constant string with no expressions, return that. */ - if(state->expr_list.size == 0) { + if (!state->fmode) { + assert(!state->expr_list.size); if (!state->last_str) { /* Create a zero length string. */ state->last_str = PyUnicode_FromStringAndSize(NULL, 0); @@ -4984,11 +4988,6 @@ FstringParser_Finish(FstringParser *state, struct compiling *c, if (!seq) goto error; - /* If there's only one expression, return it. Otherwise, we need - to join them together. */ - if (seq->size == 1) - return seq->elements[0]; - return JoinedStr(seq, LINENO(n), n->n_col_offset, c->c_arena); error: diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 69e5f08..ef5a34c 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2107,7 +2107,7 @@ reverse flag can be set to request the result in descending order. [end disabled clinic input]*/ PyDoc_STRVAR(builtin_sorted__doc__, -"sorted($module, iterable, key=None, reverse=False)\n" +"sorted($module, iterable, /, *, key=None, reverse=False)\n" "--\n" "\n" "Return a new list containing all items from the iterable in ascending order.\n" @@ -2123,7 +2123,7 @@ builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *newlist, *v, *seq, *keyfunc=NULL, **newargs; PyObject *callable; - static char *kwlist[] = {"iterable", "key", "reverse", 0}; + static char *kwlist[] = {"", "key", "reverse", 0}; int reverse; Py_ssize_t nargs; @@ -2142,6 +2142,7 @@ builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } + assert(PyTuple_GET_SIZE(args) >= 1); newargs = &PyTuple_GET_ITEM(args, 1); nargs = PyTuple_GET_SIZE(args) - 1; v = _PyObject_FastCallDict(callable, newargs, nargs, kwds); diff --git a/Python/ceval.c b/Python/ceval.c index d5172b9..9cac771 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1409,9 +1409,15 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) TARGET(BINARY_MODULO) { PyObject *divisor = POP(); PyObject *dividend = TOP(); - PyObject *res = PyUnicode_CheckExact(dividend) ? - PyUnicode_Format(dividend, divisor) : - PyNumber_Remainder(dividend, divisor); + PyObject *res; + if (PyUnicode_CheckExact(dividend) && ( + !PyUnicode_Check(divisor) || PyUnicode_CheckExact(divisor))) { + // fast path; string formatting, but not if the RHS is a str subclass + // (see issue28598) + res = PyUnicode_Format(dividend, divisor); + } else { + res = PyNumber_Remainder(dividend, divisor); + } Py_DECREF(divisor); Py_DECREF(dividend); SET_TOP(res); @@ -1898,13 +1904,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) awaitable = _PyCoro_GetAwaitableIter(iter); if (awaitable == NULL) { - SET_TOP(NULL); - PyErr_Format( + _PyErr_FormatFromCause( PyExc_TypeError, "'async for' received an invalid object " "from __aiter__: %.100s", Py_TYPE(iter)->tp_name); + SET_TOP(NULL); Py_DECREF(iter); goto error; } else { @@ -1963,7 +1969,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) awaitable = _PyCoro_GetAwaitableIter(next_iter); if (awaitable == NULL) { - PyErr_Format( + _PyErr_FormatFromCause( PyExc_TypeError, "'async for' received an invalid object " "from __anext__: %.100s", @@ -2851,13 +2857,16 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) TARGET(IMPORT_STAR) { PyObject *from = POP(), *locals; int err; - if (PyFrame_FastToLocalsWithError(f) < 0) + if (PyFrame_FastToLocalsWithError(f) < 0) { + Py_DECREF(from); goto error; + } locals = f->f_locals; if (locals == NULL) { PyErr_SetString(PyExc_SystemError, "no locals found during 'import *'"); + Py_DECREF(from); goto error; } err = import_all_from(locals, from); @@ -4690,11 +4699,7 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *args, PyObject *kwargs) assert(!PyErr_Occurred()); #endif - if (args == NULL) { - return _PyObject_FastCallDict(func, NULL, 0, kwargs); - } - - if (!PyTuple_Check(args)) { + if (args != NULL && !PyTuple_Check(args)) { PyErr_SetString(PyExc_TypeError, "argument list must be a tuple"); return NULL; @@ -4706,7 +4711,12 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *args, PyObject *kwargs) return NULL; } - return PyObject_Call(func, args, kwargs); + if (args == NULL) { + return _PyObject_FastCallDict(func, NULL, 0, kwargs); + } + else { + return PyObject_Call(func, args, kwargs); + } } const char * diff --git a/Python/compile.c b/Python/compile.c index 35151cd..6255ec7 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1043,7 +1043,7 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) case CALL_FUNCTION_KW: return -oparg-1; case CALL_FUNCTION_EX: - return - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0); + return -1 - ((oparg & 0x01) != 0); case MAKE_FUNCTION: return -1 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) - ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0); @@ -3415,7 +3415,8 @@ static int compiler_joined_str(struct compiler *c, expr_ty e) { VISIT_SEQ(c, expr, e->v.JoinedStr.values); - ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); + if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) + ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); return 1; } diff --git a/Python/errors.c b/Python/errors.c index 7b25a22..6095843 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1059,16 +1059,15 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) PyErr_Clear(); Py_DECREF(tmp); } + tmp = NULL; if (col_offset >= 0) { tmp = PyLong_FromLong(col_offset); if (tmp == NULL) PyErr_Clear(); - else { - if (_PyObject_SetAttrId(v, &PyId_offset, tmp)) - PyErr_Clear(); - Py_DECREF(tmp); - } } + if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) + PyErr_Clear(); + Py_XDECREF(tmp); if (filename != NULL) { if (_PyObject_SetAttrId(v, &PyId_filename, filename)) PyErr_Clear(); @@ -1080,9 +1079,6 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) Py_DECREF(tmp); } } - if (_PyObject_SetAttrId(v, &PyId_offset, Py_None)) { - PyErr_Clear(); - } if (exc != PyExc_SyntaxError) { if (!_PyObject_HasAttrId(v, &PyId_msg)) { tmp = PyObject_Str(v); @@ -1148,11 +1144,8 @@ err_programtext(FILE *fp, int lineno) } fclose(fp); if (i == lineno) { - char *p = linebuf; PyObject *res; - while (*p == ' ' || *p == '\t' || *p == '\014') - p++; - res = PyUnicode_FromString(p); + res = PyUnicode_FromString(linebuf); if (res == NULL) PyErr_Clear(); return res; diff --git a/Python/fileutils.c b/Python/fileutils.c index 6a32c42..e84d66e 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -20,7 +20,7 @@ extern int winerror_to_errno(int); #include #endif /* HAVE_FCNTL_H */ -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(__ANDROID__) extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); #endif @@ -273,7 +273,7 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) wchar_t* Py_DecodeLocale(const char* arg, size_t *size) { -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(__ANDROID__) wchar_t *wstr; wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); if (size != NULL) { @@ -406,7 +406,7 @@ oom: if (size != NULL) *size = (size_t)-1; return NULL; -#endif /* __APPLE__ */ +#endif /* __APPLE__ or __ANDROID__ */ } /* Encode a wide character string to the locale encoding with the @@ -424,7 +424,7 @@ oom: char* Py_EncodeLocale(const wchar_t *text, size_t *error_pos) { -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(__ANDROID__) Py_ssize_t len; PyObject *unicode, *bytes = NULL; char *cpath; @@ -522,7 +522,7 @@ Py_EncodeLocale(const wchar_t *text, size_t *error_pos) bytes = result; } return result; -#endif /* __APPLE__ */ +#endif /* __APPLE__ or __ANDROID__ */ } diff --git a/Python/getcopyright.c b/Python/getcopyright.c index c3f1e89..cac647c 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static const char cprt[] = "\ -Copyright (c) 2001-2016 Python Software Foundation.\n\ +Copyright (c) 2001-2017 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/Python/importlib.h b/Python/importlib.h index 195fbfd..4607c40 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -392,7 +392,7 @@ const unsigned char _Py_M__importlib[] = { 111,118,101,100,197,0,0,0,115,2,0,0,0,0,8,114, 58,0,0,0,114,33,0,0,0,41,1,218,9,118,101,114, 98,111,115,105,116,121,99,1,0,0,0,1,0,0,0,3, - 0,0,0,5,0,0,0,71,0,0,0,115,54,0,0,0, + 0,0,0,4,0,0,0,71,0,0,0,115,54,0,0,0, 116,0,106,1,106,2,124,1,107,5,114,50,124,0,106,3, 100,6,131,1,115,30,100,3,124,0,23,0,125,0,116,4, 124,0,106,5,124,2,142,0,116,0,106,6,100,4,141,2, diff --git a/Python/importlib_external.h b/Python/importlib_external.h index 1b767c5..886aa68 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -578,7 +578,7 @@ const unsigned char _Py_M__importlib_external[] = { 218,17,95,102,105,110,100,95,109,111,100,117,108,101,95,115, 104,105,109,157,1,0,0,115,10,0,0,0,0,10,14,1, 16,1,4,1,22,1,114,127,0,0,0,99,4,0,0,0, - 0,0,0,0,11,0,0,0,22,0,0,0,67,0,0,0, + 0,0,0,0,11,0,0,0,19,0,0,0,67,0,0,0, 115,136,1,0,0,105,0,125,4,124,2,100,1,107,9,114, 22,124,2,124,4,100,2,60,0,110,4,100,3,125,2,124, 3,100,1,107,9,114,42,124,3,124,4,100,4,60,0,124, @@ -2334,7 +2334,7 @@ const unsigned char _Py_M__importlib_external[] = { 111,111,116,115,116,114,97,112,32,109,111,100,117,108,101,46, 10,10,32,32,32,32,114,52,0,0,0,114,63,0,0,0, 218,8,98,117,105,108,116,105,110,115,114,140,0,0,0,90, - 5,112,111,115,105,120,250,1,47,218,2,110,116,250,1,92, + 5,112,111,115,105,120,250,1,47,90,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,26,0,0,0,124,0,93,18,125,1, 116,0,124,1,131,1,100,0,107,2,86,0,1,0,113,2, @@ -2376,61 +2376,58 @@ const unsigned char _Py_M__importlib_external[] = { 1,10,1,4,2,2,1,10,1,6,1,14,1,12,2,8, 1,12,1,12,1,18,3,2,1,14,1,16,2,10,1,12, 3,10,1,12,3,10,1,10,1,12,3,14,1,14,1,10, - 1,10,1,10,1,114,32,1,0,0,99,1,0,0,0,0, + 1,10,1,10,1,114,31,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, - 72,0,0,0,116,0,124,0,131,1,1,0,116,1,131,0, + 50,0,0,0,116,0,124,0,131,1,1,0,116,1,131,0, 125,1,116,2,106,3,106,4,116,5,106,6,124,1,142,0, - 103,1,131,1,1,0,116,7,106,8,100,1,107,2,114,56, - 116,2,106,9,106,10,116,11,131,1,1,0,116,2,106,9, - 106,10,116,12,131,1,1,0,100,2,83,0,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,27,1,0,0,78,41, - 13,114,32,1,0,0,114,159,0,0,0,114,8,0,0,0, - 114,253,0,0,0,114,147,0,0,0,114,5,1,0,0,114, - 18,1,0,0,114,3,0,0,0,114,109,0,0,0,218,9, - 109,101,116,97,95,112,97,116,104,114,161,0,0,0,114,166, - 0,0,0,114,248,0,0,0,41,2,114,31,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,6,0,0, - 0,218,8,95,105,110,115,116,97,108,108,158,5,0,0,115, - 12,0,0,0,0,2,8,1,6,1,20,1,10,1,12,1, - 114,34,1,0,0,41,1,114,0,0,0,0,41,2,114,1, - 0,0,0,114,2,0,0,0,41,1,114,49,0,0,0,41, - 1,78,41,3,78,78,78,41,3,78,78,78,41,2,114,62, - 0,0,0,114,62,0,0,0,41,1,78,41,1,78,41,58, - 114,111,0,0,0,114,12,0,0,0,90,37,95,67,65,83, - 69,95,73,78,83,69,78,83,73,84,73,86,69,95,80,76, - 65,84,70,79,82,77,83,95,66,89,84,69,83,95,75,69, - 89,114,11,0,0,0,114,13,0,0,0,114,19,0,0,0, - 114,21,0,0,0,114,30,0,0,0,114,40,0,0,0,114, - 41,0,0,0,114,45,0,0,0,114,46,0,0,0,114,48, - 0,0,0,114,58,0,0,0,218,4,116,121,112,101,218,8, - 95,95,99,111,100,101,95,95,114,142,0,0,0,114,17,0, - 0,0,114,132,0,0,0,114,16,0,0,0,114,20,0,0, - 0,90,17,95,82,65,87,95,77,65,71,73,67,95,78,85, - 77,66,69,82,114,77,0,0,0,114,76,0,0,0,114,88, - 0,0,0,114,78,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,83, - 0,0,0,114,89,0,0,0,114,95,0,0,0,114,99,0, - 0,0,114,101,0,0,0,114,120,0,0,0,114,127,0,0, - 0,114,139,0,0,0,114,145,0,0,0,114,148,0,0,0, - 114,153,0,0,0,218,6,111,98,106,101,99,116,114,160,0, - 0,0,114,165,0,0,0,114,166,0,0,0,114,181,0,0, - 0,114,191,0,0,0,114,207,0,0,0,114,215,0,0,0, - 114,220,0,0,0,114,226,0,0,0,114,221,0,0,0,114, - 227,0,0,0,114,246,0,0,0,114,248,0,0,0,114,5, - 1,0,0,114,23,1,0,0,114,159,0,0,0,114,32,1, - 0,0,114,34,1,0,0,114,4,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,6,0,0,0,218,8,60,109,111, - 100,117,108,101,62,8,0,0,0,115,108,0,0,0,4,16, - 4,1,4,1,2,1,6,3,8,17,8,5,8,5,8,6, - 8,12,8,10,8,9,8,5,8,7,10,22,10,123,16,1, - 12,2,4,1,4,2,6,2,6,2,8,2,16,45,8,34, - 8,19,8,12,8,12,8,28,8,17,10,55,10,12,10,10, - 8,14,6,3,4,1,14,67,14,64,14,29,16,110,14,41, - 18,45,18,16,4,3,18,53,14,60,14,42,14,127,0,5, - 14,127,0,22,10,23,8,11,8,68, + 103,1,131,1,1,0,116,2,106,7,106,8,116,9,131,1, + 1,0,100,1,83,0,41,2,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,78,41,10,114,31,1,0,0,114,159,0,0,0, + 114,8,0,0,0,114,253,0,0,0,114,147,0,0,0,114, + 5,1,0,0,114,18,1,0,0,218,9,109,101,116,97,95, + 112,97,116,104,114,161,0,0,0,114,248,0,0,0,41,2, + 114,30,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,6,0,0,0,218,8,95,105,110,115,116,97,108, + 108,158,5,0,0,115,8,0,0,0,0,2,8,1,6,1, + 20,1,114,33,1,0,0,41,1,114,0,0,0,0,41,2, + 114,1,0,0,0,114,2,0,0,0,41,1,114,49,0,0, + 0,41,1,78,41,3,78,78,78,41,3,78,78,78,41,2, + 114,62,0,0,0,114,62,0,0,0,41,1,78,41,1,78, + 41,58,114,111,0,0,0,114,12,0,0,0,90,37,95,67, + 65,83,69,95,73,78,83,69,78,83,73,84,73,86,69,95, + 80,76,65,84,70,79,82,77,83,95,66,89,84,69,83,95, + 75,69,89,114,11,0,0,0,114,13,0,0,0,114,19,0, + 0,0,114,21,0,0,0,114,30,0,0,0,114,40,0,0, + 0,114,41,0,0,0,114,45,0,0,0,114,46,0,0,0, + 114,48,0,0,0,114,58,0,0,0,218,4,116,121,112,101, + 218,8,95,95,99,111,100,101,95,95,114,142,0,0,0,114, + 17,0,0,0,114,132,0,0,0,114,16,0,0,0,114,20, + 0,0,0,90,17,95,82,65,87,95,77,65,71,73,67,95, + 78,85,77,66,69,82,114,77,0,0,0,114,76,0,0,0, + 114,88,0,0,0,114,78,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,83,0,0,0,114,89,0,0,0,114,95,0,0,0,114, + 99,0,0,0,114,101,0,0,0,114,120,0,0,0,114,127, + 0,0,0,114,139,0,0,0,114,145,0,0,0,114,148,0, + 0,0,114,153,0,0,0,218,6,111,98,106,101,99,116,114, + 160,0,0,0,114,165,0,0,0,114,166,0,0,0,114,181, + 0,0,0,114,191,0,0,0,114,207,0,0,0,114,215,0, + 0,0,114,220,0,0,0,114,226,0,0,0,114,221,0,0, + 0,114,227,0,0,0,114,246,0,0,0,114,248,0,0,0, + 114,5,1,0,0,114,23,1,0,0,114,159,0,0,0,114, + 31,1,0,0,114,33,1,0,0,114,4,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,6,0,0,0,218,8,60, + 109,111,100,117,108,101,62,8,0,0,0,115,108,0,0,0, + 4,16,4,1,4,1,2,1,6,3,8,17,8,5,8,5, + 8,6,8,12,8,10,8,9,8,5,8,7,10,22,10,123, + 16,1,12,2,4,1,4,2,6,2,6,2,8,2,16,45, + 8,34,8,19,8,12,8,12,8,28,8,17,10,55,10,12, + 10,10,8,14,6,3,4,1,14,67,14,64,14,29,16,110, + 14,41,18,45,18,16,4,3,18,53,14,60,14,42,14,127, + 0,5,14,127,0,22,10,23,8,11,8,68, }; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index c881f90..8befa54 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -528,7 +528,7 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj) offset -= (int)(nl+1-text); text = nl+1; } - while (*text == ' ' || *text == '\t') { + while (*text == ' ' || *text == '\t' || *text == '\f') { text++; offset--; } diff --git a/Python/random.c b/Python/random.c index 46e3bb5..c97d5e7 100644 --- a/Python/random.c +++ b/Python/random.c @@ -12,7 +12,7 @@ # ifdef HAVE_LINUX_RANDOM_H # include # endif -# if defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY) +# if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY)) # include # endif # if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL) @@ -77,57 +77,23 @@ 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 - -/* Fill buffer with size pseudo-random bytes generated by getentropy(). - Return 0 on success, or raise an exception and return -1 on error. - - If raise is zero, don't raise an exception on error. */ -static int -py_getentropy(char *buffer, Py_ssize_t size, int raise) -{ - while (size > 0) { - Py_ssize_t len = Py_MIN(size, 256); - int res; - - if (raise) { - Py_BEGIN_ALLOW_THREADS - res = getentropy(buffer, len); - Py_END_ALLOW_THREADS - } - else { - res = getentropy(buffer, len); - } - - if (res < 0) { - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); - } - return -1; - } - - buffer += len; - size -= len; - } - return 0; -} - -#else +#else /* !MS_WINDOWS */ #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) #define PY_GETRANDOM 1 -/* Call getrandom() +/* Call getrandom() to get random bytes: + - Return 1 on success - - Return 0 if getrandom() syscall is not available (failed with ENOSYS or - EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom - not initialized yet) and raise=0. + - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM), + or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not + initialized yet) and raise=0. - Raise an exception (if raise is non-zero) and return -1 on error: - getrandom() failed with EINTR and the Python signal handler raised an - exception, or getrandom() failed with a different error. */ + if getrandom() failed with EINTR, raise is non-zero and the Python signal + handler raised an exception, or if getrandom() failed with a different + error. + + getrandom() is retried if it failed with EINTR: interrupted by a signal. */ static int py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) { @@ -148,7 +114,8 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) while (0 < size) { #ifdef sun /* Issue #26735: On Solaris, getrandom() is limited to returning up - to 1024 bytes */ + to 1024 bytes. Call it multiple times if more bytes are + requested. */ n = Py_MIN(size, 1024); #else n = Py_MIN(size, LONG_MAX); @@ -179,18 +146,19 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) #endif if (n < 0) { - /* ENOSYS: getrandom() syscall not supported by the kernel (but - * maybe supported by the host which built Python). EPERM: - * getrandom() syscall blocked by SECCOMP or something else. */ + /* ENOSYS: the syscall is not supported by the kernel. + EPERM: the syscall is blocked by a security policy (ex: SECCOMP) + or something else. */ if (errno == ENOSYS || errno == EPERM) { getrandom_works = 0; return 0; } /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom - is not initialiazed yet. For _PyRandom_Init(), we ignore their + is not initialiazed yet. For _PyRandom_Init(), we ignore the error and fall back on reading /dev/urandom which never blocks, - even if the system urandom is not initialized yet. */ + even if the system urandom is not initialized yet: + see the PEP 524. */ if (errno == EAGAIN && !raise && !blocking) { return 0; } @@ -217,7 +185,80 @@ py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) } return 1; } -#endif + +#elif defined(HAVE_GETENTROPY) +#define PY_GETENTROPY 1 + +/* Fill buffer with size pseudo-random bytes generated by getentropy(): + + - Return 1 on success + - Return 0 if getentropy() syscall is not available (failed with ENOSYS or + EPERM). + - Raise an exception (if raise is non-zero) and return -1 on error: + if getentropy() failed with EINTR, raise is non-zero and the Python signal + handler raised an exception, or if getentropy() failed with a different + error. + + getentropy() is retried if it failed with EINTR: interrupted by a signal. */ +static int +py_getentropy(char *buffer, Py_ssize_t size, int raise) +{ + /* Is getentropy() supported by the running kernel? Set to 0 if + getentropy() failed with ENOSYS or EPERM. */ + static int getentropy_works = 1; + + if (!getentropy_works) { + return 0; + } + + while (size > 0) { + /* getentropy() is limited to returning up to 256 bytes. Call it + multiple times if more bytes are requested. */ + Py_ssize_t len = Py_MIN(size, 256); + int res; + + if (raise) { + Py_BEGIN_ALLOW_THREADS + res = getentropy(buffer, len); + Py_END_ALLOW_THREADS + } + else { + res = getentropy(buffer, len); + } + + if (res < 0) { + /* ENOSYS: the syscall is not supported by the running kernel. + EPERM: the syscall is blocked by a security policy (ex: SECCOMP) + or something else. */ + if (errno == ENOSYS || errno == EPERM) { + getentropy_works = 0; + return 0; + } + + if (errno == EINTR) { + if (raise) { + if (PyErr_CheckSignals()) { + return -1; + } + } + + /* retry getentropy() if it was interrupted by a signal */ + continue; + } + + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + } + return -1; + } + + buffer += len; + size -= len; + } + return 1; +} +#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */ + static struct { int fd; @@ -225,35 +266,38 @@ static struct { ino_t st_ino; } urandom_cache = { -1 }; +/* Read random bytes from the /dev/urandom device: + + - Return 0 on success + - Raise an exception (if raise is non-zero) and return -1 on error + + Possible causes of errors: + + - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device + was not found. For example, it was removed manually or not exposed in a + chroot or container. + - open() failed with a different error + - fstat() failed + - read() failed or returned 0 -/* Read 'size' random bytes from py_getrandom(). Fall back on reading from - /dev/urandom if getrandom() is not available. + read() is retried if it failed with EINTR: interrupted by a signal. - Return 0 on success. Raise an exception (if raise is non-zero) and return -1 - on error. */ + The file descriptor of the device is kept open between calls to avoid using + many file descriptors when run in parallel from multiple threads: + see the issue #18756. + + st_dev and st_ino fields of the file descriptor (from fstat()) are cached to + check if the file descriptor was replaced by a different file (which is + likely a bug in the application): see the issue #21207. + + If the file descriptor was closed or replaced, open a new file descriptor + but don't close the old file descriptor: it probably points to something + important for some third-party code. */ static int -dev_urandom(char *buffer, Py_ssize_t size, int blocking, int raise) +dev_urandom(char *buffer, Py_ssize_t size, int raise) { int fd; Py_ssize_t n; -#ifdef PY_GETRANDOM - int res; -#endif - - assert(size > 0); - -#ifdef PY_GETRANDOM - res = py_getrandom(buffer, size, blocking, raise); - if (res < 0) { - return -1; - } - if (res == 1) { - return 0; - } - /* getrandom() failed with ENOSYS or EPERM, - fall back on reading /dev/urandom */ -#endif - if (raise) { struct _Py_stat_struct st; @@ -275,9 +319,10 @@ dev_urandom(char *buffer, Py_ssize_t size, int blocking, int raise) fd = _Py_open("/dev/urandom", O_RDONLY); if (fd < 0) { if (errno == ENOENT || errno == ENXIO || - errno == ENODEV || errno == EACCES) + errno == ENODEV || errno == EACCES) { PyErr_SetString(PyExc_NotImplementedError, "/dev/urandom (or equivalent) not found"); + } /* otherwise, keep the OSError exception raised by _Py_open() */ return -1; } @@ -349,8 +394,8 @@ dev_urandom_close(void) urandom_cache.fd = -1; } } +#endif /* !MS_WINDOWS */ -#endif /* Fill buffer with pseudo-random bytes generated by a linear congruent generator (LCG): @@ -373,14 +418,56 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) } } -/* If raise is zero: - - Don't raise exceptions on error - - Don't call PyErr_CheckSignals() on EINTR (retry directly the interrupted - syscall) - - Don't release the GIL to call syscalls. */ +/* Read random bytes: + + - Return 0 on success + - Raise an exception (if raise is non-zero) and return -1 on error + + Used sources of entropy ordered by preference, preferred source first: + + - CryptGenRandom() on Windows + - getrandom() function (ex: Linux and Solaris): call py_getrandom() + - getentropy() function (ex: OpenBSD): call py_getentropy() + - /dev/urandom device + + Read from the /dev/urandom device if getrandom() or getentropy() function + is not available or does not work. + + Prefer getrandom() over getentropy() because getrandom() supports blocking + and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at + startup to initialize its hash secret, but os.urandom() must block until the + system urandom is initialized (at least on Linux 3.17 and newer). + + Prefer getrandom() and getentropy() over reading directly /dev/urandom + because these functions don't need file descriptors and so avoid ENFILE or + EMFILE errors (too many open files): see the issue #18756. + + Only the getrandom() function supports non-blocking mode. + + Only use RNG running in the kernel. They are more secure because it is + harder to get the internal state of a RNG running in the kernel land than a + RNG running in the user land. The kernel has a direct access to the hardware + and has access to hardware RNG, they are used as entropy sources. + + Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed + its RNG on fork(), two child processes (with the same pid) generate the same + random numbers: see issue #18747. Kernel RNGs don't have this issue, + they have access to good quality entropy sources. + + If raise is zero: + + - Don't raise an exception on error + - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if + a function fails with EINTR: retry directly the interrupted function + - Don't release the GIL to call functions. +*/ static int pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise) { +#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) + int res; +#endif + if (size < 0) { if (raise) { PyErr_Format(PyExc_ValueError, @@ -395,10 +482,25 @@ pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise) #ifdef MS_WINDOWS return win32_urandom((unsigned char *)buffer, size, raise); -#elif defined(PY_GETENTROPY) - return py_getentropy(buffer, size, raise); #else - return dev_urandom(buffer, size, blocking, raise); + +#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) +#ifdef PY_GETRANDOM + res = py_getrandom(buffer, size, blocking, raise); +#else + res = py_getentropy(buffer, size, raise); +#endif + if (res < 0) { + return -1; + } + if (res == 1) { + return 0; + } + /* getrandom() or getentropy() function is not available: failed with + ENOSYS or EPERM. Fall back on reading from /dev/urandom. */ +#endif + + return dev_urandom(buffer, size, raise); #endif } @@ -491,8 +593,6 @@ _PyRandom_Fini(void) CryptReleaseContext(hCryptProv, 0); hCryptProv = 0; } -#elif defined(PY_GETENTROPY) - /* nothing to clean */ #else dev_urandom_close(); #endif diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 52034ff..99e6b5e 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1942,9 +1942,9 @@ _PySys_Init(void) PyUnicode_FromString(Py_GetVersion())); SET_SYS_FROM_STRING("hexversion", PyLong_FromLong(PY_VERSION_HEX)); - SET_SYS_FROM_STRING("_mercurial", - Py_BuildValue("(szz)", "CPython", _Py_hgidentifier(), - _Py_hgversion())); + SET_SYS_FROM_STRING("_git", + Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), + _Py_gitversion())); SET_SYS_FROM_STRING("dont_write_bytecode", PyBool_FromLong(Py_DontWriteBytecodeFlag)); SET_SYS_FROM_STRING("api_version", diff --git a/README b/README deleted file mode 100644 index d52d86c..0000000 --- a/README +++ /dev/null @@ -1,233 +0,0 @@ -This is Python version 3.6.0 -============================ - -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -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, -especially how built-in objects like dictionaries and strings work, -have changed considerably, and a lot of deprecated features have finally -been removed. - - -Build Instructions ------------------- - -On Unix, Linux, BSD, OSX, and Cygwin: - - ./configure - make - make test - sudo make install - -This will install Python as python3. - -You can pass many options to the configure script; run "./configure --help" to -find out more. On OSX and Cygwin, the executable is called python.exe; -elsewhere it's just python. - -On Mac OS X, if you have configured Python with --enable-framework, you should -use "make frameworkinstall" to do the installation. Note that this installs the -Python executable in a place that is not normally on your PATH, you may want to -set up a symlink in /usr/local/bin. - -On Windows, see PCbuild/readme.txt. - -If you wish, you can create a subdirectory and invoke configure from there. -For example: - - mkdir debug - cd debug - ../configure --with-pydebug - make - make test - -(This will fail if you *also* built at the top-level directory. -You should do a "make clean" at the toplevel first.) - -To get an optimized build of Python, "configure --enable-optimizations" before -you run make. This sets the default make targets up to enable Profile Guided -Optimization (PGO) and may be used to auto-enable Link Time Optimization (LTO) -on some platforms. For more details, see the sections bellow. - - -Profile Guided Optimization ---------------------------- - -PGO takes advantage of recent versions of the GCC or Clang compilers. -If ran, "make profile-opt" will do several steps. - -First, the entire Python directory is cleaned of temporary files that -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 -step and the binary resulted after this step is not good for real life -workloads, as it has profiling instructions embedded inside. - -After this instrumented version of the interpreter is built, the Makefile -will automatically run a training workload. This is necessary in order to -profile the interpreter execution. Note also that any output, both stdout -and stderr, that may appear at this step is suppressed. - -Finally, the last step is to rebuild the interpreter, using the information -collected in the previous one. The end result will be a Python binary -that is optimized and suitable for distribution or production installation. - - -Link Time Optimization ----------------------- - -Enabled via configure's --with-lto flag. LTO takes advantages of recent -compiler toolchains ability to optimize across the otherwise arbitrary .o file -boundary when building final executables or shared libraries for additional -performance gains. - - -What's New ----------- - -We have a comprehensive overview of the changes in the "What's New in -Python 3.6" document, found at - - https://docs.python.org/3.6/whatsnew/3.6.html - -For a more detailed change log, read Misc/NEWS (though this file, too, -is incomplete, and also doesn't list anything merged in from the 2.7 -release under development). - -If you want to install multiple versions of Python see the section below -entitled "Installing multiple versions". - - -Documentation -------------- - -Documentation for Python 3.6 is online, updated daily: - - https://docs.python.org/3.6/ - -It can also be downloaded in many formats for faster access. The documentation -is downloadable in HTML, PDF, and reStructuredText formats; the latter version -is primarily for documentation authors, translators, and people with special -formatting requirements. - -If you would like to contribute to the development of Python, relevant -documentation is available at: - - https://docs.python.org/devguide/ - -For information about building Python's documentation, refer to Doc/README.txt. - - -Converting From Python 2.x to 3.x ---------------------------------- - -Python starting with 2.6 contains features to help locating code that needs to -be changed, such as optional warnings when deprecated features are used, and -backported versions of certain key Python 3.x features. - -A source-to-source translation tool, "2to3", can take care of the mundane task -of converting large amounts of source code. It is not a complete solution but -is complemented by the deprecation warnings in 2.6. See -https://docs.python.org/3.6/library/2to3.html for more information. - - -Testing -------- - -To test the interpreter, type "make test" in the top-level directory. -The test set produces some output. You can generally ignore the messages -about skipped tests due to optional features which can't be imported. -If a message is printed about a failed test or a traceback or core dump -is produced, something is wrong. - -By default, tests are prevented from overusing resources like disk space and -memory. To enable these tests, run "make testall". - -IMPORTANT: If the tests fail and you decide to mail a bug report, *don't* -include the output of "make test". It is useless. Run the failing test -manually, as follows: - - ./python -m test -v test_whatever - -(substituting the top of the source tree for '.' if you built in a different -directory). This runs the test in verbose mode. - - -Installing multiple versions ----------------------------- - -On Unix and Mac systems if you intend to install multiple versions of Python -using the same installation prefix (--prefix argument to the configure script) -you must take care that your primary python executable is not overwritten by the -installation of a different version. All files and directories installed using -"make altinstall" contain the major and minor version and can thus live -side-by-side. "make install" also creates ${prefix}/bin/python3 which refers to -${prefix}/bin/pythonX.Y. If you intend to install multiple versions using the -same prefix you must decide which version (if any) is your "primary" version. -Install that version using "make install". Install all other versions using -"make altinstall". - -For example, if you want to install Python 2.7, 3.5, and 3.6 with 3.6 being the -primary version, you would execute "make install" in your 3.6 build directory -and "make altinstall" in the others. - - -Issue Tracker and Mailing List ------------------------------- - -We're soliciting bug reports about all aspects of the language. Fixes are also -welcome, preferably in unified diff format. Please use the issue tracker: - - https://bugs.python.org/ - -If you're not sure whether you're dealing with a bug or a feature, use the -mailing list: - - python-dev@python.org - -To subscribe to the list, use the mailman form: - - https://mail.python.org/mailman/listinfo/python-dev/ - - -Proposals for enhancement -------------------------- - -If you have a proposal to change Python, you may want to send an email to the -comp.lang.python or python-ideas mailing lists for initial feedback. A Python -Enhancement Proposal (PEP) may be submitted if your idea gains ground. All -current PEPs, as well as guidelines for submitting a new PEP, are listed at -https://www.python.org/dev/peps/. - - -Release Schedule ----------------- - -See PEP 494 for release details: https://www.python.org/dev/peps/pep-0494/ - - -Copyright and License Information ---------------------------------- - -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013, 2014, 2015, 2016 Python Software Foundation. All rights reserved. - -Copyright (c) 2000 BeOpen.com. All rights reserved. - -Copyright (c) 1995-2001 Corporation for National Research Initiatives. All -rights reserved. - -Copyright (c) 1991-1995 Stichting Mathematisch Centrum. All rights reserved. - -See the file "LICENSE" for information on the history of this software, -terms & conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. - -This Python distribution contains *no* GNU General Public License (GPL) code, -so it may be used in proprietary projects. There are interfaces to some GNU -code but these are entirely optional. - -All trademarks referenced herein are property of their respective holders. - diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..9ea0360 --- /dev/null +++ b/README.rst @@ -0,0 +1,247 @@ +This is Python version 3.6.1 +============================ + +.. image:: https://travis-ci.org/python/cpython.svg?branch=3.6 + :alt: CPython build status on Travis CI + :target: https://travis-ci.org/python/cpython + +.. image:: https://codecov.io/gh/python/cpython/branch/3.6/graph/badge.svg + :alt: CPython code coverage on Codecov + :target: https://codecov.io/gh/python/cpython + +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, +2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation. All rights +reserved. + +See the end of this file for further copyright and license information. + +General Information +------------------- + +- Website: https://www.python.org +- Source code: https://github.com/python/cpython +- Issue tracker: https://bugs.python.org +- Documentation: https://docs.python.org +- Developer's Guide: https://docs.python.org/devguide/ + +Contributing to CPython +----------------------- + +For more complete instructions on contributing to CPython development, +see the `Developer Guide`_. + +.. _Developer Guide: https://docs.python.org/devguide/ + +Using Python +------------ + +Installable Python kits, and information about using Python, are available at +`python.org`_. + +.. _python.org: https://www.python.org/ + + +Build Instructions +------------------ + +On Unix, Linux, BSD, macOS, and Cygwin:: + + ./configure + make + make test + sudo make install + +This will install Python as python3. + +You can pass many options to the configure script; run ``./configure --help`` +to find out more. On macOS and Cygwin, the executable is called ``python.exe``; +elsewhere it's just ``python``. + +On macOS, if you have configured Python with ``--enable-framework``, you +should use ``make frameworkinstall`` to do the installation. Note that this +installs the Python executable in a place that is not normally on your PATH, +you may want to set up a symlink in ``/usr/local/bin``. + +On Windows, see `PCbuild/readme.txt +`_. + +If you wish, you can create a subdirectory and invoke configure from there. +For example:: + + mkdir debug + cd debug + ../configure --with-pydebug + make + make test + +(This will fail if you *also* built at the top-level directory. You should do +a ``make clean`` at the toplevel first.) + +To get an optimized build of Python, ``configure --enable-optimizations`` +before you run ``make``. This sets the default make targets up to enable +Profile Guided Optimization (PGO) and may be used to auto-enable Link Time +Optimization (LTO) on some platforms. For more details, see the sections +below. + + +Profile Guided Optimization +--------------------------- + +PGO takes advantage of recent versions of the GCC or Clang compilers. If ran, +``make profile-opt`` will do several steps. + +First, the entire Python directory is cleaned of temporary files that 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 step +and the binary resulted after this step is not good for real life workloads, as +it has profiling instructions embedded inside. + +After this instrumented version of the interpreter is built, the Makefile will +automatically run a training workload. This is necessary in order to profile +the interpreter execution. Note also that any output, both stdout and stderr, +that may appear at this step is suppressed. + +Finally, the last step is to rebuild the interpreter, using the information +collected in the previous one. The end result will be a Python binary that is +optimized and suitable for distribution or production installation. + + +Link Time Optimization +---------------------- + +Enabled via configure's ``--with-lto`` flag. LTO takes advantage of the +ability of recent compiler toolchains to optimize across the otherwise +arbitrary ``.o`` file boundary when building final executables or shared +libraries for additional performance gains. + + +What's New +---------- + +We have a comprehensive overview of the changes in the `What's New in Python +3.6 `_ document. For a more +detailed change log, read `Misc/NEWS +`_, but a full +accounting of changes can only be gleaned from the `commit history +`_. + +If you want to install multiple versions of Python see the section below +entitled "Installing multiple versions". + + +Documentation +------------- + +`Documentation for Python 3.6 `_ is online, +updated daily. + +It can also be downloaded in many formats for faster access. The documentation +is downloadable in HTML, PDF, and reStructuredText formats; the latter version +is primarily for documentation authors, translators, and people with special +formatting requirements. + +For information about building Python's documentation, refer to `Doc/README.rst +`_. + + +Converting From Python 2.x to 3.x +--------------------------------- + +Significant backward incompatible changes were made for the release of Python +3.0, which may cause programs written for Python 2 to fail when run with Python +3. For more information about porting your code from Python 2 to Python 3, see +the `Porting HOWTO `_. + + +Testing +------- + +To test the interpreter, type ``make test`` in the top-level directory. The +test set produces some output. You can generally ignore the messages about +skipped tests due to optional features which can't be imported. If a message +is printed about a failed test or a traceback or core dump is produced, +something is wrong. + +By default, tests are prevented from overusing resources like disk space and +memory. To enable these tests, run ``make testall``. + +If any tests fail, you can re-run the failing test(s) in verbose mode:: + + make test TESTOPTS="-v test_that_failed" + +If the failure persists and appears to be a problem with Python rather than +your environment, you can `file a bug report `_ and +include relevant output from that command to show the issue. + + +Installing multiple versions +---------------------------- + +On Unix and Mac systems if you intend to install multiple versions of Python +using the same installation prefix (``--prefix`` argument to the configure +script) you must take care that your primary python executable is not +overwritten by the installation of a different version. All files and +directories installed using ``make altinstall`` contain the major and minor +version and can thus live side-by-side. ``make install`` also creates +``${prefix}/bin/python3`` which refers to ``${prefix}/bin/pythonX.Y``. If you +intend to install multiple versions using the same prefix you must decide which +version (if any) is your "primary" version. Install that version using ``make +install``. Install all other versions using ``make altinstall``. + +For example, if you want to install Python 2.7, 3.5, and 3.6 with 3.6 being the +primary version, you would execute ``make install`` in your 3.6 build directory +and ``make altinstall`` in the others. + + +Issue Tracker and Mailing List +------------------------------ + +Bug reports are welcome! You can use the `issue tracker +`_ to report bugs, and/or submit pull requests `on +GitHub `_. + +You can also follow development discussion on the `python-dev mailing list +`_. + + +Proposals for enhancement +------------------------- + +If you have a proposal to change Python, you may want to send an email to the +comp.lang.python or `python-ideas`_ mailing lists for initial feedback. A +Python Enhancement Proposal (PEP) may be submitted if your idea gains ground. +All current PEPs, as well as guidelines for submitting a new PEP, are listed at +`python.org/dev/peps/ `_. + +.. _python-ideas: https://mail.python.org/mailman/listinfo/python-ideas/ + + +Release Schedule +---------------- + +See :pep:`494` for Python 3.6 release details. + + +Copyright and License Information +--------------------------------- + +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, +2012, 2013, 2014, 2015, 2016 Python Software Foundation. All rights reserved. + +Copyright (c) 2000 BeOpen.com. All rights reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. All +rights reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum. All rights reserved. + +See the file "LICENSE" for information on the history of this software, terms & +conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. + +This Python distribution contains *no* GNU General Public License (GPL) code, +so it may be used in proprietary projects. There are interfaces to some GNU +code but these are entirely optional. + +All trademarks referenced herein are property of their respective holders. diff --git a/Tools/README b/Tools/README index 0d961de..edbf4fb 100644 --- a/Tools/README +++ b/Tools/README @@ -45,4 +45,4 @@ unittestgui A Tkinter based GUI test runner for unittest, with test discovery. -(*) A generic benchmark suite is maintained separately at http://hg.python.org/benchmarks/ +(*) A generic benchmark suite is maintained separately at https://github.com/python/performance diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 798b062..cc1afbe 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1570,7 +1570,11 @@ class Frame(object): def get_selected_python_frame(cls): '''Try to obtain the Frame for the python-related code in the selected frame, or None''' - frame = cls.get_selected_frame() + try: + frame = cls.get_selected_frame() + except gdb.error: + # No frame: Python didn't start yet + return None while frame: if frame.is_python_frame(): @@ -1711,6 +1715,10 @@ PyList() def move_in_stack(move_up): '''Move up or down the stack (for the py-up/py-down command)''' frame = Frame.get_selected_python_frame() + if not frame: + print('Unable to locate python frame') + return + while frame: if move_up: iter_frame = frame.older() @@ -1773,6 +1781,10 @@ class PyBacktraceFull(gdb.Command): def invoke(self, args, from_tty): frame = Frame.get_selected_python_frame() + if not frame: + print('Unable to locate python frame') + return + while frame: if frame.is_python_frame(): frame.print_summary() @@ -1790,8 +1802,12 @@ class PyBacktrace(gdb.Command): def invoke(self, args, from_tty): - sys.stdout.write('Traceback (most recent call first):\n') frame = Frame.get_selected_python_frame() + if not frame: + print('Unable to locate python frame') + return + + sys.stdout.write('Traceback (most recent call first):\n') while frame: if frame.is_python_frame(): frame.print_traceback() diff --git a/Tools/importbench/README b/Tools/importbench/README index 81a5544..6ba386c 100644 --- a/Tools/importbench/README +++ b/Tools/importbench/README @@ -3,4 +3,4 @@ Importbench is a set of micro-benchmarks for various import scenarios. It should not be used as an overall benchmark of import performance, but rather an easy way to measure impact of possible code changes. For a real-world benchmark of import, use the normal_startup benchmark from -hg.python.org/benchmarks. +https://github.com/python/performance diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 4659a32..81a3f86 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -65,8 +65,8 @@ if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) -if not exist "%HG%" where hg > "%TEMP%\hg.loc" 2> nul && set /P HG= < "%TEMP%\hg.loc" & del "%TEMP%\hg.loc" -if not exist "%HG%" echo Cannot find Mercurial on PATH && exit /B 1 +if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" +if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1 call "%D%get_externals.bat" diff --git a/Tools/msi/exe/exe_files.wxs b/Tools/msi/exe/exe_files.wxs index 0138587..e675c21 100644 --- a/Tools/msi/exe/exe_files.wxs +++ b/Tools/msi/exe/exe_files.wxs @@ -8,9 +8,6 @@ - - - diff --git a/Tools/msi/make_zip.proj b/Tools/msi/make_zip.proj index f78e6ff..b3588b7 100644 --- a/Tools/msi/make_zip.proj +++ b/Tools/msi/make_zip.proj @@ -17,15 +17,12 @@ rmdir /q/s "$(IntermediateOutputPath)\zip_$(ArchName)" "$(PythonExe)" "$(MSBuildThisFileDirectory)\make_zip.py" $(Arguments) -e -o "$(TargetPath)" -t "$(IntermediateOutputPath)\zip_$(ArchName)" -a $(ArchName) - set DOC_FILENAME=python$(PythonVersion).chm -set VCREDIST_PATH=$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT + set DOC_FILENAME=python$(PythonVersion).chm + $(Environment)%0D%0Aset VCREDIST_PATH=$(CRTRedist)\$(Platform) - + diff --git a/Tools/msi/make_zip.py b/Tools/msi/make_zip.py index 8dbe83e..710e4a5 100644 --- a/Tools/msi/make_zip.py +++ b/Tools/msi/make_zip.py @@ -29,12 +29,15 @@ DEBUG_FILES = { EXCLUDE_FROM_LIBRARY = { '__pycache__', - 'ensurepip', 'idlelib', 'pydoc_data', 'site-packages', 'tkinter', 'turtledemo', +} + +EXCLUDE_FROM_EMBEDDABLE_LIBRARY = { + 'ensurepip', 'venv', } @@ -82,6 +85,12 @@ def include_in_lib(p): suffix = p.suffix.lower() return suffix not in {'.pyc', '.pyo', '.exe'} +def include_in_embeddable_lib(p): + if p.is_dir() and p.name.lower() in EXCLUDE_FROM_EMBEDDABLE_LIBRARY: + return False + + return include_in_lib(p) + def include_in_libs(p): if not is_not_debug(p): return False @@ -114,7 +123,7 @@ EMBED_LAYOUT = [ ('/', 'PCBuild/$arch', 'python*.exe', is_not_debug), ('/', 'PCBuild/$arch', '*.pyd', is_not_debug), ('/', 'PCBuild/$arch', '*.dll', is_not_debug), - ('{}.zip'.format(BASE_NAME), 'Lib', '**/*', include_in_lib), + ('{}.zip'.format(BASE_NAME), 'Lib', '**/*', include_in_embeddable_lib), ] if os.getenv('DOC_FILENAME'): diff --git a/Tools/msi/uploadrelease.bat b/Tools/msi/uploadrelease.bat index 4e319ce..670836b 100644 --- a/Tools/msi/uploadrelease.bat +++ b/Tools/msi/uploadrelease.bat @@ -9,6 +9,8 @@ set USER= set TARGET= set DRYRUN=false set NOGPG= +set PURGE_OPTION=/p:Purge=true +set NOTEST= :CheckOpts if "%1" EQU "-h" goto Help @@ -19,7 +21,11 @@ if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts -if "%1" EQU "--no-gpg" (set NOGPG=true) && shift && goto CheckOpts +if "%1" EQU "--skip-gpg" (set NOGPG=true) && shift && goto CheckOpts +if "%1" EQU "--skip-purge" (set PURGE_OPTION=) && shift && godo CheckOpts +if "%1" EQU "--skip-test" (set NOTEST=true) && shift && godo CheckOpts +if "%1" EQU "-T" (set NOTEST=true) && shift && godo CheckOpts +if "%1" NEQ "" echo Unexpected argument "%1" & exit /B 1 if not defined PLINK where plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" if not defined PLINK where /R "%ProgramFiles(x86)%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" @@ -35,7 +41,7 @@ echo Found pscp.exe at %PSCP% if defined NOGPG ( set GPG= - echo Skipping GPG signature generation because of --no-gpg + echo Skipping GPG signature generation because of --skip-gpg ) else ( if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" if not defined GPG where /R "%PCBUILD%..\externals\windows-installer" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" @@ -45,8 +51,12 @@ if defined NOGPG ( call "%PCBUILD%env.bat" > nul 2> nul pushd "%D%" -msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 -msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false +msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 %PURGE_OPTION% +msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false %PURGE_OPTION% +if not defined NOTEST ( + msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x86 + msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x64 +) msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false popd @@ -55,9 +65,12 @@ exit /B 0 :Help echo uploadrelease.bat --host HOST --user USERNAME [--target TARGET] [--dry-run] [-h] echo. -echo --host (-o) Specify the upload host (required) -echo --user (-u) Specify the user on the host (required) -echo --target (-t) Specify the target directory on the host -echo --dry-run Display commands and filenames without executing them -echo -h Display this help information +echo --host (-o) Specify the upload host (required) +echo --user (-u) Specify the user on the host (required) +echo --target (-t) Specify the target directory on the host +echo --dry-run Display commands and filenames without executing them +echo --skip-gpg Does not generate GPG signatures before uploading +echo --skip-purge Does not perform CDN purge after uploading +echo --skip-test (-T) Does not perform post-upload tests +echo -h Display this help information echo. diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj index 0d472de..75840f2 100644 --- a/Tools/msi/uploadrelease.proj +++ b/Tools/msi/uploadrelease.proj @@ -8,7 +8,9 @@ $(TARGET) /srv/www.python.org/ftp/python true + true false + false @@ -64,7 +66,37 @@ echo. echo." /> - + + + + + + + + + + $(TEMP)\%(Filename)_source + $(TEMP)\%(Filename)_source\%(Filename)%(Extension) + $(TEMP)\%(Filename)_layout + $(OutputPath)\%(Filename)_layoutlog + $(OutputPath)\%(Filename)_layoutlog\%(Filename).log + + + + + + + + + + + + + + + + diff --git a/Tools/nuget/make_pkg.proj b/Tools/nuget/make_pkg.proj index d7e932c..464ef04 100644 --- a/Tools/nuget/make_pkg.proj +++ b/Tools/nuget/make_pkg.proj @@ -34,9 +34,8 @@ $(NugetArguments) -Version "$(NuspecVersion)" $(NugetArguments) -NoPackageAnalysis -NonInteractive - setlocal -set DOC_FILENAME=python$(PythonVersion).chm -set VCREDIST_PATH=$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT + set DOC_FILENAME=python$(PythonVersion).chm + $(Environment)%0D%0Aset VCREDIST_PATH=$(CRTRedist)\$(Platform) @@ -45,8 +44,7 @@ set VCREDIST_PATH=$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140. - + diff --git a/configure b/configure index cf95b27..abe1dc5 100755 --- a/configure +++ b/configure @@ -760,10 +760,10 @@ build_os build_vendor build_cpu build -HAS_HG -HGBRANCH -HGTAG -HGVERSION +HAS_GIT +GITBRANCH +GITTAG +GITVERSION BASECPPFLAGS target_alias host_alias @@ -2698,17 +2698,17 @@ fi -if test -e $srcdir/.hg/dirstate +if test -e $srcdir/.git/HEAD then -# Extract the first word of "hg", so it can be a program name with args. -set dummy hg; ac_word=$2 +# Extract the first word of "git", so it can be a program name with args. +set dummy git; 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_prog_HAS_HG+:} false; then : +if ${ac_cv_prog_HAS_GIT+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$HAS_HG"; then - ac_cv_prog_HAS_HG="$HAS_HG" # Let the user override the test. + if test -n "$HAS_GIT"; then + ac_cv_prog_HAS_GIT="$HAS_GIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -2717,7 +2717,7 @@ do 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_prog_HAS_HG="found" + ac_cv_prog_HAS_GIT="found" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2725,13 +2725,13 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_prog_HAS_HG" && ac_cv_prog_HAS_HG="not-found" + test -z "$ac_cv_prog_HAS_GIT" && ac_cv_prog_HAS_GIT="not-found" fi fi -HAS_HG=$ac_cv_prog_HAS_HG -if test -n "$HAS_HG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_HG" >&5 -$as_echo "$HAS_HG" >&6; } +HAS_GIT=$ac_cv_prog_HAS_GIT +if test -n "$HAS_GIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_GIT" >&5 +$as_echo "$HAS_GIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -2739,17 +2739,17 @@ fi else -HAS_HG=no-repository +HAS_GIT=no-repository fi -if test $HAS_HG = found +if test $HAS_GIT = found then - HGVERSION="hg id -i \$(srcdir)" - HGTAG="hg id -t \$(srcdir)" - HGBRANCH="hg id -b \$(srcdir)" + GITVERSION="git -C \$(srcdir) rev-parse --short HEAD" + GITTAG="git -C \$(srcdir) describe --all --always --dirty" + GITBRANCH="git -C \$(srcdir) name-rev --name-only HEAD" else - HGVERSION="" - HGTAG="" - HGBRANCH="" + GITVERSION="" + GITTAG="" + GITBRANCH="" fi @@ -3247,6 +3247,9 @@ then # a lot of different things including 'define_xopen_source' # in the case statement below. case "$host" in + *-*-linux-android*) + ac_sys_system=Linux-android + ;; *-*-linux*) ac_sys_system=Linux ;; @@ -5218,29 +5221,7 @@ cat >> conftest.c <&6; } cat >> conftest.c < -__ANDROID_API__ +android_api = __ANDROID_API__ +arm_arch = __ARM_ARCH #else #error not Android #endif EOF if $CPP $CPPFLAGS conftest.c >conftest.out 2>/dev/null; then - ANDROID_API_LEVEL=`grep -v '^#' conftest.out | grep -v '^ *$'` + ANDROID_API_LEVEL=`sed -n -e '/__ANDROID_API__/d' -e 's/^android_api = //p' conftest.out` + _arm_arch=`sed -n -e '/__ARM_ARCH/d' -e 's/^arm_arch = //p' conftest.out` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ANDROID_API_LEVEL" >&5 $as_echo "$ANDROID_API_LEVEL" >&6; } @@ -5677,6 +5660,15 @@ cat >>confdefs.h <<_ACEOF #define ANDROID_API_LEVEL $ANDROID_API_LEVEL _ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Android arm ABI" >&5 +$as_echo_n "checking for the Android arm ABI... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_arm_arch" >&5 +$as_echo "$_arm_arch" >&6; } + if test "$_arm_arch" = 7; then + BASECFLAGS="${BASECFLAGS} -mfloat-abi=softfp -mfpu=vfpv3-d16" + LDFLAGS="${LDFLAGS} -march=armv7-a -Wl,--fix-cortex-a8" + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not Android" >&5 $as_echo "not Android" >&6; } @@ -7785,7 +7777,7 @@ unistd.h utime.h \ poll.h sys/devpoll.h sys/epoll.h sys/poll.h \ sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/ioctl.h \ sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \ -sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \ +sys/param.h sys/random.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 \ @@ -9303,6 +9295,7 @@ then then CCSHARED="-fPIC"; else CCSHARED="+z"; fi;; + Linux-android*) ;; Linux*|GNU*) CCSHARED="-fPIC";; BSD/OS*/4*) CCSHARED="-fpic";; FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) CCSHARED="-fPIC";; @@ -9336,6 +9329,7 @@ then LINKFORSHARED="-Wl,-E -Wl,+s";; # LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";; BSD/OS/4*) LINKFORSHARED="-Xlinker -export-dynamic";; + Linux-android*) LINKFORSHARED="-pie -Xlinker -export-dynamic";; Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";; # -u libsys_s pulls in all symbols in libsys Darwin/*) @@ -11220,8 +11214,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ futimens futimes gai_strerror getentropy \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ - if_nameindex \ - initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ + initgroups kill killpg lchmod lchown linkat lstat lutimes mmap \ memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise pread \ @@ -12668,6 +12661,80 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext +# On Android API level 24 with android-ndk-r13, if_nameindex() is available, +# but the if_nameindex structure is not defined. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for if_nameindex" >&5 +$as_echo_n "checking for if_nameindex... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_NET_IF_H +# include +#endif + +int +main () +{ +struct if_nameindex *ni = if_nameindex(); int x = ni[0].if_index; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +$as_echo "#define HAVE_IF_NAMEINDEX 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +# Issue #28762: lockf() is available on Android API level 24, but the F_LOCK +# macro is not defined in android-ndk-r13. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lockf" >&5 +$as_echo_n "checking for lockf... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +lockf(0, F_LOCK, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +$as_echo "#define HAVE_LOCKF 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + # On OSF/1 V5.1, getaddrinfo is available, but a define # for [no]getaddrinfo in netdb.h. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 @@ -15712,7 +15779,9 @@ fi # first curses header check ac_save_cppflags="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" +if test "$cross_compiling" = no; then + CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" +fi for ac_header in curses.h ncurses.h do : diff --git a/configure.ac b/configure.ac index 1d63813..9eacf52 100644 --- a/configure.ac +++ b/configure.ac @@ -25,25 +25,25 @@ else BASECPPFLAGS="" fi -AC_SUBST(HGVERSION) -AC_SUBST(HGTAG) -AC_SUBST(HGBRANCH) +AC_SUBST(GITVERSION) +AC_SUBST(GITTAG) +AC_SUBST(GITBRANCH) -if test -e $srcdir/.hg/dirstate +if test -e $srcdir/.git/HEAD then -AC_CHECK_PROG(HAS_HG, hg, found, not-found) +AC_CHECK_PROG(HAS_GIT, git, found, not-found) else -HAS_HG=no-repository +HAS_GIT=no-repository fi -if test $HAS_HG = found +if test $HAS_GIT = found then - HGVERSION="hg id -i \$(srcdir)" - HGTAG="hg id -t \$(srcdir)" - HGBRANCH="hg id -b \$(srcdir)" + GITVERSION="git -C \$(srcdir) rev-parse --short HEAD" + GITTAG="git -C \$(srcdir) describe --all --always --dirty" + GITBRANCH="git -C \$(srcdir) name-rev --name-only HEAD" else - HGVERSION="" - HGTAG="" - HGBRANCH="" + GITVERSION="" + GITTAG="" + GITBRANCH="" fi AC_CONFIG_SRCDIR([Include/object.h]) @@ -379,6 +379,9 @@ then # a lot of different things including 'define_xopen_source' # in the case statement below. case "$host" in + *-*-linux-android*) + ac_sys_system=Linux-android + ;; *-*-linux*) ac_sys_system=Linux ;; @@ -770,29 +773,7 @@ cat >> conftest.c <> conftest.c < -__ANDROID_API__ +android_api = __ANDROID_API__ +arm_arch = __ARM_ARCH #else #error not Android #endif EOF if $CPP $CPPFLAGS conftest.c >conftest.out 2>/dev/null; then - ANDROID_API_LEVEL=`grep -v '^#' conftest.out | grep -v '^ *$'` + ANDROID_API_LEVEL=`sed -n -e '/__ANDROID_API__/d' -e 's/^android_api = //p' conftest.out` + _arm_arch=`sed -n -e '/__ARM_ARCH/d' -e 's/^arm_arch = //p' conftest.out` AC_MSG_RESULT([$ANDROID_API_LEVEL]) AC_DEFINE_UNQUOTED(ANDROID_API_LEVEL, $ANDROID_API_LEVEL, [The Android API level.]) + + AC_MSG_CHECKING([for the Android arm ABI]) + AC_MSG_RESULT([$_arm_arch]) + if test "$_arm_arch" = 7; then + BASECFLAGS="${BASECFLAGS} -mfloat-abi=softfp -mfpu=vfpv3-d16" + LDFLAGS="${LDFLAGS} -march=armv7-a -Wl,--fix-cortex-a8" + fi else AC_MSG_RESULT([not Android]) fi @@ -2041,7 +2031,7 @@ unistd.h utime.h \ poll.h sys/devpoll.h sys/epoll.h sys/poll.h \ sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/ioctl.h \ sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \ -sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \ +sys/param.h sys/random.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 \ @@ -2557,6 +2547,7 @@ then then CCSHARED="-fPIC"; else CCSHARED="+z"; fi;; + Linux-android*) ;; Linux*|GNU*) CCSHARED="-fPIC";; BSD/OS*/4*) CCSHARED="-fpic";; FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) CCSHARED="-fPIC";; @@ -2588,6 +2579,7 @@ then LINKFORSHARED="-Wl,-E -Wl,+s";; # LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";; BSD/OS/4*) LINKFORSHARED="-Xlinker -export-dynamic";; + Linux-android*) LINKFORSHARED="-pie -Xlinker -export-dynamic";; Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";; # -u libsys_s pulls in all symbols in libsys Darwin/*) @@ -3406,8 +3398,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ futimens futimes gai_strerror getentropy \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ - if_nameindex \ - initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ + initgroups kill killpg lchmod lchown linkat lstat lutimes mmap \ memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise pread \ @@ -3759,6 +3750,40 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ AC_MSG_RESULT(no) ]) +# On Android API level 24 with android-ndk-r13, if_nameindex() is available, +# but the if_nameindex structure is not defined. +AC_MSG_CHECKING(for if_nameindex) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_NET_IF_H +# include +#endif +]], [[struct if_nameindex *ni = if_nameindex(); int x = ni[0].if_index;]])], + [AC_DEFINE(HAVE_IF_NAMEINDEX, 1, Define to 1 if you have the 'if_nameindex' function.) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) +]) + +# Issue #28762: lockf() is available on Android API level 24, but the F_LOCK +# macro is not defined in android-ndk-r13. +AC_MSG_CHECKING(for lockf) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[lockf(0, F_LOCK, 0);]])], + [AC_DEFINE(HAVE_LOCKF, 1, Define to 1 if you have the 'lockf' function and the F_LOCK macro.) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) +]) + # On OSF/1 V5.1, getaddrinfo is available, but a define # for [no]getaddrinfo in netdb.h. AC_MSG_CHECKING(for getaddrinfo) @@ -4907,7 +4932,9 @@ fi # first curses header check ac_save_cppflags="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" +if test "$cross_compiling" = no; then + CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" +fi AC_CHECK_HEADERS(curses.h ncurses.h) diff --git a/pyconfig.h.in b/pyconfig.h.in index e7a836c..b10c57f 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -472,7 +472,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_IEEEFP_H -/* Define to 1 if you have the `if_nameindex' function. */ +/* Define to 1 if you have the 'if_nameindex' function. */ #undef HAVE_IF_NAMEINDEX /* Define if you have the 'inet_aton' function. */ @@ -574,7 +574,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_TIPC_H -/* Define to 1 if you have the `lockf' function. */ +/* Define to 1 if you have the 'lockf' function and the F_LOCK macro. */ #undef HAVE_LOCKF /* Define to 1 if you have the `log1p' function. */ @@ -1033,6 +1033,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RANDOM_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H diff --git a/setup.py b/setup.py index af9a414..f04bf22 100644 --- a/setup.py +++ b/setup.py @@ -532,8 +532,9 @@ class PyBuildExt(build_ext): for directory in reversed(options.dirs): add_dir_to_list(dir_list, directory) - if os.path.normpath(sys.base_prefix) != '/usr' \ - and not sysconfig.get_config_var('PYTHONFRAMEWORK'): + if (not cross_compiling and + os.path.normpath(sys.base_prefix) != '/usr' and + not sysconfig.get_config_var('PYTHONFRAMEWORK')): # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework # (PYTHONFRAMEWORK is set) to avoid # linking problems when # building a framework with different architectures than @@ -1349,7 +1350,8 @@ class PyBuildExt(build_ext): panel_library = 'panel' if curses_library == 'ncursesw': curses_defines.append(('HAVE_NCURSESW', '1')) - curses_includes.append('/usr/include/ncursesw') + if not cross_compiling: + curses_includes.append('/usr/include/ncursesw') # Bug 1464056: If _curses.so links with ncursesw, # _curses_panel.so must link with panelw. panel_library = 'panelw' @@ -1630,7 +1632,7 @@ class PyBuildExt(build_ext): ## ext = Extension('xx', ['xxmodule.c']) ## self.extensions.append(ext) - if 'd' not in sys.abiflags: + if 'd' not in sysconfig.get_config_var('ABIFLAGS'): ext = Extension('xxlimited', ['xxlimited.c'], define_macros=[('Py_LIMITED_API', '0x03050000')]) self.extensions.append(ext) @@ -2062,7 +2064,7 @@ class PyBuildExt(build_ext): 'Modules', '_decimal', 'libmpdec'))] - libraries = [] + libraries = self.detect_math_libs() sources = [ '_decimal/_decimal.c', '_decimal/libmpdec/basearith.c', -- 2.7.4